[GH-ISSUE #2850] How do you configure blocklists on forwarder zones via Toml Config? #1074

Closed
opened 2026-03-16 01:32:45 +03:00 by kerem · 7 comments
Owner

Originally created by @rskntroot on GitHub (Mar 14, 2025).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2850

I am trying to get a blocklist running before forwarding requests upstream. I supposed Im going about it all wrong and need help. Appreciate any support.

Have been trying to follow any examples I could find in test_configs.

https://github.com/hickory-dns/hickory-dns/blob/main/tests/test-data/test_configs/chained_blocklist.toml#L28-L45

not only is zone_type = "External" not valid but im also seeing zones.stores.type = blocklist not valid too (at least as a part of forwarder).

dns-1  | Hickory DNS named server 0.24.4
dns-1  | 1741942114:INFO:hickory_dns:336:Hickory DNS 0.24.4 starting
dns-1  | 1741942114:INFO:hickory_dns:341:loading configuration from: "/etc/hickory/config.toml"
dns-1  | thread 'main' panicked at /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hickory-dns-0.24.4/src/hickory-dns.rs:343:29:
dns-1  | could not read config /etc/hickory/config.toml: Error { kind: TomlDecode(Error { kind: Custom, line: Some(25), col: 7, at: Some(437), message: "unknown variant `blocklist`, expected one of `file`, `sqlite`, `forward`", key: ["zones", "stores", "type"] }) }
dns-1  | note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
dns-1 exited with code 101
[[zones]]
zone = "."
zone_type = "Forward"

[zones.stores]
type = "blocklist"
wildcard_match = true
min_wildcard_depth = 2
sinkhole_ipv4 = "192.0.2.1"
sinkhole_ipv6 = "::ffff:c0:0:2:1"
block_message = "This query has been blocked by the DNS server"
lists = [ "/etc/hickory/lists/disconnectme", "/etc/hickory/lists/stevenblack" ]

[zones.stores]
type = "forward"

[[zones.stores.name_servers]]
socket_addr = "1.1.1.1:53"
protocol = "udp"
trust_negative_responses = false

[[zones.stores.name_servers]]
socket_addr = "1.1.1.1:53"
protocol = "tcp"
trust_negative_responses = false

I can load that config when zones.stores.type=file but obviously we are going to run into issues where zones.stores cannot be a map...

dns-1  | thread 'main' panicked at /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hickory-dns-0.24.4/src/hickory-dns.rs:343:29:
dns-1  | could not read config /etc/hickory/config.toml: Error { kind: TomlDecode(Error { kind: Custom, line: Some(51), col: 0, at: Some(1057), message: "invalid type: map, expected variant identifier", key: ["zones", "stores"] }) }
[[zones.stores]]
type = "file"
wildcard_match = true
min_wildcard_depth = 2
sinkhole_ipv4 = "192.0.2.1"
sinkhole_ipv6 = "::ffff:c0:0:2:1"
block_message = "This query has been blocked by the DNS server"
lists = [ "/etc/hickory/lists/disconnectme", "/etc/hickory/lists/stevenblack" ]

[[zones.stores]]
type = "forward"

Finally I tried to merge the zone.stores as using type forwarder and the server runs -- but I dont get any blocklist features.

[zones.stores]
type = "forward"
wildcard_match = true
min_wildcard_depth = 2
sinkhole_ipv4 = "192.0.2.1"
sinkhole_ipv6 = "::ffff:c0:0:2:1"
block_message = "This query has been blocked by the DNS server"
lists = [ "/etc/hickory/lists/disconnectme", "/etc/hickory/lists/stevenblack" ]

[[zones.stores.name_servers]]
socket_addr = "1.1.1.1:53"
protocol = "udp"
trust_negative_responses = false

[[zones.stores.name_servers]]
socket_addr = "1.1.1.1:53"
protocol = "tcp"
trust_negative_responses = false
dns-1  | 1741944010:DEBUG:hickory_dns:147:loading zone with config: ZoneConfig {
dns-1  |     zone: ".",
dns-1  |     zone_type: Forward,
dns-1  |     file: None,
dns-1  |     allow_update: None,
dns-1  |     allow_axfr: None,
dns-1  |     enable_dnssec: None,
dns-1  |     keys: [],
dns-1  |     stores: Some(
dns-1  |         Forward(
dns-1  |             ForwardConfig {
dns-1  |                 name_servers: NameServerConfigGroup(
dns-1  |                     [
dns-1  |                         NameServerConfig {
dns-1  |                             socket_addr: 1.1.1.1:53,
dns-1  |                             protocol: Udp,
dns-1  |                             tls_dns_name: None,
dns-1  |                             trust_negative_responses: false,
dns-1  |                             bind_addr: None,
dns-1  |                         },
dns-1  |                         NameServerConfig {
dns-1  |                             socket_addr: 1.1.1.1:53,
dns-1  |                             protocol: Tcp,
dns-1  |                             tls_dns_name: None,
dns-1  |                             trust_negative_responses: false,
dns-1  |                             bind_addr: None,
dns-1  |                         },
dns-1  |                     ],
dns-1  |                 ),
dns-1  |                 options: None,
dns-1  |             },
dns-1  |         ),
dns-1  |     ),
dns-1  | }

and as expected, blocklisted names are not denied.

$ dig adjust.io @192.168.1.151

; <<>> DiG 9.18.33 <<>> adjust.io @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22484
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;adjust.io.			IN	A

;; ANSWER SECTION:
adjust.io.		3600	IN	A	185.151.204.5

;; Query time: 17 msec
;; SERVER: 192.168.1.151#53(192.168.1.151) (UDP)
;; WHEN: Fri Mar 14 03:21:11 MDT 2025
;; MSG SIZE  rcvd: 54
Originally created by @rskntroot on GitHub (Mar 14, 2025). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2850 I am trying to get a blocklist running before forwarding requests upstream. I supposed Im going about it all wrong and need help. Appreciate any support. Have been trying to follow any examples I could find in test_configs. > https://github.com/hickory-dns/hickory-dns/blob/main/tests/test-data/test_configs/chained_blocklist.toml#L28-L45 not only is `zone_type = "External"` not valid but im also seeing zones.stores.type = `blocklist` not valid too (at least as a part of forwarder). ``` dns-1 | Hickory DNS named server 0.24.4 dns-1 | 1741942114:INFO:hickory_dns:336:Hickory DNS 0.24.4 starting dns-1 | 1741942114:INFO:hickory_dns:341:loading configuration from: "/etc/hickory/config.toml" dns-1 | thread 'main' panicked at /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hickory-dns-0.24.4/src/hickory-dns.rs:343:29: dns-1 | could not read config /etc/hickory/config.toml: Error { kind: TomlDecode(Error { kind: Custom, line: Some(25), col: 7, at: Some(437), message: "unknown variant `blocklist`, expected one of `file`, `sqlite`, `forward`", key: ["zones", "stores", "type"] }) } dns-1 | note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace dns-1 exited with code 101 ``` ``` toml [[zones]] zone = "." zone_type = "Forward" [zones.stores] type = "blocklist" wildcard_match = true min_wildcard_depth = 2 sinkhole_ipv4 = "192.0.2.1" sinkhole_ipv6 = "::ffff:c0:0:2:1" block_message = "This query has been blocked by the DNS server" lists = [ "/etc/hickory/lists/disconnectme", "/etc/hickory/lists/stevenblack" ] [zones.stores] type = "forward" [[zones.stores.name_servers]] socket_addr = "1.1.1.1:53" protocol = "udp" trust_negative_responses = false [[zones.stores.name_servers]] socket_addr = "1.1.1.1:53" protocol = "tcp" trust_negative_responses = false ``` I can load that config when `zones.stores.type=file` but obviously we are going to run into issues where `zones.stores` cannot be a map... ``` dns-1 | thread 'main' panicked at /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hickory-dns-0.24.4/src/hickory-dns.rs:343:29: dns-1 | could not read config /etc/hickory/config.toml: Error { kind: TomlDecode(Error { kind: Custom, line: Some(51), col: 0, at: Some(1057), message: "invalid type: map, expected variant identifier", key: ["zones", "stores"] }) } ``` ``` toml [[zones.stores]] type = "file" wildcard_match = true min_wildcard_depth = 2 sinkhole_ipv4 = "192.0.2.1" sinkhole_ipv6 = "::ffff:c0:0:2:1" block_message = "This query has been blocked by the DNS server" lists = [ "/etc/hickory/lists/disconnectme", "/etc/hickory/lists/stevenblack" ] [[zones.stores]] type = "forward" ``` Finally I tried to merge the zone.stores as using type forwarder and the server runs -- but I dont get any blocklist features. ```toml [zones.stores] type = "forward" wildcard_match = true min_wildcard_depth = 2 sinkhole_ipv4 = "192.0.2.1" sinkhole_ipv6 = "::ffff:c0:0:2:1" block_message = "This query has been blocked by the DNS server" lists = [ "/etc/hickory/lists/disconnectme", "/etc/hickory/lists/stevenblack" ] [[zones.stores.name_servers]] socket_addr = "1.1.1.1:53" protocol = "udp" trust_negative_responses = false [[zones.stores.name_servers]] socket_addr = "1.1.1.1:53" protocol = "tcp" trust_negative_responses = false ``` ``` dns-1 | 1741944010:DEBUG:hickory_dns:147:loading zone with config: ZoneConfig { dns-1 | zone: ".", dns-1 | zone_type: Forward, dns-1 | file: None, dns-1 | allow_update: None, dns-1 | allow_axfr: None, dns-1 | enable_dnssec: None, dns-1 | keys: [], dns-1 | stores: Some( dns-1 | Forward( dns-1 | ForwardConfig { dns-1 | name_servers: NameServerConfigGroup( dns-1 | [ dns-1 | NameServerConfig { dns-1 | socket_addr: 1.1.1.1:53, dns-1 | protocol: Udp, dns-1 | tls_dns_name: None, dns-1 | trust_negative_responses: false, dns-1 | bind_addr: None, dns-1 | }, dns-1 | NameServerConfig { dns-1 | socket_addr: 1.1.1.1:53, dns-1 | protocol: Tcp, dns-1 | tls_dns_name: None, dns-1 | trust_negative_responses: false, dns-1 | bind_addr: None, dns-1 | }, dns-1 | ], dns-1 | ), dns-1 | options: None, dns-1 | }, dns-1 | ), dns-1 | ), dns-1 | } ``` and as expected, blocklisted names are not denied. ``` bash $ dig adjust.io @192.168.1.151 ; <<>> DiG 9.18.33 <<>> adjust.io @localhost ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22484 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 1232 ;; QUESTION SECTION: ;adjust.io. IN A ;; ANSWER SECTION: adjust.io. 3600 IN A 185.151.204.5 ;; Query time: 17 msec ;; SERVER: 192.168.1.151#53(192.168.1.151) (UDP) ;; WHEN: Fri Mar 14 03:21:11 MDT 2025 ;; MSG SIZE rcvd: 54 ```
kerem closed this issue 2026-03-16 01:32:50 +03:00
Author
Owner

@djc commented on GitHub (Mar 14, 2025):

Which version are you using?

<!-- gh-comment-id:2724218079 --> @djc commented on GitHub (Mar 14, 2025): Which version are you using?
Author
Owner

@rskntroot commented on GitHub (Mar 14, 2025):

Which version are you using?

dns-1  | Hickory DNS named server 0.24.4

from cargo install hickory-dns

<!-- gh-comment-id:2724241763 --> @rskntroot commented on GitHub (Mar 14, 2025): > Which version are you using? ``` dns-1 | Hickory DNS named server 0.24.4 ``` from `cargo install hickory-dns`
Author
Owner

@djc commented on GitHub (Mar 14, 2025):

Ah, sorry, missed that. The test configs you're looking at are from the main branch though, right? There's substantial delta between those. You'll want to try the latest 0.25.0-alpha.5, or even better, compile from main.

(We're on the cusp of releasing 0.25.0, see #2206.)

<!-- gh-comment-id:2724246047 --> @djc commented on GitHub (Mar 14, 2025): Ah, sorry, missed that. The test configs you're looking at are from the main branch though, right? There's substantial delta between those. You'll want to try the latest 0.25.0-alpha.5, or even better, compile from main. (We're on the cusp of releasing 0.25.0, see #2206.)
Author
Owner

@rskntroot commented on GitHub (Mar 14, 2025):

I'll give it a shot when I get some time, thank you.

<!-- gh-comment-id:2724252766 --> @rskntroot commented on GitHub (Mar 14, 2025): I'll give it a shot when I get some time, thank you.
Author
Owner

@rskntroot commented on GitHub (Mar 15, 2025):

im now running a build of main branch with default features and have tested a couple different configurations

/etc/hickory # hickory-dns -V
Hickory DNS named server 0.25.0

tl;dr from what I can tell the expected use case isn't currently support as External zones' dont support blocklist stores. see below for expected implementation patterns.


my goal is to run a blocklist in front of a forwarder

-- the examples show blocklists in-front of a recursor, but it looks like those haven't been merged in yet, so no worries.

https://github.com/hickory-dns/hickory-dns/blob/main/tests/test-data/test_configs/chained_blocklist.toml

Error: failed to read config file from "/etc/hickory/recursor.toml": toml decode error: TOML parse error at line 28, column 1
   |
28 | [[zones]]
   | ^^^^^^^^^
unknown variant `recursor`, expected `forward` or `default`

multiple zones.stores where zones.type="External"

[[zones]]
zone = "."
zone_type = "External"

[[zones.stores]]
type = "blocklist"
wildcard_match = true
min_wildcard_depth = 2
sinkhole_ipv4 = "192.0.2.1"
sinkhole_ipv6 = "::ffff:c0:0:2:1"
block_message = "This query has been blocked by the DNS server"
lists = [ "/etc/hickory/lists/disconnectme", "/etc/hickory/lists/stevenblack" ]

[[zones.stores]]
type = "forward"

[[zones.stores.name_servers]]
socket_addr = "1.1.1.1:53"
protocol = "udp"
trust_negative_responses = false

[[zones.stores.name_servers]]
socket_addr = "1.1.1.1:53"
protocol = "tcp"
trust_negative_responses = false

this throws:

# hickory-dns --debug --config /etc/hickory/testing.toml
1742021579:INFO:hickory_dns:178:Hickory DNS 0.25.0 starting...
1742021579:INFO:hickory_dns:185:loading configuration from: "/etc/hickory/testing.toml"
Error: failed to read config file from "/etc/hickory/testing.toml": toml decode error: TOML parse error at line 38, column 1
   |
38 | [[zones]]
   | ^^^^^^^^^
unknown variant `blocklist`, expected `forward` or `default`

blocklists in forward zones.stores where zones.type="External"

[[zones]]
zone = "."
zone_type = "External"

[zones.stores]
type = "forward"
wildcard_match = true
min_wildcard_depth = 2
sinkhole_ipv4 = "192.0.2.1"
sinkhole_ipv6 = "::ffff:c0:0:2:1"
block_message = "This query has been blocked by the DNS server"
lists = [ "/etc/hickory/lists/disconnectme", "/etc/hickory/lists/stevenblack" ]

[[zones.stores.name_servers]]
socket_addr = "1.1.1.1:53"
protocol = "udp"
trust_negative_responses = false

[[zones.stores.name_servers]]
socket_addr = "1.1.1.1:53"
protocol = "tcp"
trust_negative_responses = false
# hickory-dns --debug --config /etc/hickory/testing_merged.toml
1742021730:INFO:hickory_dns:178:Hickory DNS 0.25.0 starting...
1742021730:INFO:hickory_dns:185:loading configuration from: "/etc/hickory/testing_merged.toml"
Error: failed to read config file from "/etc/hickory/testing_merged.toml": toml decode error: TOML parse error at line 38, column 1
   |
38 | [[zones]]
   | ^^^^^^^^^
unknown field `wildcard_match`, expected `name_servers` or `options`
<!-- gh-comment-id:2726297271 --> @rskntroot commented on GitHub (Mar 15, 2025): im now running a build of main branch with default features and have tested a couple different configurations ``` /etc/hickory # hickory-dns -V Hickory DNS named server 0.25.0 ``` tl;dr from what I can tell the expected use case isn't currently support as `External` zones' dont support `blocklist` stores. see below for expected implementation patterns. --- my goal is to run a blocklist in front of a forwarder -- the examples show blocklists in-front of a recursor, but it looks like those haven't been merged in yet, so no worries. > https://github.com/hickory-dns/hickory-dns/blob/main/tests/test-data/test_configs/chained_blocklist.toml ``` Error: failed to read config file from "/etc/hickory/recursor.toml": toml decode error: TOML parse error at line 28, column 1 | 28 | [[zones]] | ^^^^^^^^^ unknown variant `recursor`, expected `forward` or `default` ``` --- **multiple `zones.stores` where `zones.type="External"`** ``` toml [[zones]] zone = "." zone_type = "External" [[zones.stores]] type = "blocklist" wildcard_match = true min_wildcard_depth = 2 sinkhole_ipv4 = "192.0.2.1" sinkhole_ipv6 = "::ffff:c0:0:2:1" block_message = "This query has been blocked by the DNS server" lists = [ "/etc/hickory/lists/disconnectme", "/etc/hickory/lists/stevenblack" ] [[zones.stores]] type = "forward" [[zones.stores.name_servers]] socket_addr = "1.1.1.1:53" protocol = "udp" trust_negative_responses = false [[zones.stores.name_servers]] socket_addr = "1.1.1.1:53" protocol = "tcp" trust_negative_responses = false ``` this throws: ``` # hickory-dns --debug --config /etc/hickory/testing.toml 1742021579:INFO:hickory_dns:178:Hickory DNS 0.25.0 starting... 1742021579:INFO:hickory_dns:185:loading configuration from: "/etc/hickory/testing.toml" Error: failed to read config file from "/etc/hickory/testing.toml": toml decode error: TOML parse error at line 38, column 1 | 38 | [[zones]] | ^^^^^^^^^ unknown variant `blocklist`, expected `forward` or `default` ``` --- **blocklists in `forward` `zones.stores` where `zones.type="External"`** ``` toml [[zones]] zone = "." zone_type = "External" [zones.stores] type = "forward" wildcard_match = true min_wildcard_depth = 2 sinkhole_ipv4 = "192.0.2.1" sinkhole_ipv6 = "::ffff:c0:0:2:1" block_message = "This query has been blocked by the DNS server" lists = [ "/etc/hickory/lists/disconnectme", "/etc/hickory/lists/stevenblack" ] [[zones.stores.name_servers]] socket_addr = "1.1.1.1:53" protocol = "udp" trust_negative_responses = false [[zones.stores.name_servers]] socket_addr = "1.1.1.1:53" protocol = "tcp" trust_negative_responses = false ``` ``` # hickory-dns --debug --config /etc/hickory/testing_merged.toml 1742021730:INFO:hickory_dns:178:Hickory DNS 0.25.0 starting... 1742021730:INFO:hickory_dns:185:loading configuration from: "/etc/hickory/testing_merged.toml" Error: failed to read config file from "/etc/hickory/testing_merged.toml": toml decode error: TOML parse error at line 38, column 1 | 38 | [[zones]] | ^^^^^^^^^ unknown field `wildcard_match`, expected `name_servers` or `options` ```
Author
Owner

@marcus0x62 commented on GitHub (Mar 28, 2025):

Hi @rskntroot, the config you posted earlier:

[[zones]]
zone = "."
zone_type = "External"

[[zones.stores]]
type = "blocklist"
wildcard_match = true
min_wildcard_depth = 2
sinkhole_ipv4 = "192.0.2.1"
sinkhole_ipv6 = "::ffff:c0:0:2:1"
block_message = "This query has been blocked by the DNS server"
lists = ["/etc/hickory/lists/disconnectme", "/etc/hickory/lists/stevenblack"]

[[zones.stores]]
type = "forward"

[[zones.stores.name_servers]]
socket_addr = "1.1.1.1:53"
protocol = "udp"
trust_negative_responses = false

[[zones.stores.name_servers]]
socket_addr = "1.1.1.1:53"
protocol = "tcp"
trust_negative_responses = false

works for me with hickory built from the main branch. How are you building the hickory-dns binary? Based on the error you've posted, I suspect the blocklist feature is not being enabled.

You'll need to build with --features=blocklist in order to use the blocklist authority:

cargo build --bin hickory-dns --features=blocklist --release

<!-- gh-comment-id:2762169208 --> @marcus0x62 commented on GitHub (Mar 28, 2025): Hi @rskntroot, the config you posted earlier: ``` [[zones]] zone = "." zone_type = "External" [[zones.stores]] type = "blocklist" wildcard_match = true min_wildcard_depth = 2 sinkhole_ipv4 = "192.0.2.1" sinkhole_ipv6 = "::ffff:c0:0:2:1" block_message = "This query has been blocked by the DNS server" lists = ["/etc/hickory/lists/disconnectme", "/etc/hickory/lists/stevenblack"] [[zones.stores]] type = "forward" [[zones.stores.name_servers]] socket_addr = "1.1.1.1:53" protocol = "udp" trust_negative_responses = false [[zones.stores.name_servers]] socket_addr = "1.1.1.1:53" protocol = "tcp" trust_negative_responses = false ``` works for me with hickory built from the main branch. How are you building the hickory-dns binary? Based on the error you've posted, I suspect the blocklist feature is not being enabled. You'll need to build with --features=blocklist in order to use the blocklist authority: ``` cargo build --bin hickory-dns --features=blocklist --release```
Author
Owner

@rskntroot commented on GitHub (Mar 31, 2025):

can confirm, building with --features=blocklist did it. thank you!

<!-- gh-comment-id:2765015018 --> @rskntroot commented on GitHub (Mar 31, 2025): can confirm, building with `--features=blocklist` did it. thank you!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hickory-dns#1074
No description provided.