Posted by lindenle on Tue 19 Jun 2007 at 08:59
I was chatting with a colleague over IRC on Tuesday and he was complaining about the new update for Bind9 that broke his automatic blocking of ad servers. Naturally I was curious and asked him what he was talking about..
He pointed me to the site pgl.yoyo.org/adservers that provides a list of the currently known banner ad distribution domains. The avid web surfer in me immediately decided I could no longer live with banner adds while web browsing at home and I set out to solve this problem. The easiest solution would have been to ask "Bob" for his scripts and install Bind9 on my server. I however already run dnsmasq on said server and figured there must be a way to bend it to my will. Reading the dnsmasq manpage I found the following:
A, --address=/<domain>/ [domain/] <ipaddr>
Specify an IP address to return for any host in the given
domains. Queries in the domains are never forwarded and always
replied to with the specified IP address which may be IPv4 or
IPv6. To give both IPv4 and IPv6 addresses for a domain, use
repeated -A flags. Note that /etc/hosts and DHCP leases over-
ride this for individual names. A common use of this is to redi-
rect the entire doubleclick.net domain to some friendly local
web server to avoid banner ads. The domain specification works
in the same was as for --server, with the additional facility
that /#/ matches any domain. Thus --address=/#/1.2.3.4 will
always return 1.2.3.4 for any query not answered from /etc/hosts
or DHCP and not sent to an upstream nameserver by a more spe-
cific --server directive."
This seemed to be exactly what I wanted. It redirects any server in a given domain to a specified ip address. Now all I had to do was write a script to download the list, rewrite my dnsmasq.conf file and restart dnsmasq at regular intervals.
The following bash script is the result of about an hour of hacking yesterday. It downloads a plain text list of ad servers from yoyo, rewrites "/etc/dnsmasq.conf" and restarts the server:
#!/bin/sh
### short script that downloads a list of ad servers for use with
### dnsmasq to block ads.
###
# the ipaddress where we want to send the requests to, instead of the
# bannerservers
addcatcherip='192.168.1.4'
configfile=/etc/dnsmasq.conf
# the args to add to the request to the yoyo server, to tell it that we want
# a hosts file and that we want to redirect to the addcatcher
listurlargs="hostformat=nohtml&showintro=0&mimetype=plaintext"
# URL of the ad server list to download
listurl="http://pgl.yoyo.org/adservers/serverlist.php?${listurlargs}"
# location of a file where hostnames not listed can be added
extrasfile='/etc/banner_add_hosts.manual'
## command to reload dnsmasq - change according to your system
## not sure if we need this for dnsmasq
reloadcmd='/etc/init.d/dnsmasq restart'
# temp files to use
tmpfile="/tmp/.adlist.$$"
tmpconffile="/tmp/.dnsmasq.conf.$$"
# command to fetch the list (alternatives commented out)
fetchcmd="/usr/bin/wget -q -O $tmpfile $listurl"
$fetchcmd
# add the extras
[ -f "$extrasfile" ] && cat $extrasfile >> $tmpfile
# check the temp file exists OK before overwriting the existing list
if [ ! -s $tmpfile ]
then
echo "temp file '$tmpfile' either doesn't exist or is empty; quitting"
exit
fi
# get a fresh list of ad server addresses for dnsmasq to refuse
cat $configfile | grep -v "address=" > $tmpconffile
while read line; do
ADDRESS="/${line}/${addcatcherip}"
echo "address=\"${ADDRESS}\"" >> $tmpconffile
done < $tmpfile
mv $tmpconffile $configfile
$reloadcmd
rm $tmpfile
exit
The script has the nice feature that hosts can be added by hand in the file /etc/banner_add_hosts.manual. I installed it in /usr/local/bin and changed the permissions to 700 and ran the script:
$ sudo cp update_bannerhosts /usr/local/bin $ sudo chown root.root /usr/local/bin/update_bannerhosts $ sudo chmod 700 /usr/local/bin/update_bannerhosts $ sudo /usr/local/bin/update_bannerhosts Restarting DNS forwarder and DHCP server: dnsmasq.
Looking at my /etc/dnsmasq.conf revealed the addition of many lines of new address entries:
address="/ac.rnm.ca/192.168.1.4" address="/accelerator-media.com/192.168.1.4" address="/action.ientry.net/192.168.1.4" address="/actionsplash.com/192.168.1.4" address="/actualdeals.com/192.168.1.4"
Next I ran a few quick tests to see that all ad domains were being redirected to my addcatcherip.
$ nslookup doubleclick.net Server: 192.168.1.4 Address: 192.168.1.4#53 Name: doubleclick.net Address: 192.168.1.4 $ nslookup ads.doubleclick.net Server: 192.168.1.4 Address: 192.168.1.4#53 Name: ads.doubleclick.net Address: 192.168.1.4
Sure enough any server in the domain doubleclick.net is now resolving to my local ip address. The next big test was to open a web page and see if the banner ads were gone, I chose heise.de and sure enough the big banner add at the top was now gone. Success!
The last step in this project was to add crontab entry to run the new script every 4 hours to update the list of ad servers:
$ cat /etc/cron.d/update_bannerhosts #Update the banner hosts... 0 0,4,8,12,16,18,20 * * * root /usr/local/bin/update_bannerhosts
I hope this helps some people get rid of banner ads without having to install and learn Bind9.
This article can be found online at the Debian Administration website at the following bookmarkable URL (along with associated comments):
This article is copyright 2007 lindenle - please ask for permission to republish or translate.