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 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
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
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
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:
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.