Raspberry Pi + ad blocking + nginx

There’s this howto that explains how to set up the RPi as ad blocker.

I’ve two RPi’s acting a router and was already running dnsmasq. I decided to give it a try. Note that this howto can actually be used on any DNS serving Linux server.

First of all, don’t go with the pixelserv as it crashes after a few minutes.

Apache is an option that worked fine. A general hint: if you’re already running Apache or whatever on port 80, just add a 2nd static IP and make Apache listen to that.

For example (/etc/network/interfaces) — be sure it’s in the same subnet:

auto eth0:0
iface eth0:0 inet static
 address 10.100.200.254
 netmask 255.255.255.0
 broadcast 10.100.200.255

10.100.200.254 is the Apache IP that just serves a HTTP 200 (or 204).

Here’s the relevant config part (note the HTTP 204 code, more info on that later):

<VirtualHost adblock:80>
 ServerAdmin webmaster@domain.net
 DocumentRoot /var/www
 <Directory />
 Options FollowSymLinks
 AllowOverride All
 </Directory>
 <Directory /var/www/>
 Options Indexes FollowSymLinks MultiViews
 AllowOverride None
 Order allow,deny
 allow from all
 RewriteEngine on
 RedirectMatch 204 (.*)$
 ErrorDocument 204 " "
 </Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
 LogLevel warn
 CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

And edit /etc/hosts to add “adblock”:

10.100.200.254 adblock.local adblock

If I had used the IP instead of adblock I would have had this error:

# apache2ctl configtest
[Mon Sep 16 20:27:21 2013] [error] (EAI 2)Name or service not known: 
Failed to resolve server name for 10.100.200.254 (check DNS) 
-- or specify an explicit ServerName
Syntax OK

With the HTTP 200 code, some browsers expect some content/file in return. So it’s generally safer to use HTTP 204 “No Content“; which basically means “all good but I have nothing to serve you.”

Now, I call myself an nginx fan. Running Apache on a RPi is a no go (at least for me). I could’ve ran nginx on the RPi, but decided to run it on a remote server with an additional IP. At least for now. To preserve resources on the RPi.

Here’s the relevant config to run it on nginx (and be sure this config is the first file nginx parses; or it might redirect all the domains to some other site):

server {
 listen 80;
 server_name pixel.0x04.com 10.100.200.254 _;
 access_log /var/log/nginx/pixel.access.log;
 error_log /var/log/nginx/pixel.error.log;
 expires max;
 autoindex off; 
 rewrite ^(.*)$ /;
 location / {
  return 204 'pixel';
 }
}

And if we test it, this is what we get:

HTTP/1.1 204 No Content
Server: nginx/1.4.0
Date: Mon, 16 Sep 2013 18:36:52 GMT
Connection: close
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Cache-Control: max-age=315360000

And that’s it.

<3 nginx

The only downside is that this won’t work with HTTPS. You can run your webbrowser with a self signed certificate, but this will throw errors…

The result:

adblock

Leave a Reply...