Adblock-oisd : 22.03 allows you to use huge blocklists with dnsmasq

UPDATE: an outcome of this thread has been the development of adblock-oisd - a super lean script written as an OpenWrt service file that implements adblocking via the oisd blocklist and incorporates several safety checks and useful features. adblock-oisd will download the latest oisd list and perform various safety checks associated with the file before and after restarting dnsmasq and act accordingly. It is designed to be run as a daily scheduled task.

adblock-oisd is available here:

ORIGINAL POST:
Not my work, just reposting here for more people to see. I'm using this method - it's truly insanely fast, and the full OISD blocklist is only consuming ~30mb ram on my r7800 / 22.03.

Thanks to luigi_xp whoever/wherever you are. Link to original reddit thread:

22.03-rcx comes with dnsmasq 2.86, which brings a full rewrite of the dns handling code making it much more efficient in both ram and processing for various things, including common blocklist syntax.

I'm running the full 1M+ line oisd blocklist with no noticeable performance penalty on my humble MT7621/128MB Archer C6.

I created a script which is literally

wget https://dnsmasq.oisd.nl -O /tmp/dnsmasq.d/oisd.txt && /etc/init.d/dnsmasq restart

and setup it to run every day and on startup, and it's working silk smooth. Dnsmasq is using a "large" amount of ram (17%), but considering what it's doing and that there's still a lot of free ram left, i'm happy with the result.

Unfortunately plugins such as adblock still choke because they process the lists before, but if you use dnsmasq directly and create a little script to download and update the lists it works as good if not better than the standalone plugins.

Hope someone finds this useful

13 Likes

Great - I run dnsmasq, now also at version 2.86, on my Linux desktop, with several blocklists that in total, in their human readable text format, consume over 27 Mbytes. I've been using dnsmasq since at least 2016. It's outstanding.

1 Like

Kudos for sharing this, afaik there are lot of people here on the forum who don't frequent reddit and vice a versa.

Obviously to each their own, and yes, that blocklist would probably choke simple-adblock on a 128Mb router, but there are upsides of "processing", especially if you're using multiple sources -- adblock pioneered and simple-adblock shamelessly copied the functionality to remove duplicates and unnecessary 3rd level domains from the final block list for supported dnsmasq/unbound configs.

Another upside of using adblock or simple-adblock is a built-in enforcement of OpenWrt's resolver across your network, so even if your clients are set up to use hardcoded DNS (but not DoT/DoH) servers, the ads would still be blocked.

PS. Have you run any actual tests to measure the performance of dnsmasq with and without that list?

3 Likes

Hey no problems re-posting it here. Exactly why I did it, I think a lot of people would never visit the Reddit/Openwrt community. In fact I only found it by complete accident doing a google search. Hit the jackpot in this case tho.

I'll send details of performance etc when I get home (which is very, very good BTW!)

I totally get the usage cases dnsmasq vs adblock & simple. Ie wanting to manage client DNS. However I'm pretty liberal with that, if guests want to use their own DNS, go for it.

The below graph is anecdotal. But context - I'm now running the full OISD blocklist, Layer Cake SQM, ~15 devices, 3x IP motion cameras, IOT & Guest WLAN, 100/20 (Australia speeds) on R7800. For comparison the full OISD blocklist on Adblock with 21.02 would hover around 20% on one CPU and could take literal seconds to load a webpage. The full OISD blocklist on dnsmasq is also noticeably faster than Adblock on 21.02 with OISD basic (webpage load speeds). No other graphs sorry, just what I described here.

I got home around 17:00, web browsing / searching etc. Video chat started around 17:35. All in all this router/config is just idling along. This is easily the fastest setup I've run....pages just load quickly.

One thing to note and IDKW, but after running the dnsmasq command on bootup, WLAN1-1 and WLAN1-2 stop providing DHCP. I just run "/etc/init.d/network restart" straight after in local startup, and all is good.

edit: forgot to mention the graph looks almost identical without dnsmasq/oisd_full. Close to zero impact

Also saw it over on Reddit, thanks for sharing here.

Just sharing what I've configured in Startup (above the exit 0 line):

mkdir -p /tmp/dnsmasq.d && wget https://dnsmasq.oisd.nl -O /tmp/oisd.txt && mv /tmp/oisd.txt /tmp/dnsmasq.d/oisd.txt && /etc/init.d/dnsmasq restart

And Scheduled Tasks (below line runs every day at 5:00am):

0 5 * * * mkdir -p /tmp/dnsmasq.d && wget https://dnsmasq.oisd.nl -O /tmp/oisd.txt && mv /tmp/oisd.txt /tmp/dnsmasq.d/oisd.txt && /etc/init.d/dnsmasq restart

Details:

mkdir -p /tmp/dnsmasq.d ensures the folder exists

wget https://dnsmasq.oisd.nl -O /tmp/oisd.txt downloads the list to /tmp/oisd.txt (a temporary file)

mv /tmp/oisd.txt /tmp/dnsmasq.d/oisd.txt moves the temporary file to the actual location. This is so that if the wget download fails it doesn't load an empty file. If the download failed, this command will fail as there won't be any /tmp/oisd.txt file to move.

/etc/init.d/dnsmasq restart restarts the dnsmasq service with the updated list

And for those who aren't familiar, anything in the /tmp directory is stored on RAM (not non-volatile storage), which is good for the longevity of the device.

I've paired the above with this firewall rule to force all devices' plain 53 connections to be filtered: https://openwrt.org/docs/guide-user/firewall/fw3_configurations/intercept_dns

7 Likes

Ah, you meant zero impact in CPU load, I thought you meant zero impact on speed of resolution requests (which was an issue with the older dnsmasq versions for large servers lists).

1 Like

@jackiechun does some minimum amount of control need to be put into place to ensure the source of the information isn't malicious and poisoning DNS entries?

Maybe I'm a nervous Nelly, because I never heard of oisd.nl before?

Example1: Maybe grep -v out any entries that map FQDN to an IP??

1 Like

It's a popular blocklist, integrated in AdGuard DNS, NextDNS, and ControlD: https://oisd.nl/howto

But you can use the above method with your own or any other blocklist if you want.

It looks like the OISD list almost tripled in size overnight and my OpenWRT was not able to handle it, did you encounter this as well?

You are right, the full dnsmasq file went from ~10mb to ~25mb. Hopefully this is a temporary issue?

Using an extra 55mb ram on r7800, but still have 280mb free and seems to be running fine.

Well looks like OISD full dnsmasq file is back at it's usual ~10mb on the website....

1 Like

Thanks for the update! This experience made me realize that my modest Archer C7 is too old to handle these possible fluctuations so I've decided to generate my own static dnsmasq blocklist in place of the OISD list, and changed to an adblocking public dns.

1 Like

I wrote earlier that with the startup script I lost DHCP for WLAN1-1 and WLAN1-2 (my guest and IOT WLAN's) and was using "/etc/init.d/network restart" at startup as a workaround. Now just sharing that I'm using sleep 60 before the script (last in local startup) and everything is working 100% without a network restart at startup. IMO sleep 60 is the nicer solution for me...

@jackiechun Thanks for that script with sense checking - good idea. I guess you could add a file size check and ignore if it's oversized - just an idea tho. I have used both NextDNS and Adguard before in round robin to accommodate the 300k dns lookup per month limit both of them have.

1 Like

I've decided to give it another try: the allure of using Cloudflare/Quad9 DNS servers was too great.

My solution: simple bash script that will pre-process the blocklist and push to Github if < 400,000 entries (arbitrarily chosen), and I've modified my command to download that blocklist from Github. Currently the list is ~340,000, when it ballooned 2 weeks ago it was ~ 950,000.

A bonus to this is I can append domains I want blocked (such as autoupdates for my Amazon Firesticks). Will run and see how it goes, I'll only report back if there are any issues.

EDIT: recent update went to 437,051 entries so I bumped my threshold up to 500,000 and my Archer C7 is still able to handle it.

3 Likes

Thanks guys for the posting of this thread.

Put this on a Netgear Wax202 in rc.local ; and it's taking care of business now.



top n 1

/$ top n 1

e[He[JMem: 93048K used, 416832K free, 12452K shrd, 0K buff, 27560K cached
CPU:   2% usr   0% sys   0% nic  97% idle   0% io   0% irq   0% sirq
Load average: 0.13 0.15 0.11 2/90 3869
e[7m  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMANDe[m
 3869  2854 root     R     1328   0%   2% top n 1
 3751  3750 dnsmasq  S    25332   5%   0% /usr/sbin/dnsmasq -C /var/etc/dnsmasq.
 3023     1 stubby   S     4952   1%   0% /usr/sbin/stubby -C /var/etc/stubby/st
 1629  1625 network  S     4584   1%   0% /usr/sbin/hostapd -s -g /var/run/hosta
 1628  1626 network  S     4404   1%   0% /usr/sbin/wpa_supplicant -n -s -g /var
 1911     1 root     S     4156   1%   0% /usr/sbin/uhttpd -f -h /www -r StonesT
 3595     1 root     S     2664   1%   0% {ntpd} /sbin/ujail -t 5 -n ntpd -U ntp
 1625     1 root     S     2664   1%   0% {hostapd} /sbin/ujail -t 5 -n hostapd 
 3750     1 root     S     2664   1%   0% {dnsmasq} /sbin/ujail -t 5 -n dnsmasq 
 1626     1 root     S     2664   1%   0% {wpa_supplicant} /sbin/ujail -t 5 -n w
 1315     1 root     S     2272   0%   0% /sbin/rpcd -s /var/run/ubus/ubus.sock
 1690     1 root     S     1836   0%   0% /sbin/netifd
    1     0 root     S     1692   0%   0% /sbin/procd
 1261     1 logd     S     1352   0%   0% /sbin/logd -S 64
  719     1 ubus     S     1340   0%   0% /sbin/ubusd
 1841     1 root     S     1316   0%   0% /usr/sbin/crond -f -c /etc/crontabs -l
 2698  1690 root     S     1312   0%   0% udhcpc -p /var/run/udhcpc-wlan0.pid -s
 3758  1690 root     S     1312   0%   0% udhcpc -p /var/run/udhcpc-wlan1.pid -s
 3622  3595 ntp      S     1312   0%   0% /usr/sbin/ntpd -n -N -S /usr/sbin/ntpd
 2854  2722 root     S     1312   0%   0% -ash
System Board
"kernel": "5.10.138",
"hostname": "OpenWrt",
"system": "MediaTek MT7621 ver:1 eco:3",
"model": "Netgear WAX202",
"board_name": "netgear,wax202",
"rootfs_type": "squashfs",
"release": {
	"distribution": "OpenWrt",
	"version": "22.03.0",
	"revision": "r19685-512e76967f",
	"target": "ramips/mt7621",
	"description": "OpenWrt 22.03.0 r19685-512e76967f"
opkg list-installed
/$ opkg list-installed
base-files - 1490-r19685-512e76967f
bind-dig - 9.18.1-1
bind-libs - 9.18.1-1
busybox - 1.35.0-3
ca-bundle - 20211016-1
cgi-io - 2022-08-10-901b0f04-21
curl - 7.85.0-2
diffutils - 3.8-1
dnsmasq-full - 2.86-14
dropbear - 2022.82-2
firewall4 - 2022-09-01-f5fcdcf2-1
fstools - 2022-06-02-93369be0-2
fwtool - 2019-11-12-8f7fe925-1
getdns - 1.7.0-2
getrandom - 2021-08-03-205defb5-2
hostapd-common - 2022-01-16-cff80b4f-11
iw - 5.16-1
iwinfo - 2022-08-19-0dad3e66-1
jansson4 - 2.13.1-2
jq - 1.6-2
jshn - 2022-05-15-d2223ef9-1
jsonfilter - 2018-02-04-c7e938d6-1
kernel - 5.10.138-1-218bf6e00a546ab5c6ea465b29f9c777
kmod-cfg80211 - 5.10.138+5.15.58-1-1
kmod-crypto-aead - 5.10.138-1
kmod-crypto-ccm - 5.10.138-1
kmod-crypto-cmac - 5.10.138-1
kmod-crypto-crc32c - 5.10.138-1
kmod-crypto-ctr - 5.10.138-1
kmod-crypto-gcm - 5.10.138-1
kmod-crypto-gf128 - 5.10.138-1
kmod-crypto-ghash - 5.10.138-1
kmod-crypto-hash - 5.10.138-1
kmod-crypto-hmac - 5.10.138-1
kmod-crypto-kpp - 5.10.138-1
kmod-crypto-lib-chacha20 - 5.10.138-1
kmod-crypto-lib-chacha20poly1305 - 5.10.138-1
kmod-crypto-lib-curve25519 - 5.10.138-1
kmod-crypto-lib-poly1305 - 5.10.138-1
kmod-crypto-manager - 5.10.138-1
kmod-crypto-null - 5.10.138-1
kmod-crypto-rng - 5.10.138-1
kmod-crypto-seqiv - 5.10.138-1
kmod-crypto-sha256 - 5.10.138-1
kmod-gpio-button-hotplug - 5.10.138-3
kmod-hwmon-core - 5.10.138-1
kmod-ipt-core - 5.10.138-1
kmod-ipt-ipset - 5.10.138-1
kmod-leds-gpio - 5.10.138-1
kmod-lib-crc-ccitt - 5.10.138-1
kmod-lib-crc32c - 5.10.138-1
kmod-mac80211 - 5.10.138+5.15.58-1-1
kmod-mt76-connac - 5.10.138+2022-08-26-5ec78e1e-4
kmod-mt76-core - 5.10.138+2022-08-26-5ec78e1e-4
kmod-mt7615-common - 5.10.138+2022-08-26-5ec78e1e-4
kmod-mt7915e - 5.10.138+2022-08-26-5ec78e1e-4
kmod-nf-conntrack - 5.10.138-1
kmod-nf-conntrack-netlink - 5.10.138-1
kmod-nf-conntrack6 - 5.10.138-1
kmod-nf-flow - 5.10.138-1
kmod-nf-ipt - 5.10.138-1
kmod-nf-log - 5.10.138-1
kmod-nf-log6 - 5.10.138-1
kmod-nf-nat - 5.10.138-1
kmod-nf-reject - 5.10.138-1
kmod-nf-reject6 - 5.10.138-1
kmod-nfnetlink - 5.10.138-1
kmod-nft-core - 5.10.138-1
kmod-nft-fib - 5.10.138-1
kmod-nft-nat - 5.10.138-1
kmod-nft-offload - 5.10.138-1
kmod-ppp - 5.10.138-1
kmod-pppoe - 5.10.138-1
kmod-pppox - 5.10.138-1
kmod-slhc - 5.10.138-1
kmod-thermal - 5.10.138-1
kmod-udptunnel4 - 5.10.138-1
kmod-udptunnel6 - 5.10.138-1
kmod-wireguard - 5.10.138-1
libatomic1 - 11.2.0-4
libblobmsg-json20220515 - 2022-05-15-d2223ef9-1
libc - 1.2.3-4
libcap - 2.63-1
libcurl4 - 7.85.0-2
libgcc1 - 11.2.0-4
libgmp10 - 6.2.1-1
libiwinfo-data - 2022-08-19-0dad3e66-1
libiwinfo-lua - 2022-08-19-0dad3e66-1
libiwinfo20210430 - 2022-08-19-0dad3e66-1
libjson-c5 - 0.15-2
libjson-script20220515 - 2022-05-15-d2223ef9-1
liblua5.1.5 - 5.1.5-10
liblucihttp-lua - 2022-07-08-6e68a106-1
liblucihttp0 - 2022-07-08-6e68a106-1
libmbedtls12 - 2.28.1-1
libmnl0 - 1.0.5-1
libnetfilter-conntrack3 - 1.0.9-2
libnettle8 - 3.7.3-2
libnfnetlink0 - 1.0.2-1
libnftnl11 - 1.2.1-1
libnghttp2-14 - 1.44.0-1
libnl-tiny1 - 2021-11-21-8e0555fb-1
libopenssl1.1 - 1.1.1q-1
libpthread - 1.2.3-4
librt - 1.2.3-4
libubox20220515 - 2022-05-15-d2223ef9-1
libubus-lua - 2022-06-01-2bebf93c-1
libubus20220601 - 2022-06-01-2bebf93c-1
libuci-lua - 2021-10-22-f84f49f0-6
libuci20130104 - 2021-10-22-f84f49f0-6
libuclient20201210 - 2021-05-14-6a6011df-1
libucode20220812 - 2022-08-29-344fa9e6-1
libustream-wolfssl20201210 - 2022-01-16-868fd881-1
libuv1 - 1.41.1-1
libwolfssl5.4.0.ee39414e - 5.4.0-stable-5
libyaml - 0.2.5-1
logd - 2021-08-03-205defb5-2
lua - 5.1.5-10
luci - git-20.074.84698-ead5e81
luci-app-firewall - git-22.089.67563-7e3c1b4
luci-app-opkg - git-22.154.41881-28e92e3
luci-app-wireguard - git-21.322.66896-8ae208d
luci-base - git-22.245.77528-487e58a
luci-lib-base - git-20.232.39649-1f6dc29
luci-lib-ip - git-20.250.76529-62505bd
luci-lib-jsonc - git-22.097.61921-7513345
luci-lib-nixio - git-20.234.06894-c4a4e43
luci-mod-admin-full - git-19.253.48496-3f93650
luci-mod-network - git-22.244.54818-b13d8c7
luci-mod-status - git-22.189.48501-6731190
luci-mod-system - git-22.140.66206-02913be
luci-proto-ipv6 - git-21.148.48881-79947af
luci-proto-ppp - git-21.158.38888-88b9d84
luci-proto-wireguard - git-22.213.40001-18e6040
luci-ssl - git-20.244.36115-e10f954
luci-theme-bootstrap - git-22.141.59265-d8ecf48
mtd - 26
netifd - 2022-08-25-76d2d41b-1
nftables-json - 1.0.2-2.1
ntpdate - 4.2.8p15-4
odhcp6c - 2022-08-05-7d21e8d8-18
openwrt-keyring - 2022-03-25-62471e69-3
opkg - 2022-02-24-d038e5b6-1
ppp - 2.4.9.git-2021-01-04-3
ppp-mod-pppoe - 2.4.9.git-2021-01-04-3
procd - 2022-06-01-7a009685-1
procd-seccomp - 2022-06-01-7a009685-1
procd-ujail - 2022-06-01-7a009685-1
px5g-wolfssl - 4
rpcd - 2022-08-24-82904bd4-1
rpcd-mod-file - 2022-08-24-82904bd4-1
rpcd-mod-iwinfo - 2022-08-24-82904bd4-1
rpcd-mod-luci - 20210614
rpcd-mod-rrdns - 20170710
stubby - 0.4.0-6
ubi-utils - 2.1.4-1
ubox - 2021-08-03-205defb5-2
ubus - 2022-06-01-2bebf93c-1
ubusd - 2022-06-01-2bebf93c-1
uci - 2021-10-22-f84f49f0-6
uclient-fetch - 2021-05-14-6a6011df-1
ucode - 2022-08-29-344fa9e6-1
ucode-mod-fs - 2022-08-29-344fa9e6-1
ucode-mod-ubus - 2022-08-29-344fa9e6-1
ucode-mod-uci - 2022-08-29-344fa9e6-1
uhttpd - 2022-08-12-e3395cd9-1
uhttpd-mod-ubus - 2022-08-12-e3395cd9-1
urandom-seed - 3
urngd - 2020-01-21-c7f7b6b6-1
usign - 2020-05-23-f1f65026-1
wireguard-tools - 1.0.20210424-3
wireless-regdb - 2022.06.06-1
wpad-basic-wolfssl - 2022-01-16-cff80b4f-11
zlib - 1.2.11-6
1 Like

Last night there was an issue with OISD and this morning I found out with DNSMasq not working.
The blocklist had a one line error message so since the download succeeded the command continued with restarting DNSMasq.

Log:

Thu Oct 20 05:10:00 2022 cron.err crond[1447]: USER root pid 21924 cmd curl --max-time 60 --retry 4 --retry-delay 6 --url https://dnsmasq.oisd.nl/ --output /tmp/oisd.txt && mv /tmp/oisd.txt /tmp/dnsmasq.d/oisd.txt && /etc/init.d/dnsmasq restart
Thu Oct 20 05:10:00 2022 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM
Thu Oct 20 05:10:04 2022 daemon.crit dnsmasq[1]: bad option at line 1 of /tmp/dnsmasq.d/oisd.txt
Thu Oct 20 05:10:04 2022 daemon.crit dnsmasq[1]: FAILED to start up
Thu Oct 20 05:10:09 2022 daemon.crit dnsmasq[1]: bad option at line 1 of /tmp/dnsmasq.d/oisd.txt
Thu Oct 20 05:10:09 2022 daemon.crit dnsmasq[1]: FAILED to start up
Thu Oct 20 05:10:14 2022 daemon.crit dnsmasq[1]: bad option at line 1 of /tmp/dnsmasq.d/oisd.txt
Thu Oct 20 05:10:14 2022 daemon.crit dnsmasq[1]: FAILED to start up
Thu Oct 20 05:10:19 2022 daemon.crit dnsmasq[1]: bad option at line 1 of /tmp/dnsmasq.d/oisd.txt
Thu Oct 20 05:10:19 2022 daemon.crit dnsmasq[1]: FAILED to start up
Thu Oct 20 05:10:24 2022 daemon.crit dnsmasq[1]: bad option at line 1 of /tmp/dnsmasq.d/oisd.txt
Thu Oct 20 05:10:24 2022 daemon.crit dnsmasq[1]: FAILED to start up
Thu Oct 20 05:10:29 2022 daemon.crit dnsmasq[1]: bad option at line 1 of /tmp/dnsmasq.d/oisd.txt
Thu Oct 20 05:10:29 2022 daemon.crit dnsmasq[1]: FAILED to start up
Thu Oct 20 05:10:29 2022 daemon.info procd: Instance dnsmasq::cfg01411c s in a crash loop 6 crashes, 0 seconds since last crash

I was thinking just adding || rm /tmp/dnsmasq.d/oisd.txt && /etc/init.d/dnsmasq restart to the end of the command so if DNSMasq doesn't start the blocklist file is deleted and DNSMasq restarted again.

However, when doing a /etc/init.d/dnsmasq restart from the command line it always appears to start and doesn't throw an error exit code, the errors appear in the log later:

root@OpenWrt:~# /etc/init.d/dnsmasq restart
udhcpc: started, v1.35.0
udhcpc: broadcasting discover
udhcpc: no lease, failing

So wouldn't the || OR operator not work?

EDIT: This should do the trick: pgrep -x dnsmasq >/dev/null || rm /tmp/dnsmasq.d/oisd.txt && /etc/init.d/dnsmasq restart
Check for the DNSMasq process and if not there then delete the blocklist file and restart

While those are indeed 'errors', they're expected and the intended outcome. Background for this is dnsmasq first checking for another (rogue) DHCPd on your network (by trying to get an IP via DHCP by the means of udhcpc itself), this ought to fail (or there's something seriously wrong on your network), before dnsmasq itself gets started.

Correct, meaning that I get that output regardless if DNSMasq successfully started or not.

So far the pgrep -x dnsmasq >/dev/null is working to see if there is a DNSMasq process. Do you recommend a better way to check?

Testing this and when tried to download the list at the CLI I get an error:

root@OpenWrt:~# wget https://dnsmasq.oisd.nl -O /tmp/dnsmasq.d/oisd.txt
Downloading 'https://dnsmasq.oisd.nl'
Connecting to 2606:4700:130:436c:6f75:6466:6c61:7265:443
HTTP error 403

If I open the link in the browser it offers to save "oisd_dnsmasq_full.txt"

What am I doing wrong?