DNS based adblock using OpenWRT, OpenDNS, and dnsmasq

[Update 24 Feb 2018: I am now using a MikroTik router and have written an article to do the same kind of DNS adblocking.]

 

Why use a DNS based adblock?  Because I prefer to try to keep advertisements and pop ups off of all computers that use my internet connection, not just the ones with an ad-blocking  browser plugin installed.  It also cuts down on bandwidth usage from those auto-play advertising videos and flashing images.

This setup works great using OpenWRT router firmware and dnsmasq for DNS.  It was in use on my home router up until recently.  I believe that the lists have grown to a size that puts a strain on my aging router hardware so I removed this setup until I get a newer router with more memory.

My particular settings are a mashup of several scripts and resources I found online long ago.  Unfortunately I do not have the original sources to provide reference links.

Here is what I used to set it up:

  • Linksys WRT54G v4 (4MB Flash, 16MB RAM)
  • OpenWRT Backfire 10.03.1

There are several parts I used to get this setup and automated so that the adblock lists update each morning at 05:00.  Also I created an account with OpenDNS so that I can forward and filter DNS queries based off of their lists.

These are the changes I made to the OpenWRT router configuration:

  • OpenWRT > System > Software

Installed package luci-app-ddns to automatically update our dynamic IP with the OpenDNS service DNS-O-Matic.

  • OpenWRT > System > Startup > Local Startup

This script will download lists from various websites and then rebuild them in a way that is useful for our DNS ad-blocking.

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.

#!/bin/sh
#Block ads, malware, etc.
logger -t "adblock" -s 'Starting adblock setup...'

#Delete the old adblock_hosts to make room for the updates
rm /tmp/adblock_hosts

logger -t "adblock" -s 'Downloading hosts lists...'
wget -qO- "http://winhelp2002.mvps.org/hosts.txt" | awk '/^0.0.0.0/' > /tmp/block.build.list
wget -qO- "http://www.malwaredomainlist.com/hostslist/hosts.txt" | awk '{sub(/^127.0.0.1/, "0.0.0.0")} /^0.0.0.0/' >> /tmp/block.build.list
wget -qO- "http://hosts-file.net/ad_servers.txt" | awk '{sub(/^127.0.0.1/, "0.0.0.0")} /^0.0.0.0/' >> /tmp/block.build.list
wget -qO- "http://adaway.org/hosts.txt" | awk '{sub(/^127.0.0.1/, "0.0.0.0")} /^0.0.0.0/' >> /tmp/block.build.list

if [ -s "/etc/black.list" ]
then
 logger -t "adblock" -s 'Adding blacklist...'
 awk '/^[^#]/ { print "0.0.0.0",$1 }' /etc/black.list >> /tmp/block.build.list
fi

logger -t "adblock" -s 'Sorting lists...'
awk '{sub(/\r$/,"");print $1,$2}' /tmp/block.build.list|sort -u > /tmp/block.build.before

if [ -s "/etc/white.list" ]
then
 #Filter the blacklist, supressing whitelist matches
 # This is relatively slow =-(
 logger -t "adblock" -s 'Filtering white list...'
 awk '/^[^#]/ {sub(/\r$/,"");print $1}' /etc/white.list | grep -vf - /tmp/block.build.before > /tmp/adblock_hosts
else
 cat /tmp/block.build.before > /tmp/adblock_hosts
fi

logger -t "adblock" -s 'Cleaning up...'

#Delete files used to build list to free up the limited space
rm -f /tmp/block.build.before
rm -f /tmp/block.build.list

logger -t "adblock" -s 'Restarting dnsmasq...'
/etc/init.d/dnsmasq restart

logger -t "adblock" -s 'Finished adblock setup'

exit 0
  • OpenWRT > System > Scheduled Tasks

This will run our startup script every morning at 05:00 to get the latest adblock lists.

0 5 * * * /etc/rc.local
  • OpenWRT > Services > Dynamic DNS

This will update our IP address with OpenDNS services for when our IP changes.

Enable: Checked
Service: -- custom --
Custom update-URL: http://[USERNAME]:[PASSWORD]@updates.dnsomatic.com/nic/update?hostname=[DOMAIN]&myip=[IP]
Hostname: all.dnsomatic.com
Username: <username>
Password: <password>
Source of IP address: network
Network: wan
Check for changed IP every: 10
Check-time unit: min
Force update every: 72
Force-time unit: h
  • OpenWRT > Network > DHCP and DNS > General Settings

Forward our DNS requests to OpenDNS.

DNS forwardings: 208.67.222.222, 208.67.220.220
  • OpenWRT > Network > DHCP and DNS > Resolv and Hosts Files

Make sure that we do not use our ISP’s DNS so that all requests get forwarded to OpenDNS.

Ignore resolve file: Checked
Ignore Hosts file: Unchecked
Additional Hosts files: /tmp/adblock_hosts
  • OpenWRT > Network > DHCP and DNS > Advanced Settings

Extra settings that probably aren’t required but I like their usefulness.

Filter private: Checked
Filter useless: Checked
Localise queries: Checked
Expand hosts: Checked
No negative cache: Unchecked
Strict order: Checked
  • OpenWRT > Network > Firewall > Redirections

This firewall rule will re-route all DNS traffic to our router so that our DNS setup cannot be bypassed.  If someone specifies a different DNS server in their network config, our firewall will gracefully and transparently redirect the request to our DNS setup.

Add a new entry to Redirections that matches the following.  Change the destination to the router’s IP, mine is 192.168.15.1

Name             Protocol     Source              Via                     Destination            Action
DNS Redirect     TCP+UDP      lan:0.0.0.0/0:*     Device:0.0.0.0/0:53     lan:192.168.15.1:*     DNAT

5 Replies to “DNS based adblock using OpenWRT, OpenDNS, and dnsmasq”

  1. Thank you for your post. I successfully used your ideas with openwrt chaos calmer.

    Next step I will used privoxy. So far so good.

  2. I have an adblocker app called weblock. The app icon is purple with a hand outline. How do I do your configuration in the app so that I can redirect ads to OpenDNS and speed up my connection. I can set up a dummy proxy and set up a custom proxy as well as blacklist and whitelist rules. How should I do this as well as how should I set up the redirect rules.

  3. Yes, much has changed in 2 years. I have a working configuration on the newer OpenWRT and also a newer router that will handle more traffic and more memory for the massive domain list. Most of the configuration stays the same.

    This is the new update URL that I use: https://[USERNAME]:[PASSWORD]@updates.dnsomatic.com/nic/update?hostname=all.dnsomatic.com

    I put one of my domains into the Hostname/Domain field also so that it can do its thing when checking the IP for comparison.

  4. Hello. Sorry for bad english. Now, in Openwrt 15 (chaos calmer), ddns configuration is different: Hostname all.dnsomatic.com is not right. could you please… update that config, please??
    Thank you very much.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.