Adblock-fast: ad-blocking service for dnsmasq, smartdns and unbound

I was observing following problem when running adblock-fast

root@OpenWrt:/etc/init.d# /etc/init.d/adblock-fast start
[INIT] Force-reloading adblock-fast 1.2.0-r22...
[ DL ] Blocked List: CERT Polska - Dangerous Websites (domains) [✓]
[PROC] Sorting combined block-list [✓]
[PROC] Optimizing combined block-list [✓]
[PROC] Removing allowed domains from combined block-list [✓]
[PROC] Formatting combined block-list file [✓]
[PROC] Explicitly allowing domains in dnsmasq.servers [✓]
[PROC] Setting up dnsmasq.servers file [✓]
[PROC] Removing temporary files [✓]
[DNSM] Updating dnsmasq configuration [✓]
[DNSM] Testing dnsmasq.servers configuration [✓]
[DNSM] Sanity check for dnsmasq.servers TLDs [✓]
[DNSM] Sanity check for dnsmasq.servers leading dots [✓]
[DNSM] Restarting dnsmasq [✓]
[DNSM] Probing heartbeat.melmac.ca for 10 seconds [w][w][w][w][w][w][w][w][w][w][✗]
[DNSM] Resetting dnsmasq [✓]
[DNSM] Restarting dnsmasq [✓]
adblock-fast 1.2.0-r22 failed to start: Testing resolver on heartbeat.melmac.ca.
[ERROR] Heartbeat domain is not accessible after resolver restart!
[ERROR] Failed to create block-list or restart DNS resolver!
[TRIG] Setting trigger for wan [✓]

turns out the problem was that I did not have nslookup which is used in /etc/init.d/adblock-fast without checking if nslookup is present or not. I solved it on my end by building busybox with nslookup enabled.

I don't quite know what would be proper way to handle the case. But a warning either in luci or in the console output would make it easier to troubleshoot that the problem was not with DNS but rather with missing nslookup.

2 Likes

I have solely updated Adblock-fast to r1.2.1-r3 yesterday,
then Adblock-fast not working after update.

My setup use : option dns 'dnsmasq.servers'
then getting tons of errors in r1.2.1-r3

Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303122 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303123 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303124 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303125 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303126 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303127 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303128 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303129 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303130 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303131 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303132 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303133 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303134 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303135 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303136 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303137 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303138 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303139 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303140 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303141 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303142 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303143 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303144 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303145 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303146 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303147 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303148 of /var/run/adblock-fast/dnsmasq.servers
Mon Feb  2 13:04:52 2026 daemon.err dnsmasq[1]: bad option at line 303149 of /var/run/adblock-fast/dnsmasq.servers

It was working in r1.2.1-r2 and before,
and this time only updated the package,
so believe that the issue related to adblock-fast.

Now changed to : option dns 'dnsmasq.addnhosts'
adblock-fast working again.

2 Likes

README has a pretty good description of various modes and which ones you can target specific dnsmasq instances in.

Ouch, thanks for posting that, switched nslookup to resolveip and added resolveip to the list of dependencies. Dunno how I skipped when adding heartbeat testing functionality.

The 1.2.1-r5 has some additional filtering applied to external lists to prevent dnsmasq from choking on the final list.

2 Likes

I have the same with r1.2.1-r5 and it doesn't block servers.
Unfortunately switching to the option dns 'dnsmasq.addnhosts' doesn't help either.

I see adds on all Android devices connected to my WLAN.

Same issue with 1.2.1-r7 too.

1 Like

reboot them after installing r7.

Current r7 working fine for me now :hugs:

user.notice: adblock-fast [5310]: [STAT] adblock-fast 1.2.1-r7 is blocking 429947 domains (with dnsmasq.servers)

Tested back and fore change settings without reboot,
and test after restart,
all blocking and block+allow list are working.

Y, I'm through with it. My setup is a bit special. So far I stick to the imagination that it is an issue with the file rights. If I load the file from the router itself everything works. If I load the file from an USB drive mounted to /tmp/OPENWRT (which is on top shared via ksmbd and guest access enabled) it fails. I didn't try without ksmbd on this device so far nor dit I try mouting it to /mnt (maybe /tmp is not so wise).

Kind regards.

EDIT: I've tested with a 2nd usb stick mounted to /mnt. There it works. So ksmbd and/or filerights is propably the issue here (I guess). EDIT2: To early. It used the cache. stop/start is telling failed. While the file size is updated correctly within the config. ...
EDIT3: Any hint how I could better debug the issue? I'll try in a VM these days.
EDIT4: Found the issue. I missed somehow sed -i 's/\r$//' I didn't expect that this line is necessary (doing everything on linux anyway). So one or some lists of my compilation are compiled on windows. ^^ Thx anyway for trying to help the dumb ppl. :confused:

I messed up my post regarding the dnsmasq instances. So in short again:
Selecting an instance via gui I end up with:

MTKFLINT2B:/tmp/OPENWRT# /etc/init.d/adblock-fast start
[INIT] Starting adblock-fast 1.2.1-r7...
[ DL ] Allowed List: whitelist (domains) [✓]
[ DL ] Blocked List: blocklist [✗]
[ DL ] Blocked List: tracking5 (domains) [✓]
[PROC] Sorting combined block-list [✓]
[PROC] Optimizing combined block-list [✓]
[PROC] Removing allowed domains from combined block-list [✓]
[PROC] Formatting combined block-list file [✓]
[PROC] Explicitly allowing domains in dnsmasq.servers [✓]
[PROC] Setting up dnsmasq.servers file [✓]
[PROC] Removing temporary files [✓]
[DNSM] Updating dnsmasq configuration Syntax error: Expecting Label or '*'
In expression @.dnsmasq.instances.@dnsmasq[1].command
Near here ------------------------^

If look into the config I see:
adblock-fast.config.dnsmasq_instance='1'
Changing it to:
adblock-fast.config.dnsmasq_instances='1'
works.
The GUI is reverting to "Ad-blocking on all instances".

You should start with posting at least adblock-fast and dhcp configs and more information about what do you want to do/achieve.

Your comments about “loading file from USB” don’t make sense. If the USB is plugged into the router, you don’t need samba to read it.

The correct option for targeting specific dnsmasq instances is dnsmasq_instance not dnsmasq_instances.

1 Like

Sry, I was in hurry and deleted accidently some text and wrote it shorter again. So it was not clear enough.

I've solved my issue regarding loading a custom blocklist file. The file did contain \n\r (windows like LF). This was not accpeted (at least it seems so) because issuing a sed -i 's/\r$//' over the file solved the loading issue.

Regarding the instances. I wrote earlier that it has no influence what i choose.

If I add the two required lines into config via:

uci add_list adblock-fast.config.dnsmasq_instances='1'

The GUI is showing "Ad-blocking on all instances" and dnsmasq is loading the blocklist for all three instances (RAM usage is indicating it).


If I modify via GUI LuCI is showing and writing:

Which is wrong and leads to the error I wrote. But as I wrote the correct syntax does not have any effect it seems (to me).

I hope its clearer now.

Works now.

Can you post the output of:

ubus call service list '{"name":"dnsmasq"}'

It’s erroring on trying to find a @dnsmasq[1] entry in that output.

There is no code in Adblock-fast that understands “dnsmasq_instances”. Might as well delete it with the same effect.

1 Like
{
"dnsmasq": {
"instances": {
"lan": {
"running": true,
"pid": 10557,
"command": [
"/usr/sbin/dnsmasq",
"-C",
"/var/etc/dnsmasq.conf.lan",
"-k",
"-x",
"/var/run/dnsmasq/dnsmasq.lan.pid"
],
"term_timeout": 5,
"netdev": [
"br-lan0608"
],
"respawn": {
"threshold": 3600,
"timeout": 5,
"retry": 5
},
"jail": {
"name": "dnsmasq",
"procfs": false,
"sysfs": false,
"ubus": true,
"log": true,
"ronly": false,
"netns": false,
"userns": false,
"cgroupsns": false,
"console": false
},
"mount": {
"/bin/ubus": "0",
"/etc/TZ": "0",
"/etc/dnsmasq.conf": "0",
"/etc/dnsmasq.hosts": "0",
"/etc/ethers": "0",
"/etc/group": "0",
"/etc/hosts": "0",
"/etc/passwd": "0",
"/tmp/dhcp.leases": "1",
"/tmp/dnsmasq.lan.d": "0",
"/tmp/hosts/dhcp.lan": "0",
"/usr/bin/env": "0",
"/usr/bin/jshn": "0",
"/usr/lib/dnsmasq/dhcp-script.sh": "0",
"/usr/share/dnsmasq/dhcpbogushostname.conf": "0",
"/usr/share/dnsmasq/rfc6761.conf": "0",
"/usr/share/dnsmasq/trust-anchors.conf": "0",
"/usr/share/libubox/jshn.sh": "0",
"/var/etc/dnsmasq.conf.lan": "0",
"/var/run/adblock-fast/dnsmasq.servers": "0",
"/var/run/dnsmasq/": "1"
}
},
"lang": {
"running": true,
"pid": 10558,
"command": [
"/usr/sbin/dnsmasq",
"-C",
"/var/etc/dnsmasq.conf.lang",
"-k",
"-x",
"/var/run/dnsmasq/dnsmasq.lang.pid"
],
"term_timeout": 5,
"netdev": [
"br-lan0608g"
],
"respawn": {
"threshold": 3600,
"timeout": 5,
"retry": 5
},
"jail": {
"name": "dnsmasq",
"procfs": false,
"sysfs": false,
"ubus": true,
"log": true,
"ronly": false,
"netns": false,
"userns": false,
"cgroupsns": false,
"console": false
},
"mount": {
"/bin/ubus": "0",
"/etc/TZ": "0",
"/etc/dnsmasq.conf": "0",
"/etc/dnsmasq.hosts": "0",
"/etc/ethers": "0",
"/etc/group": "0",
"/etc/hosts": "0",
"/etc/passwd": "0",
"/tmp/dhcp.leases": "1",
"/tmp/dnsmasq.lang.d": "0",
"/tmp/hosts/dhcp.lang": "0",
"/usr/bin/env": "0",
"/usr/bin/jshn": "0",
"/usr/lib/dnsmasq/dhcp-script.sh": "0",
"/usr/share/dnsmasq/dhcpbogushostname.conf": "0",
"/usr/share/dnsmasq/rfc6761.conf": "0",
"/usr/share/dnsmasq/trust-anchors.conf": "0",
"/usr/share/libubox/jshn.sh": "0",
"/var/etc/dnsmasq.conf.lang": "0",
"/var/run/adblock-fast/dnsmasq.servers": "0",
"/var/run/dnsmasq/": "1"
}
},
"lani": {
"running": true,
"pid": 10559,
"command": [
"/usr/sbin/dnsmasq",
"-C",
"/var/etc/dnsmasq.conf.lani",
"-k",
"-x",
"/var/run/dnsmasq/dnsmasq.lani.pid"
],
"term_timeout": 5,
"netdev": [
"br-lan0608i"
],
"respawn": {
"threshold": 3600,
"timeout": 5,
"retry": 5
},
"jail": {
"name": "dnsmasq",
"procfs": false,
"sysfs": false,
"ubus": true,
"log": true,
"ronly": false,
"netns": false,
"userns": false,
"cgroupsns": false,
"console": false
},
"mount": {
"/bin/ubus": "0",
"/etc/TZ": "0",
"/etc/dnsmasq.conf": "0",
"/etc/dnsmasq.hosts": "0",
"/etc/ethers": "0",
"/etc/group": "0",
"/etc/hosts": "0",
"/etc/passwd": "0",
"/tmp/dhcp.leases": "1",
"/tmp/dnsmasq.lani.d": "0",
"/tmp/hosts/dhcp.lani": "0",
"/usr/bin/env": "0",
"/usr/bin/jshn": "0",
"/usr/lib/dnsmasq/dhcp-script.sh": "0",
"/usr/share/dnsmasq/dhcpbogushostname.conf": "0",
"/usr/share/dnsmasq/rfc6761.conf": "0",
"/usr/share/dnsmasq/trust-anchors.conf": "0",
"/usr/share/libubox/jshn.sh": "0",
"/var/etc/dnsmasq.conf.lani": "0",
"/var/run/adblock-fast/dnsmasq.servers": "0",
"/var/run/dnsmasq/": "1"
}
}
}
}
}

Well, the option is there within the GUI so I thought it would be available working.

P.S. The reason why I do this:

I've migrated a while ago a VPN setup directly to the router. They are powerfull nowdays and dnsmasq got the possibility running multiple setups (was a bit ugly at the beginning).

If I use wireguard I want to pipe DNS through VPN DNS (e. g. 10.0.2.1). But with this I cut out my pihole server. That is the reason why I use an ad-blocker on the router directly. In this way I can run a seperate unit pointing to 10.0.2.1 and getting things pre-filtered/blocked.

The option to choose the instance is very usefull in this regard because the RAM footprint is quite huge with multiple instances running.

EDIT: What the GUI is showing:

Apologies, my point was that it is a singular name, not plural (correct: dnsmasq_instance; incorrect: dnsmasq_instances).

I don’t quite understand how this is supposed to work with named dnsmasq instances based on your ubus output. Your 1 instance would never match the output shown.

1 Like

Yes this is quite confusing. Correctly it should be with "s". But LuCI is cutting the "s" off as my screenshot shows. So the startup fails. If I fix the error (adding the "s") adblock is starting correctly but enabled for all instances.

Where do you see this s? It doesn’t exist in the config or config script.

1 Like

Oh you are correct. I still think the other way around. Sry.

But back to the instances. Do you think its a naming issue? I did this in the past during the transition to multiple instances. It helped to get it running in the past. Maybe I have to drop it. I'll try tomorrow if the instances get recognized correctly then.

@stangri What seems to happen here is the init script errors on the ubus / jsonfilter call and the next awk command is sitting waiting for stdin since cfg_file is empty.

root@router:~# service adblock-fast restart
[STOP] Stopping adblock-fast 1.2.1-r7... [✓]
[WARN] Some recommended packages are missing, install them by running:!
opkg update; opkg --force-overwrite install grep sed;[INIT] Starting adblock-fast 1.2.1-r7...
[INIT] Found cache file, reusing it [✓]
[DNSM] Updating dnsmasq configuration Syntax error: Expecting Label or '*'
In expression @.dnsmasq.instances.@dnsmasq[1].command
Near here ------------------------^

In another window:
26754 root      2236 S    {adblock-fast} /bin/sh /etc/rc.common /etc/init.d/adblock-fast restart
26761 root      2412 S    awk -F= /^conf-dir=/{print $2; exit}

config adblock-fast 'config'
        option enabled '1'
        list allowed_domain 'cdn.jsdelivr.net'
        option allow_non_ascii '0'
        option canary_domains_icloud '0'
        option canary_domains_mozilla '0'
        option compressed_cache '0'
        option compressed_cache_dir '/etc'
        option config_update_enabled '0'
        option config_update_url 'https://cdn.jsdelivr.net/gh/openwrt/packages/net/adblock-fast/files/adblock-fast.config.update'
        option curl_max_file_size '30000000'
        option curl_retry '3'
        option debug_init_script '0'
        option debug_performance '0'
        option dns 'dnsmasq.servers'
        option download_timeout '10'
        option force_dns '1'
        list force_dns_port '53'
        list force_dns_port '853'
        option parallel_downloads '1'
        option pause_timeout '20'
        option procd_trigger_wan6 '0'
        option procd_boot_wan_timeout '60'
        option verbosity '2'
        option heartbeat_domain 'heartbeat.melmac.ca'
        option heartbeat_sleep_timeout '10'
        option update_config_sizes '1'
        option dnsmasq_sanity_check '1'
        option auto_update_enabled '0'
        option dnsmasq_validity_check '0'
        option debug '0'
        list dnsmasq_instance '1'


config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/home.arpa/'
        option domain 'home.arpa'
        option expandhosts '1'
        option cachesize '1000'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option localservice '1'
        option ednspacket_max '1232'
        list server '/168.192.in-addr.arpa/'
        list rebind_domain 'dns.msftncsi.com'
        option serversfile '/var/run/adblock-fast/dnsmasq.servers'

config dnsmasq 'test'
        option rebind_protection '0'
        option localservice '0'
        option port '5053'
        option serversfile '/var/run/adblock-fast/dnsmasq.servers'

I've removed the labels for the dnsmasq instances but it does not change the outcome. I didn't reboot the device because I cannot atm. But I restarted dnsmasq first and after I restarted adblock-fast.

I can see now within /tmp the old entries and the new ones:

drwxr-xr-x  2 root   root       40 Feb  8 08:20 dnsmasq.cfg03411c.d
drwxr-xr-x  2 root   root       40 Feb  8 08:20 dnsmasq.cfg05411c.d
drwxr-xr-x  2 root   root       40 Feb  8 08:20 dnsmasq.cfg07411c.d
drwxr-xr-x  2 root   root       40 Feb  5 00:20 dnsmasq.lan.d
drwxr-xr-x  2 root   root       40 Feb  5 00:20 dnsmasq.lang.d
drwxr-xr-x  2 root   root       40 Feb  5 00:20 dnsmasq.lani.d

I'll reboot the device in ~ 4 hrs and report back if this would change anything.
EDIT: reboot does not change the outcome.