Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 35 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save martinsohn/b6098f1ef678fe7094facbff811b0312 to your computer and use it in GitHub Desktop.
Save martinsohn/b6098f1ef678fe7094facbff811b0312 to your computer and use it in GitHub Desktop.
HOWTO Ubiquity EdgeMAX Ad & Malware Blocking Content Filtering using EdgeRouter as dnsmasq server

Ubiquity EdgeMAX Ad & Malware Blocking Content Filtering using EdgeRouter

NB: I am not using this setup anymore, and will not update the config and code if it breaks. I recommend Pi-hole instead, which gives many features such as web UI, statistics, DNS-over-HTTPS, and definitely better written code ;)

This will show you how to use your EdgeRouter as a local DNS server and blocking DNS queries to domains that hosts ads and malware.

The blocklist used is:

There used to be more blocklists in this script, but these were deprecated. I take no responsibility for the default blocklist and it might get deprecated or poisoned with malicious stuff.

Assumptions:

  • WAN interface is eth0 and is using DHCP
  • All other interfaces are for LAN
  • EdgeRouter has a DHCP server named 'LAN' with subnet '192.168.1.0/24' and router IP '192.168.1.1' (default ERX config)
  • EdgeRouter is using firmware 1.9.7 or higher (to use 'forwarding except-interface' instead of 'forwarding listen-on')

Connect to EdgeRouter and set system DNS servers

Connect to EdgeRouter using PowerShell

PS > ssh <username>@<edgerouter IP  address>

Enter configure mode and set system nameservers. The system DNS servers will later be used for DNS forwarding.

I'm using Cloudflare and OpenDNS

admin@ERX:~$ configure
admin@ERX:~$ set system name-server 1.1.1.1
admin@ERX:~$ set system name-server 1.0.0.1
admin@ERX:~$ set system name-server 208.67.220.220
admin@ERX:~$ set system name-server 208.67.222.222

Stop EdgeRouter from adding extra system DNS servers from eth0 DHCP (the ones your ISP wants you to use)

admin@ERX:~$ set interfaces ethernet eth0 dhcp-options name-server no-update

Renew DHCP for eth0. This will remove the ISP DNS servers from EdgeRouter system

admin@ERX:~$ run renew dhcp interface eth0

Commit and save the new config

admin@ERX:~$ commit
admin@ERX:~$ save

Enable DNS server with DNS forwarding on EdgeRouter

Based on Ubiquiti guide to setup EdgeRouter as DNS server with forwarding enabled.

Enable DNS cache (EdgeRouter forum post discussing cache sizes)

admin@ERX:~$ set service dns forwarding cache-size 3000

Set eth0 to not listen for DNS queries coming from your ISP or the internet. This is better for privacy.

Using 'except-interface' setting allows incoming queries from all other interfaces

admin@ERX:~$ set service dns forwarding except-interface eth0

Forward unknown/uncached DNS queries to the EdgeRouter system DNS servers

admin@ERX:~$ set service dns forwarding system

Make DHCP clients use EdgeRouter as DNS server

admin@ERX:~$ set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 dns-server 192.168.1.1

Commit and save the new config. Exit the configuration tool.

admin@ERX:~$ commit
admin@ERX:~$ save
admin@ERX:~$ exit

Renew DHCP on a client in your LAN

PS > ipconfig /release
PS > ipconfig /renew

Confirm DNS server is set to EdgeRouter and DNS works

PS > nslookup
Default Server:  UnKnown
Address:  192.168.1.1

> github.com
Server:  UnKnown
Address:  192.168.1.1

Non-authoritative answer:
Name:       github.com
Addresses:  140.82.118.4
            140.82.118.3

Validate configuration

Check the correct forwarding nameservers are used

admin@ERX:~$ show dns forwarding nameservers
-----------------------------------------------
   Nameservers configured for DNS forwarding
-----------------------------------------------
1.1.1.1 available via 'optionally configured'
1.0.0.1 available via 'optionally configured'
208.67.222.222 available via 'optionally configured'
208.67.220.220 available via 'optionally configured'

Generate some traffic on your network. Afterwards show DNS statistics

admin@ERX:~$ show dns forwarding statistics
----------------
Cache statistics
----------------
Cache size: 3000
Queries forwarded: 472
Queries answered locally: 316
Total DNS entries inserted into cache: 1381
DNS entries removed from cache before expiry: 0

---------------------
Nameserver statistics
---------------------
Server: 208.67.220.220
Queries sent: 205
Queries retried or failed: 8

Server: 208.67.222.222
Queries sent: 162
Queries retried or failed: 3

Server: 1.0.0.1
Queries sent: 248
Queries retried or failed: 6

Server: 1.1.1.1
Queries sent: 202
Queries retried or failed: 7

Add DNS filter to dnsmasq

Switch to the root user and create a bash script with vi in root home directory.

root@ERX:~# sudo -i
root@ERX:~# vi ~/update-adblock-dnsmasq.sh

Enable insert in 'vi' by pressing 'i'. Paste the following to the bash script

#!/bin/bash

# Blocklists pre-formatted as e.g. "0.0.0.0 ads.google.com"
# NB: the script implies blocklists use 0.0.0.0 as the blackhole IP. If you change blocklists you need to change the code.
blocklist_urls=("https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts")

# Blackhole/IP to respond to DNS query if domain is on blocklist
# IP "0.0.0.0" is a black hole. Per RFC 1122, section 3.2.1.3 "This host on this network. MUST NOT be sent, except as a source address as part of an initialization procedure by which the host learns its own IP address."
blackhole_ip="0.0.0.0"

# Block configuration to be used by dnsmasq
blocklist="/etc/dnsmasq.d/dnsmasq-blocklist.conf"
# Temp blocklists
tmp_blocklist="/tmp/dnsmasq-raw_blocklist.conf.tmp"

# Make sure we're starting with empty blocklists
rm -f $tmp_blocklist

# Blocklists pre-formatted as e.g. "0.0.0.0 ads.google.com"
# NB: the script implies blocklists use 0.0.0.0 as the blackhole IP. If you change blocklists you need to change the code.
# You could use regex matches to make this prettier and more flexible.
for i in "${blocklist_urls[@]}"
do
    curl -s "$i" | sed "s/0\.0\.0\.0 //" >> $tmp_blocklist
done

# Remove any comment lines/lines containing '#'
sed -i "/#.*$/d;/^$/d" $tmp_blocklist

# Format raw blocklist
# Add to start of all lines: '/address='
sed -i "s/^/address=\//g" $tmp_blocklist
# Add to end of all lines: '/$blackhole_ip'
sed -i "s/$/\/$blackhole_ip/" $tmp_blocklist

# Keep only unique entries
sort $tmp_blocklist | uniq > $blocklist

# Clean up temp blocklists
rm -f $tmp_blocklist

# Restart dnsmasq to load new config
/etc/init.d/dnsmasq force-reload

Save the bash file by hitting escape, ':wq', and enter.

Make sure you're root, chmod the script, and run the script.

root@ERX:~# sudo -i
root@ERX:~# chmod a+x ~/update-adblock-dnsmasq.sh
root@ERX:~# ~/update-adblock-dnsmasq.sh

Make sure no errors were written to the console. Then add the script to crontab. Contab will generate a new blocklist everyday from your blocklist sources.

root@ERX:~# (crontab -l ; echo "20 4 * * *  /root/update-adblock-dnsmasq.sh") | crontab -

Disconnect from the router

root@ERX:~# logout
admin@ERX:~# exit

Visit the following sites to confirm the ad-blocker is working:

@SyRaza
Copy link

SyRaza commented Jun 13, 2019

Hoping you might be able to help me out. I'm following your guide and I keep getting this error.

ne@EdgeRoute# set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 dns-server
The specified configuration node requires a value
Set failed

I'm simply copy-pasting what you have written

@marksherman
Copy link

@SyRaza you need to finish it with the IP address of your router, which for me is 192.168.1.1.

So the whole thing is set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 dns-server 192.168.1.1

@martinsohn
Copy link
Author

martinsohn commented Sep 12, 2019

@marksherman thank you. Fixed the issue in the guide.

@Bugman1400
Copy link

Hmm...the DShield domain lists seem to be discontinued. Wonder what the Pi-hole scripts are using.

@martinsohn
Copy link
Author

Hmm...the DShield domain lists seem to be discontinued. Wonder what the Pi-hole scripts are using.

Thank you. I have added a known blocklist and removed any others. Did some quick changes to the code too. I don't have the setup to test the new code, so fingers crossed an use at own risk.

@ajeden
Copy link

ajeden commented Mar 13, 2021

Hi.
Cleanup from comments works better with:

 # Remove comment lines and empty lines
    sed -i "/#.*$/d;/^$/d" $tmp_blocklist

as # can appear anywhere and empty lines create entries address=//0.0.0.0 and dnsmasq config fails to load.

@martinsohn
Copy link
Author

Thank you ajeden, I've added it.

Be aware that in the my recommended blocklist there also seems to be lines with domains that should be blocked which contains #, for example.:
0.0.0.0 www.specificpop.com #[Tracking.Cookie]

There might be other exceptions, but I'm not using more time into this project.

@Makaveli101
Copy link

thanks can't wait to give this a try

@rittwage-zz
Copy link

rittwage-zz commented Oct 23, 2022

Edgerouter no longer uses dnsmasq as the default, so you have to enable it.

set service dhcp-server use-dnsmasq enable

@mmhorda
Copy link

mmhorda commented Dec 29, 2022

Is it possible to add also an allow list (or exception to what was blocked)?

#Edit/Update

Nvermind I think I will just add something simple like:

sed -i '/googleadservices.com/d' $tmp_blocklist"

right before:

sed -i "/#.*$/d;/^$/d" $tmp_blocklist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment