Charlie Harvey

How to make an adblocker with BIND and Apache on Debian

There are a few approaches to blocking ads. Adblock Plus seems to have become the most popular. It uses Firefox’s content policies interface and you can read more about how Adblock plus works on the FAQ.

I have been playing around this week with another approach to Ad blocking, which is documented by Hal Pomeranz in A Simple DNS-Based Approach for Blocking Web Advertising. My approach is similar but a little different to Hal’s.

Outline

The idea is that we run a caching nameserver on the local network — I went with BIND, which is a bit sledgehammer to crack a nut, but I have a perverse fondness for it. We grab a list of ad servers and point them all at a zonefile which has an A Record pointing at a web server we control. In my case just my local Apache.

Then we set up the webserver always to return a tiny single pixel transparent gif. Or some other content. Next our browsing machine is set up to use the DNS server, which works like a normal caching DNS server for most requests. But sends browsers to our Apache to downoad a pixel rather than to an actual ad server. This eliminates outgoing requests, saving bandwidth and replacing ads with fast to download images. So here is how to set it up.

The webserver bit

First of all you’ll need a webserver. I’ve been running everything on my local machine which already has Apache running on port 80. There are other web servers, and there is even (apparently) a thing called pixelserver.pl which will serve you a single pixel given any request. But I went with Apache this time.

Step one is to grab the single pixel gif. There is a 43 byte one available from probablyprogramming.com which should do the job. I also changed the name -- which saves some bandwidth on the local machine. Next I will waste bandwidth by sending a redirect. So it isn't a big deal. $ wget http://probablyprogramming.com/wp-content/uploads/2009/03/tinytrans.gif $ mv tinytrans.gif a.gif

Next, we set up a rewrite rule in Apache’s default site (000-default or something on Debian) that points any requests for fies that do not exist to our gif. I also give it a stupid long cache control header, which ought to mean fewer repeated requests. <Directory /var/www/> … <FilesMatch "a.gif$"> Header set Cache-Control "max-age=290304000, public" </FilesMatch> RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-l RewriteRule ^(.*)$ http://localhost/a.gif …

Apache will just need a restart at this point.$ sudo apachectl graceful

The BIND part

I had to install BIND first. Again I set it up on my local machine. You will need to tweak the config according to your environment. $ aptitude install bind9 Next, we set BIND up to act as a caching DNS server, using some nice anonymous DNS servers courtesy of InterNIC’s Tier 2 list as our forwarders. $ sudo vim /etc/bind/named.conf.options forwarders { 151.236.6.6; 142.4.205.47 };

Next we grab the blacklist, which already provides a bind compatible format. $ sudo wget -O /etc/bind/ad-blacklist 'http://pgl.yoyo.org/adservers/serverlist.php?hostformat=bindconfig&showintro=0&mimetype=plaintext'

I had to break out vim to change the path to the zonefiles before debian was happy. $ cd /etc/bind $ sudo vim ad-blacklist :%s/null/\/etc\/bind\/null/ :wqWe tell to use this localy new zonefile$ sudo vim /etc/bind/named.conf.local include "/etc/bind/ad-blacklist"

Next we create the actual zonefile which looked like this $ sudo vim /etc/bind/null.zone.file $TTL 86400 ; one day @ IN SOA ads.example.com. hostmaster.example.com. ( 2014090101 28800 7200 864000 86400 ) NS my.dns.server.org A 127.0.0.1 @ IN A 127.0.0.1 * IN A 127.0.0.1

Final steps

We are now ready to reoad BIND and check our handiwork.$ sudo rndc reload $ dig +short 101com.com @localhost 127.0.0.1

Now we need to tell the browsing machine to use the new nameseerver. On a statically configured debian box this would mean editing /etc/resolv.conf and making sure that the first line readnameserver 127.0.0.1For a machine that is configured with DHCP, it is a case of prepending the same line to /etc/resolvconf/resolv.conf.d/base.

Final thoughts

I am pretty happy with this adblocking setup overall. It allows me to do some neat tricks like blocking whole domains — blackholing anything to do with facebook makes most sites run faster not to mention reducing privacy leakage. However, there are some problems. Paypal, for example gets very breaky when this is running.


Comments

  • Be respectful. You may want to read the comment guidelines before posting.
  • You can use Markdown syntax to format your comments. You can only use level 5 and 6 headings.
  • You can add class="your language" to code blocks to help highlight.js highlight them correctly.

Privacy note: This form will forward your IP address, user agent and referrer to the Akismet, StopForumSpam and Botscout spam filtering services. I don’t log these details. Those services will. I do log everything you type into the form. Full privacy statement.