AdBlocking with NGINX: Serving 1 pixel GIF and 204 No Content

There are two parts to a network-based ad block solution – resolving known advertisement host names to another server and have the server present a 1 pixel transparent GIF (for images) or 204 No Content HTTP response. This will effectively hide advertisements. This article addresses the latter part of having a server present 1 pixel transparent GIF and 204 No Content HTTP response for other files types.

 

Why use NGINX when there are pixelserv and nullserv?

If you recently upgraded to ASUS RT-AC68U with TomatoUSB (Shibby) and had been using the AdBlock script, you will (probably) realise that previous Pixelserv does not execute on ASUS RT-AC68U as it was not compiled for  ARM architecture.

Instead of cross-compiling Pixelserv for ASUS RT-AC68U, I decided to leverage NGINX web server in TomatoUSB (Shibby). This way, the ad block solution will not be  limited to ASUS RT-AC68U, you can also set up NGINX on Raspberry Pi or any other devices.

 

Serving 1 pixel transparent GIF and 204 No Content

Below is the config file I have created for ASUS RT-AC68U on TomatoUSB (Shibby). You can replicate the relevant lines to your NGINX config. The important lines that actually does the work are highlighted.

 

For those using TomatoUSB (Shibby)’s NGINX Web Server

If you are using TomatoUSB (Shibby)’s NGINX Web Server, simply add the following into the Custom configuration under the Web Server Settings. What it does is defining another HTTP instance that listens on port 80.

It should look like the following.

TomatoUSB NGINX Web Server
TomatoUSB NGINX Web Server

 

How does it work?

This section explains the above-mentioned highlighted lines and what they actually do.

Set the expiration time longer

This basically instructs the browser to cache the response so that it does not request it again unless the browser cache is purged.

Redirecting image request and serving 1 pixel transparent GIF

This regular expression (regex) attempts to match all request that ends with .png, .gif, .jpg and .jpeg and serves a empty_gif (1 pixel transparent GIF) instead.

Redirecting other requests and serves 204 No Content

This regular expression matches all requests that slipped through the previous one (essentially a catch all rule) and returns 204 No Content to the browser. To the browser, this codes means “Okay, I saw your request but I got nothing for you”.

 

Conclusion

And that is pretty much about it! I will be updating this set of codes when I got new ideas. Do check back for more.

 

 

Treat shadowandy!

If these step-by-step guides have been very helpful to you and saved you a lot of time, please consider treating shadowandy to a cup of Starbucks.  

28 thoughts on “AdBlocking with NGINX: Serving 1 pixel GIF and 204 No Content

  • July 2, 2014 at 10:34 am
    Permalink

    I could use some clarification on this article – thanks for writing it BTW.

    Do you still need to change the router admin interface port like you do with pixelserv?

    Also, do you have to put a path and enable pixelserv in the adblock script for it to work with nginx?

    I don’t see how the requests are automatically getting served based on this article.

  • July 2, 2014 at 11:57 am
    Permalink

    Hi Mike,

    Yes, you will need to change the router’s web admin port so that nginx can make use of port 80.

    For the adblock script, you will need to set NIP to your router’s IP (which is where nginx is hosted) for it to work.

    Just like pixelserv, by itself, just serves a 1 pixel image. It is how you integrate it with other components to have a solution that solves a particular issue.

    Hope it helps.

  • August 8, 2014 at 9:33 pm
    Permalink

    Would it be possible to get it to work with port 80 and 443?

  • August 10, 2014 at 2:15 pm
    Permalink

    Moo,

    The line 18 above actually makes it work with port 80. As for port 443, not sure if it will work without a valid SSL handshake.

  • December 14, 2014 at 5:27 pm
    Permalink

    Sorry to make the stupid question. How do we install NGINX on TomatoUSB? There is not a clear tut in the web.

  • January 31, 2015 at 11:26 pm
    Permalink

    Joe,

    NGINX is actually part of the TomatoUSB (Shibby) offering.

  • April 22, 2015 at 6:45 pm
    Permalink

    This doesn’t work on my ASUS RT-AC66U. Well, I don’t get it: are you just blocking ANY pics (png, jpg, …)? How does the nginx config know what pics actually are ads and which pics aren’t?!

  • July 26, 2015 at 6:23 am
    Permalink

    Hi shadowandy!
    I’m having difficulties to get this to work… so I copied your AdBlock script from the other tutorial and it is running. Now all I have to do is start the NGINX Web Server and copy the custom parameters to “NGINX
    Custom configuration”, right? I also changed NIP in the adblock script to my router’s IP, but I’m still getting ads.
    Any help is greatly apreciated!

  • July 26, 2015 at 2:04 pm
    Permalink

    Jerome,

    Make sure you have change your web admin page to run off other ports (non 80/TCP) because NGINX will be using port 80.

    Regardless of whether you are using NGINX, it will be good to do a nslookup on ad hostnames to see if your adblock is working first.

  • July 26, 2015 at 2:47 pm
    Permalink

    I did that too, forgot to mention it.
    Any other suggetions?

  • July 26, 2015 at 5:57 pm
    Permalink

    Jerome,

    For your DNS server settings, you should be using the IP of your TomatoUSB (Shibby) router that has implemented the ad block script.

    You should do nslookup on one of your LAN devices. For the hostname, you can try nslookup doubleclick.net which should not resolve to its correct IP address.

    If the ad block script has not been implemented correctly, you will see advertisements regardless of whether NGINX is running or not.

  • July 26, 2015 at 6:46 pm
    Permalink

    Thanks for your answer!
    By “DNS server settings” do you mean the settings on my PC or the “Static DNS” settings on the router? I have not configured any static DNS on the router and use 192.168.0.1 (Router’s IP) as DNS server on my PC which is connected via LAN.
    If I do a nslookup of doubleclick.net from my PC I get this:
    Server:
    127.0.0.1

    Address:
    127.0.0.1#53

    Non-authoritative answer:
    Name:
    doubleclick.net

    Address:
    70.32.146.212

    So I guess the script is not implemented correctly, though it is running (“dnsmasq is running”).
    This is all I did: copy the script from your other tutorial, changed NIP to “192.168.0.1”, changed the Web Admin port to something other than 80 and rebooted several times. Anything else I need to do?

    Thanks so much – I will make sure to donate at least a cup of coffee if we get this to work! By the way, should we continue here: http://www.shadowandy.net/wp/2012/11/adblocking-with-tomatousb-router-ad-free-internet-for-all-your-devices.htm as it is essentially a problem with that script?

  • July 26, 2015 at 11:23 pm
    Permalink

    Jerome,

    Try the following commands:

    nslookup
    server 192.168.0.1
    doubleclick.net

  • July 27, 2015 at 3:39 pm
    Permalink

    C:\Users\Jerome>nslookup
    Standardserver: unknown
    Address: 192.168.0.1

    > server 192.168.0.1
    Standardserver: unknown
    Address: 192.168.0.1

    > doubleclick.net
    Server: unknown
    Address: 192.168.0.1

    Nicht autorisierende Antwort:
    Name: doubleclick.net
    Address: 70.32.146.212

  • July 27, 2015 at 3:45 pm
    Permalink

    Jerome,

    Is 192.168.0.1 your router’s IP?

    If it is 192.168.0.1, what is the result if you issue the following command? “nslookup doubleclick.net 192.168.0.1” (without the quotes).

  • July 27, 2015 at 3:48 pm
    Permalink

    Yes, 192.168.0.1 is my router’s IP.
    This is the result I get:
    C:\Users\Jerome>nslookup doubleclick.net 192.168.0.1
    Server: unknown
    Address: 192.168.0.1

    Nicht autorisierende Antwort:
    Name: doubleclick.net
    Address: 70.32.146.212

  • July 27, 2015 at 4:08 pm
    Permalink

    Jerome,

    Your adblock script is not implemented correctly.

  • July 27, 2015 at 4:10 pm
    Permalink

    Yes, we know this since yesterday 😉
    The question is why is it not working, although I just copied it and it is running?

  • July 27, 2015 at 4:26 pm
    Permalink

    Jerome,

    Yesterday, I can only conclude that you are not using your router for the DNS resolution as your nslookup is using 127.0.0.1 on your PC. So I am trying to isolate user’s mistake.

    What I am trying to do so far is to isolate whether did you mistakenly use other DNS server instead of your router’s. That is why I forced the DNS resolution to use 192.168.0.1. After making nslookup to use your router for DNS resolution, I can conclude that you did not implement the script correctly.

    What you can do now is look at the logs and see which many addresses are processed. There are quite a few discussion in the comments over at the post. Usually, removing some of the list works.

  • July 27, 2015 at 5:19 pm
    Permalink

    Alright so I have the same problem as Mal, meaning there is no file named “hosts” in /tmp. I tried modifying the script to reduce the number of hosts (only using GETS=”1″ through GETS=”6″) but that does not change anything besides the number of entries, still no hosts file created.

    I think my RT-AC68U should have enough memory anyways:
    Total / Free Memory 249.64 MB / 220.01 MB (88.13%)
    Total / Free NVRAM 64.00 KB / 29.73 KB (46.46%)
    This is with all 6 hosts enabled.

  • July 29, 2015 at 7:40 am
    Permalink

    Jerome,

    You can try the list I posted on June 15th, 2015 at 8:05 am on that post in my reply to Don. That solved Don’s issue with huge adblock list.

  • August 20, 2015 at 3:22 am
    Permalink

    Hello, thanks for nice solution, but is there any option to add to your solution https handling? usualy doubleclicks googleads and many more are hosted on https which leads to something like https://routerwithnginx … which in my case ending up on administrative page requesting password.

    of course I can change port for admin https page, but I think then will be requested 1px picture for https ad service replyed from router as notfound as there will be no nginx on that port running.
    right?

    Thanks for advice
    Kriznik

  • August 29, 2015 at 2:42 am
    Permalink

    Hello again,
    I’m just playing with ipv6 and figured out that if my devices are using ipv6 from tomatoshibby dhcp pd, they are connected directly to the internet without adblock functionality at all. Is there any chance to get this sorted? :/

  • August 31, 2015 at 5:00 am
    Permalink

    nevermind, I’ve rewrote adblock.sh for better support of the ipv4/6 and changed https port for administration… 🙂

  • August 31, 2015 at 7:54 am
    Permalink

    kriznik,

    For the https portion, I added another set of configuration codes for nginx to listen on 443 (https) and self generated the certificate. It does not work very well as modern Web browsers will complain that the certificate is not trusted and the hostname differs (from the url and the one defined in the certificate).

    As for the IPv6 support, good that you managed to address it through rewriting. I think quite a few readers will be interested in how you did it.

Comments are closed.