BIND9’s lawful interception against commercials

Posted on 2014-12-26 in Projects • 3 min read

Combine lawful interception…

The internet domain name server BIND9 has a build-in lawful interception feature called Response Policy Zones. This feature can be used for a recursive dns server to fight against commercials and malicious internet services (aka websites).

There is an article of Paul Vixie showing howto use the RPZ feature with public (commercial) RPZ providers. Since using a remote RPZ zone enables the RPZ provider to track DNS queries of your local recursive dns server you should only use local copies of the zone (using ordinary dns zone transfers).

In the following setup I used the dns zone name rpz.fiasko-nw.net. To setup your own RPZ based filtering you should replace it by a local dns zone name. You need a BIND9 version ≥9.8 - I’ve tested it successfully with the BIND9 package shipped with Debian‘s squeeze-backports, wheezy and jessie releases.

…with a commercials blacklist

There are websites providing hosts files to fight commercials on local desktop computers or rooted Android devices. Changing the hosts file of multiple (SOHO) devices is expensive and might be impossible (non-rooted Androids, Apple devices etc.). Combining BIND9‘s RPZ feature with hosts file content gives a easy home-made “commercials” dns firewall.

In my example I use the hosts list from http://pgl.yoyo.org/as/. The list can be downloaded as plaintext with one host per line. You just need to convert it into a valid zone file and configure your local recursive BIND9 to use it as a RPZ filter.

Building the zone file…

The following basic script builds a valid zone file (requires curl). The zone filename can be provided as parameter and defaults to db/rpz.fiasko-nw.net.

#!/bin/sh -e

asurl='http://pgl.yoyo.org/as/serverlist.php?hostformat=nohtml'
zfn=${1:-db/rpz.fiasko-nw.net}

echo "Building zone '$zfn.new'..."
echo '$TTL 900
@       IN SOA localhost. root.localhost. (
                %SERIAL%     ; serial
                14400          ; refresh
                1800           ; retry
                604800         ; expire
                86400 )        ; minimum
' | sed -e 's/%SERIAL%/'`date +%Y%m%d%H`'/' > "$zfn.new"

state=0
curl -s "$asurl" | while read line; do
    printf '%-40s CNAME .\n' "$line" >> "$zfn.new"
done

echo 'Reloading bind...'
mv "$zfn.new" "$zfn"
service bind9 reload

You might need to tune the script for your requirements like adding NS records to make zone transfers more reliable etc. Lookups for blacklisted hostnames results in a NXDOMAIN dns response since the RPZ records are pointing to .. See also Chapter 6. BIND 9 Configuration Reference to get a list of available responses.

The RPZ zone rpz.fiasko-nw.net is configured as any normal zone within BIND9:

zone "rpz.fiasko-nw.net" IN {
    type master;
    file "/etc/bind/db/rpz.fiasko-nw.net";
};

If you have multiple dns servers this zone can be distributed using normal zone transfers.

…and enabling RPZ

To enable RPZ add the following statements to the global options block:

options {
        // ...

        response-policy {
            zone "rpz.fiasko-nw.net";
        };
}

You could also add multiple RPZ zone lookups. After reloading BIND9 you should see some log entries whenever someone triggeres a RPZ hit:

Dec 26 11:12:18 XXXXXXXX named[12361]: client 192.168.0.29#33322: rpz QNAME NXDOMAIN rewrite www-google-analytics.l.google.com via www-google-analytics.l.google.com.rpz.fiasko-nw.net
Dec 26 12:13:38 YYYYYYYY named[27111]: client 127.0.0.1#36221 (www.clickz.com): rpz QNAME NXDOMAIN rewrite clickz.com via clickz.com.rpz.fiasko-nw.net

Compare google’s dns response vs. the local dns server:

$ host www-google-analytics.l.google.com 8.8.8.8
Using domain server:
Name: 8.8.8.8
Address: 8.8.8.8#53
Aliases: 

www-google-analytics.l.google.com has address 74.125.133.138
www-google-analytics.l.google.com has address 74.125.133.100
www-google-analytics.l.google.com has address 74.125.133.101
www-google-analytics.l.google.com has address 74.125.133.102
www-google-analytics.l.google.com has address 74.125.133.139
www-google-analytics.l.google.com has address 74.125.133.113
www-google-analytics.l.google.com has IPv6 address 2a00:1450:4005:808::1008

$ host www-google-analytics.l.google.com
Host www-google-analytics.l.google.com not found: 3(NXDOMAIN)

Conclusions

BIND9‘s lawful interception feature helps building DNS blacklist for protecting from commercials and malware. But the feature can be easily misused to redirect traffic relaying on dns. Just be aware… if your ISP’s or Google’s dns server are using this feature…

Read more on RPZ at Jan-Piet Mens‘s blog: