Block ads with OpenWRT dnsmasq

Block ads with OpenWRT dnsmasq and automate downloading of the latest list once a week.

Motivation

I do not mind seeing ads but they must not be intrusive. Try browsing my blog without ad blocker (if you are using it now) and you will see that I do not place ads in places where it disrupts natural flow of reading.

On PC, it is possible to install ad blockers into browsers. Some browsers even come with such a feature builtin too. However, you cannot do that on some devices, such as Smart TV. Therefore, I had to find an effective way to block ads with my OpenWRT router.

Steps

Pre-requisites

Firstly, I am assuming you are using OpenWRT. It comes with dnsmasq which is a DNS forwarder.

Bash script for retrieving latest block list host file

Copy the script below into your OpenWRT. Place it somewhere that can persist over reboots, /opt/dnsmasq-blocklist/update-blocklist.sh.

#!/bin/sh
set -e

mkdir -p /tmp/dnsmasq-blocklist
curl -s --max-filesize 524288 -o /tmp/dnsmasq-blocklist/danpollock.hosts "http://someonewhocares.org/hosts/zero/hosts"
/etc/init.d/dnsmasq restart

Notes:

  1. As an example, the script above downloads Dan Pollock’s host file. You can use whichever you prefer as long as it is not too big or else your OpenWRT device will run out of free RAM.
  2. The block list is downloaded into an in-memory temporary storage for speed and to reduce writes to flash.
  3. In this case, curl is preferred over wget because it can limit file size of download, in case the block list someday gets too big, the router may not have enough RAM to operate properly. Therefore, this acts as a safeguard.
  4. If you want to download from an SSL source, you need to install SSL libraries.

Grant execute permission to the script

Run the following command:

chmod +x /opt/dnsmasq-blocklist/update-blocklist.sh

Run the script on startup

Place the following lines into /etc/rc.local above the exit 0 line.

# Update dnsmasq block list
/opt/dnsmasq-blocklist/update-blocklist.sh

Update block list once a week

Edit crontab, crontab -e. Place the following line:

0 2 * * 1 /opt/dnsmasq-blocklist/update-blocklist.sh

If you are unfamiliar with cron syntax, the above means the script is executed once every Monday at 2am.

You can also add the line above via LuCI GUI, System > Scheduled Tasks.

Configure dnsmasq to load the block list

Edit /etc/config/dhcp, add the line below into config dnsmasq:

config dnsmasq
    ...
    list addnhosts '/tmp/dnsmasq-blocklist/danpollock.hosts'
    ...

Restart dnsmasq to take effect:

/etc/init.d/dnsmasq restart