Title: DNS Firewall RPZ zones return REFUSED for all clients when AXFR from primary.dbl.ipfire.org is denied (e.g. CG-NAT) Component: DNS Firewall / Unbound Version: IPFire 2.29 Core Update 201

Summary:

The IPFire DNS Firewall configures Unbound RPZ zones with primary: primary.dbl.ipfire.org in dnsbl.conf. When Unbound cannot complete a zone transfer (AXFR) from this primary — for example because the installation is behind CG-NAT and the source IP is not authorized — Unbound returns REFUSED for all queries matching domains in those zones, instead of falling back to the locally cached zone file.

Steps to reproduce:

  1. Run IPFire behind CG-NAT (no dedicated public IP)

  2. Enable any DNS Firewall category (e.g. Advertising)

  3. Query a domain that should be blocked: dig @192.168.178.1 pagead2.googlesyndication.com

  4. Result: REFUSED instead of NXDOMAIN

Expected behavior:

Unbound should serve the locally cached zone file (/var/cache/unbound/*.zone) when AXFR from the primary fails. The zone files are downloaded and kept up to date by IPFire’s own update mechanism independently of AXFR.

Actual behavior:

AXFR from primary.dbl.ipfire.org returns only the SOA record (transfer denied). Unbound then treats the zone as non-authoritative and returns REFUSED for all matching queries. The local zone file is ignored.

Evidence:

$ dig @81.3.27.55 ads.rpz.ipfire.org AXFR | head -5
ads.rpz.ipfire.org. 60 IN SOA primary.dbl.ipfire.org. ...
# (only SOA returned = AXFR denied)

$ dig @192.168.178.1 pagead2.googlesyndication.com
;; status: REFUSED

/var/log/messages:
unbound: error: SERVFAIL <primary.dbl.ipfire.org. A IN>: misc failure

Workaround:

Comment out primary: primary.dbl.ipfire.org in /etc/unbound/dnsbl.conf — Unbound then loads only the local zone file and all zones work correctly.

Fix suggestion:

Either remove the primary: directive from dnsbl.conf entirely (zone files are already managed by IPFire’s update scripts), or add fallback-enabled: yes if supported by the Unbound version, so AXFR failure gracefully falls back to the local zone file.

Hello Daniel,

let’s have a look why you cannot fetch the zone. We don’t have any restrictions on the primary server whatsoever. There are not ACLs, and there is no rate-limiting.

Could you please check your logs and report back?

It seems to be working correctly for me, below is an example.
Core-Update 201 Development Build: master/da6ccd7a

Query without Advertising checkbox selected:

#dig pagead2.googlesyndication.com

; <<>> DiG 9.10.6 <<>> pagead2.googlesyndication.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43102
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;pagead2.googlesyndication.com. IN A

;; ANSWER SECTION:
pagead2.googlesyndication.com. 300 IN A 142.251.38.130

;; Query time: 79 msec
;; SERVER: 192.168.101.1#53(192.168.101.1)
;; WHEN: Mon Mar 23 15:10:02 CET 2026
;; MSG SIZE rcvd: 74

Query with Advertising checkbox selected:

#dig pagead2.googlesyndication.com

; <<>> DiG 9.10.6 <<>> pagead2.googlesyndication.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 52683
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;pagead2.googlesyndication.com. IN A

;; Query time: 5 msec
;; SERVER: 192.168.101.1#53(192.168.101.1)
;; WHEN: Mon Mar 23 15:11:52 CET 2026
;; MSG SIZE rcvd: 58

However, I noticed that enabling all lists in the DNS firewall significantly increased the RAM usage. On a machine with 8GB of RAM, 61% of the RAM was used.

Perhaps related, I too am getting REFUSED repsonse when attempting to fetch RPZ files.
First, I can successfully fetch the files from my operational system using commands like:

dig axfr @xfr.dbl.ipfire.org ads.rpz.ipfire.org

However, when I do the same sort of command on my test system, I get the REFUSED response. Note, my test system sits downstream from operational system on my home network. My operational system redirects traffic for port 53 to local and uses TLS/853 for DNS lookups.
[Edit] The actual response on the console looks like this:

; <<>> DiG 9.20.20 <<>> axfr @xfr.dbl.ipfire.org ads.rpz.ipfire.org
; (1 server found)
;; global options: +cmd
; Transfer failed.

I am running next/a85c4ef9 on the test system.
Here is the tcpdump output I captured while attempting to do the fetch:

1.704986 192.168.3.167 → 81.3.27.55   TCP 74 48343 → 53 [SYN] Seq=0 Win=42700 Len=0 MSS=1220 SACK_PERM TSval=515755765 TSecr=0 WS=512
1.706275   81.3.27.55 → 192.168.3.167 TCP 74 53 → 48343 [SYN, ACK] Seq=0 Ack=1 Win=43440 Len=0 MSS=1460 SACK_PERM TSval=3906283429 TSecr=515755765 WS=512
1.706396 192.168.3.167 → 81.3.27.55   TCP 66 48343 → 53 [ACK] Seq=1 Ack=1 Win=43008 Len=0 TSval=515755767 TSecr=3906283429
1.706601 192.168.3.167 → 81.3.27.55   DNS 127 Standard query 0xce29 AXFR ads.rpz.ipfire.org OPT
1.707444   81.3.27.55 → 192.168.3.167 TCP 66 53 → 48343 [ACK] Seq=1 Ack=62 Win=43520 Len=0 TSval=3906283431 TSecr=515755767
1.707503   81.3.27.55 → 192.168.3.167 DNS 127 Standard query response 0xce29 Refused AXFR ads.rpz.ipfire.org OPT
1.707541 192.168.3.167 → 81.3.27.55   TCP 66 48343 → 53 [ACK] Seq=62 Ack=62 Win=43008 Len=0 TSval=515755768 TSecr=3906283431
1.729737 192.168.3.167 → 81.3.27.55   TCP 66 48343 → 53 [FIN, ACK] Seq=62 Ack=62 Win=43008 Len=0 TSval=515755790 TSecr=3906283431
1.733393   81.3.27.55 → 192.168.3.167 TCP 66 53 → 48343 [FIN, ACK] Seq=62 Ack=63 Win=43520 Len=0 TSval=3906283457 TSecr=515755790
1.733500 192.168.3.167 → 81.3.27.55   TCP 66 48343 → 53 [ACK] Seq=63 Ack=63 Win=43008 Len=0 TSval=515755794 TSecr=3906283457
2.905564 192.168.3.167 → 81.3.27.55   TCP 74 48344 → 53 [SYN] Seq=0 Win=42700 Len=0 MSS=1220 SACK_PERM TSval=515756966 TSecr=0 WS=512
2.906729   81.3.27.55 → 192.168.3.167 TCP 74 53 → 48344 [SYN, ACK] Seq=0 Ack=1 Win=43440 Len=0 MSS=1460 SACK_PERM TSval=3906284630 TSecr=515756966 WS=512
2.906807 192.168.3.167 → 81.3.27.55   TCP 66 48344 → 53 [ACK] Seq=1 Ack=1 Win=43008 Len=0 TSval=515756967 TSecr=3906284630
2.907111 192.168.3.167 → 81.3.27.55   DNS 127 Standard query 0x2e6e AXFR ads.rpz.ipfire.org OPT
2.908068   81.3.27.55 → 192.168.3.167 TCP 66 53 → 48344 [ACK] Seq=1 Ack=62 Win=43520 Len=0 TSval=3906284631 TSecr=515756967
2.908125   81.3.27.55 → 192.168.3.167 DNS 127 Standard query response 0x2e6e Refused AXFR ads.rpz.ipfire.org OPT
2.908168 192.168.3.167 → 81.3.27.55   TCP 66 48344 → 53 [ACK] Seq=62 Ack=62 Win=43008 Len=0 TSval=515756968 TSecr=3906284632
2.922863 192.168.3.167 → 81.3.27.55   TCP 66 48344 → 53 [FIN, ACK] Seq=62 Ack=62 Win=43008 Len=0 TSval=515756983 TSecr=3906284632
2.924210   81.3.27.55 → 192.168.3.167 TCP 66 53 → 48344 [FIN, ACK] Seq=62 Ack=63 Win=43520 Len=0 TSval=3906284648 TSecr=515756983
2.924311 192.168.3.167 → 81.3.27.55   TCP 66 48344 → 53 [ACK] Seq=63 Ack=63 Win=43008 Len=0 TSval=515756985 TSecr=3906284648
3.970953 192.168.3.167 → 81.3.27.55   TCP 74 48348 → 53 [SYN] Seq=0 Win=42700 Len=0 MSS=1220 SACK_PERM TSval=515758031 TSecr=0 WS=512
3.972081   81.3.27.55 → 192.168.3.167 TCP 74 53 → 48348 [SYN, ACK] Seq=0 Ack=1 Win=43440 Len=0 MSS=1460 SACK_PERM TSval=3906285695 TSecr=515758031 WS=512
3.972185 192.168.3.167 → 81.3.27.55   TCP 66 48348 → 53 [ACK] Seq=1 Ack=1 Win=43008 Len=0 TSval=515758032 TSecr=3906285695
3.972460 192.168.3.167 → 81.3.27.55   DNS 127 Standard query 0x5996 AXFR ads.rpz.ipfire.org OPT
3.973533   81.3.27.55 → 192.168.3.167 TCP 66 53 → 48348 [ACK] Seq=1 Ack=62 Win=43520 Len=0 TSval=3906285697 TSecr=515758033
3.973602   81.3.27.55 → 192.168.3.167 DNS 127 Standard query response 0x5996 Refused AXFR ads.rpz.ipfire.org OPT
3.973647 192.168.3.167 → 81.3.27.55   TCP 66 48348 → 53 [ACK] Seq=62 Ack=62 Win=43008 Len=0 TSval=515758034 TSecr=3906285697
3.996338 192.168.3.167 → 81.3.27.55   TCP 66 48348 → 53 [FIN, ACK] Seq=62 Ack=62 Win=43008 Len=0 TSval=515758057 TSecr=3906285697
3.997316   81.3.27.55 → 192.168.3.167 TCP 66 53 → 48348 [FIN, ACK] Seq=62 Ack=63 Win=43520 Len=0 TSval=3906285721 TSecr=515758057
3.997415 192.168.3.167 → 81.3.27.55   TCP 66 48348 → 53 [ACK] Seq=63 Ack=63 Win=43008 Len=0 TSval=515758058 TSecr=3906285721

[Edit2] My operational system sits downstream from an external router. So, consequently my traffic gets double NATed. The traffic at the further downstream test system is getting triple NATed

If you have a system redirecting traffic to a different server, this would explain it. The zone transfer cannot be proxied through another DNS server. You need to have direct access to the IPFire DBL service to pull the zone from.

Excellent. Disabling the DNS redirect rule did the trick :slightly_smiling_face: