DNS-based adblocking on VyOS 1.4 & 1.5
(Updated: )
Here I describe how to enable DNS-based adblocking on VyOS, which uses PowerDNS recursor as DNS resolver.
Update: now also works for VyOS 1.5.
Adblocking on VyOS using PowerDNS ¶
There’s a few options available to achieve this:
- Use squidguard, e.g. see here (ahmeddirie.com) & here (vyos.io).
- Use
iptables
to block stuff - Use
/etc/hosts
entries (e.g. viaset system static-host-mapping host-name
) - Use PowerDNS specifics see here (may.yt), here (powerdns.com) and here (github.com) [chosen].
I chose 4. using the native PowerDNS recursor for speed and simplicity (no extra parts needed). To get this working, we can use a Lua script that is called for each DNS resolving. This is based on this (may.yt) script, however I return NXDOMAIN
which should be faster (pi-hole.net) (although pihole claims some clients might still try to resolve) and works for any DNS record type:
-- File: /config/scripts/pdns-adblock-script.lua
-- Docs: https://docs.powerdns.com/recursor/lua-scripting/hooks.html
--
-- Load from recursor.conf, e.g. lua-dns-script=/config/scripts/pdns-adblock-script.lua
adservers=newDS()
-- permitted=newDS()
function preresolve(dq)
-- if permitted:check(dq.qname) or (not adservers:check(dq.qname)) then
if (not adservers:check(dq.qname)) then
return false
end
-- Return NXDOMAIN (non-existent domain), which
dq.rcode = pdns.NXDOMAIN -- set NXDOMAIN answer
return true
end
-- Blocklist should contain something like:
-- return{"101com.com", "101order.com"}
adservers:add(dofile("/config/scripts/pdns-adblock-blocklist.lua"))
-- permitted:add(dofile("/config/scripts/pdns-adblock-permitted.lua"))
To get this working, I ensure you populate pdns-adblock-blocklist.lua
with a list of your liking. Furthermore, we need to update PowerDNS’ recursor.conf
to load this script by adding lua-dns-script=/config/scripts/pdns-adblock-script.lua
.
Ensure configuration is permanent ¶
However, on VyOS, recursor.conf
is generated automatically, so we resort to using a script attached as post-commit hook as follows:
Update: this is not required in v1.5 anymore?
#!/bin/vbash
# File: /config/scripts/commit/post-hooks.d/adblock
# N.B. the script name is quite restrictive! See https://vyos.dev/T4917
source /opt/vyatta/etc/functions/script-template
if [ "$(id -g -n)" != 'vyattacfg' ] ; then
exec sg vyattacfg -c "/bin/vbash $(readlink -f $0) $@"
fi
# For VyOS 1.4:
# echo "lua-dns-script=/config/scripts/pdns-adblock-script.lua" | sudo tee -a /run/powerdns/recursor.conf
# For VyOS 1.5:
echo "lua-dns-script=/config/scripts/pdns-adblock-script.lua" | sudo tee -a /run/pdns-recursor/recursor.conf
# Need to restart PowerDNS in order to process conf change.
run restart dns forwarding
Populate adblock list ¶
To fill pdns-adblock-blocklist.lua
I wrote a script (github.com) that supports a few different adblocking formats, and has a few sources predefined. Apply some judgement when choosing adblock sources as it might contain false positives or even malicious entries, although I’m not sure of a vector how this can be exploited.
Testing ¶
Now test that this works:
vyos@vyos:~$ host 101com.com
Host 101com.com not found: 3(NXDOMAIN)
Profit!
Update November 2024 ¶
The location of recursor.conf
changed from VyOS 1.4 to 1.5:
vyos@vyos# commit; save; exit;
tee: /run/powerdns/recursor.conf: No such file or directory
lua-dns-script=/config/scripts/pdns-adblock-script.lua
Cannot restart dns-forwarding service while a commit is in progress
exit
It’s now stored at /run/pdns-recursor/recursor.conf
:
vyos@vyos:/config/scripts/commit/post-hooks.d$ sudo find / | grep recursor.conf$
/run/pdns-recursor/recursor.conf
Update the script (already done above), and restart.
Secondly, the dns-forwarder cannot restart while a commit is in progress:
Cannot restart dns-forwarding service while a commit is in progress
But it seems the recursor.conf
persists config changes, so no update is needed. Simply remove /config/scripts/commit/post-hooks.d/adblock
.
N.B. Besides this config change, the script survives upgrade from v1.4 to v1.5.