# Ubiquity EdgeMAX Ad & Malware Blocking Content Filtering using EdgeRouter 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. An alternative is to use [Pi-hole](https://pi-hole.net/), which gives many features such as web UI, statistics, DNS-over-HTTPS, and possibly better written code ;) The blocklists used are: - [Ad blocklist from Yoyo Internet Services](https://pgl.yoyo.org/adservers/serverlist.php?hostformat=dnsmasq&showintro=0&mimetype=plaintext) - [High risk domains from DShield](https://www.dshield.org/feeds/suspiciousdomains_High.txt) - [Medium risk domains from DShield](https://www.dshield.org/feeds/suspiciousdomains_Medium.txt) - [Low risk domains from DShield](https://www.dshield.org/feeds/suspiciousdomains_Low.txt) 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 ```powershell PS > ssh @ ``` Enter configure mode and set system nameservers. The system DNS servers will later be used for DNS forwarding. I'm using [Cloudflare](https://1.1.1.1/dns/) and [OpenDNS](https://use.opendns.com/) ``` 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](https://help.ubnt.com/hc/en-us/articles/115010913367-EdgeRouter-DNS-Forwarding-Setup-Options). Enable DNS cache ([EdgeRouter forum post discussing cache sizes](https://community.ubnt.com/t5/EdgeRouter/DNS-cache-questions/td-p/1572160)) ``` 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 ```powershell PS > ipconfig /release PS > ipconfig /renew ``` Confirm DNS server is set to EdgeRouter and DNS works ```powershell 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 "address=// # NB: the script later implies pre-formatted blocklists use 127.0.0.1 as the blackhole IP formatted_blocklists=("https://pgl.yoyo.org/adservers/serverlist.php?hostformat=dnsmasq&showintro=0&mimetype=plaintext") # Blocklists with raw IP addresses raw_blocklists=("https://www.dshield.org/feeds/suspiciousdomains_High.txt" "https://www.dshield.org/feeds/suspiciousdomains_Medium.txt" "https://www.dshield.org/feeds/suspiciousdomains_Low.txt" ) # 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-blocklist.conf.tmp" tmp_formatted_blocklist="/tmp/dnsmasq-formatted_blocklist.conf.tmp" tmp_raw_blocklist="/tmp/dnsmasq-raw_blocklist.conf.tmp" # Make sure we're starting with empty blocklists rm -f $tmp_formatted_blocklist rm -f $tmp_raw_blocklist rm -f $tmp_blocklist # replace pre-formatted blocklist black hole IP with our preference # NB: This implies pre-formatted blocklists use 127.0.0.1 for i in "${formatted_blocklists[@]}" do curl -s "$i" | sed "s/127\.0\.0\.1/$blackhole_ip/" >> $tmp_formatted_blocklist done # Download blocklists for i in "${raw_blocklists[@]}" do curl -s "$i" >> $tmp_raw_blocklist done # Remove comment lines sed -i "/^#/d" $tmp_formatted_blocklist # Remove comment lines sed -i "/^#/d" $tmp_raw_blocklist # Format raw blocklist # Add to start of all lines: '/address=' sed -i "s/^/address=\//g" $tmp_raw_blocklist # Add to end of all lines: '/$blackhole_ip' sed -i "s/$/\/$blackhole_ip/" $tmp_raw_blocklist # Join files to one cat $tmp_raw_blocklist >> $tmp_formatted_blocklist # Remove invalid lines grep -E "^address=\/.{1,}\..{1,}\/0\.0\.0\.0" $tmp_formatted_blocklist > $tmp_blocklist # Keep only unique entries sort $tmp_blocklist | uniq > $blocklist # Clean up temp blocklists rm -f $tmp_raw_blocklist rm -f $tmp_formatted_blocklist 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: - https://thepcspy.com/blockadblock/ - https://ads-blocker.com/testing/