Unbound forward to BIND tips and tricks?

Started by aida, April 14, 2023, 09:18:03 AM

Previous topic - Next topic
Hi,

I've been unable to crack this one.

I can get BIND working, and if I do a query ie:


drill -p 53530 rt1.home.arpa


I get the correct result. The issue is that I'm having trouble getting Unbound to forward queries to BIND.

The idea is that Unbound will forward .home.arpa queries to my local BIND server and everything else to an external DNS server.

Ie I have:




# cat /var/unbound/etc/dot.conf
server:
  do-not-query-localhost: no

# Forward zones
forward-zone:
  name: "."
  forward-addr: 10.0.254.2@53
forward-zone:
  name: "home.arpa"
  forward-addr: 127.0.0.1@53530


I've tried by making sure the forward zone was . instead of home.arpa but nothing seems to work. I've disabled my overrides, I read in another thread that was necessary.

Could you try a domain override instead? I don't use Unbound much, so I'm guessing.
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

April 14, 2023, 09:33:56 AM #2 Last Edit: April 14, 2023, 09:35:59 AM by aida
I hadn't tried that, but I'm not sure I can specify the port there for BIND.




One other thing I should mention I made sure to put home.arpa in the "Private Domains" section and "Insecure Domains".

April 14, 2023, 10:02:56 AM #3 Last Edit: April 14, 2023, 10:10:38 AM by aida
I should mention the only reason I am introducing BIND to my setup is because I want to use the ACME plugin and the DNS-01 challenge for that uses the OPNSense BIND API.

Ie as I mentioned in this post:



If you think I'm off track and there's a better way..... happy to hear it.

I should have clicked on Full Help as it says:

QuoteIP address of the authoritative DNS server for this domain, e.g. '192.168.100.100'. To use a nondefault port for communication, append an '@' with the port number.

So I entered this:



Still not working hmm.

tcpdump the packets ...

I am using a similar setup with BIND and AdGuard Home. AdGuard Home forwarding to BIND on 127.0.0.1:53.

I have both services bound to 127.0.0.1 only and use port forwarding NAT rules to direct client requests per interface to either AGH or BIND, bypassing AGH ...

Kind regards,
Patrick
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

That does sound like the reverse of what I have.

Are there any benefits I wonder to having BIND listen locally, with authoritative zones, and then that forward to unbound -> external DNS? Maybe that would be a better approach.

AGH is the general resolver and forwards to BIND here. BIND has authoritative primary and secondary zones.

A NAT port forward rule for LAN directs all DNS requests to AGH. A NAT port forward rule in the server network directs all requests directly to BIND, because why would I want an ad block in front of a server?
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

April 15, 2023, 10:39:33 AM #7 Last Edit: April 15, 2023, 10:49:59 AM by aida
Quote from: pmhausen on April 14, 2023, 10:24:17 AM
tcpdump the packets ...

I dumped that on localhost port 53530:


length 67: (tos 0x0, ttl 64, id 29113, offset 0, flags [none], proto UDP (17), length 63, bad cksum 0 (->af3)!)
    127.0.0.1.39558 > 127.0.0.1.53530: [bad udp cksum 0xfe3e -> 0x2095!] UDP, length 35

length 83: (tos 0x0, ttl 64, id 64085, offset 0, flags [none], proto UDP (17), length 79, bad cksum 0 (->8246)!)


What is interesting is I don't see an invalid record returned, just nothing dead quiet. It looks the same even if a real record is returned. For example:


drill -p 53530 rt1.home.arpa


rt1.home.arpa. 86400 IN A 192.168.31.1


I also tried a record that doesn't exist.


drill -p 53530 doest-exist.rt1.home.arpa


rt1.home.arpa. 3600 IN SOA ns1.rt1.home.arpa. admin.srv1.home.arpa. 2304110436 21600 3600 3542400 3600


If I look at a successful packet being returned on Unbound with a Host Override I see:

length 74: (tos 0x0, ttl 64, id 21684, offset 0, flags [none], proto UDP (17), length 70, bad cksum 0 (->27f1)!)
    127.0.0.1.22926 > 127.0.0.1.53: [bad udp cksum 0xfe45 -> 0xbd2d!] 48201+ A? arch.srv1.home.arpa. (42)

length 90: (tos 0x0, ttl 64, id 26192, offset 0, flags [none], proto UDP (17), length 86, bad cksum 0 (->1645)!)
    127.0.0.1.53 > 127.0.0.1.22926: [bad udp cksum 0xfe55 -> 0x76c3!] 48201* q: A? arch.srv1.home.arpa. 1/0/0 arch.srv1.home.arpa. A 192.168.50.253 (58)


An unsuccessful lookup (because it doesn't exist) like looks like:


length 77: (tos 0x0, ttl 64, id 27142, offset 0, flags [none], proto UDP (17), length 73, bad cksum 0 (->129c)!)
    127.0.0.1.50527 > 127.0.0.1.53: [bad udp cksum 0xfe48 -> 0x9789!] 26298+ A? doesnt-exist.srv2.home.arpa. (45)
length 136: (tos 0x0, ttl 64, id 23218, offset 0, flags [none], proto UDP (17), length 132, bad cksum 0 (->21b5)!)
    127.0.0.1.53 > 127.0.0.1.50527: [bad udp cksum 0xfe83 -> 0xe7fd!] 26298 NXDomain* q: A? doesnt-exist.srv2.home.arpa. 0/1/0 ns: home.arpa. SOA localhost. nobody.invalid. 1 3600 1200 604800 10800 (104)


When I try to query Unbound for a record that is in BIND this is what I see:


length 63: (tos 0x0, ttl 64, id 19475, offset 0, flags [none], proto UDP (17), length 59, bad cksum 0 (->309d)!)
    127.0.0.1.41417 > 127.0.0.1.53: [bad udp cksum 0xfe3a -> 0x25ed!] 5216+ A? rt1.home.arpa. (31)
length 122: (tos 0x0, ttl 64, id 11664, offset 0, flags [none], proto UDP (17), length 118, bad cksum 0 (->4ee5)!)
    127.0.0.1.53 > 127.0.0.1.41417: [bad udp cksum 0xfe75 -> 0x8461!] 5216 NXDomain* q: A? rt1.home.arpa. 0/1/0 ns: home.arpa. SOA localhost. nobody.invalid. 1 3600 1200 604800 10800 (90)


localhost. nobody.invalid is returned by Unbound not BIND, because I see the same thing if i search for some other domain. like the one above.

I'm not sure what to try next. hmm.

Quote from: pmhausen on April 14, 2023, 09:19:35 AM
Could you try a domain override instead? I don't use Unbound much, so I'm guessing.

I've tried that again, and it doesn't seem to work any better.

The documentation seems to indicate domain overrides are deprecated https://docs.opnsense.org/manual/unbound.html#domain-override-settings

QuoteDomain overrides has been superseded by Query Forwarding. Query forwarding also allows you to forward every single request.
.

I tried replacing it with 8.8.8.8 and when doing https://www.dnsleaktest.com/ I noticed Google's servers in there, so that seems to be working.

I tried replacing the forwarding IP with 192.168.31.1 (IP of the router), and the listen IP on BIND and that didn't work either.

Just seems that unbound refuses to use BIND for lookups.

I don't think it's a firewall issue anyway because I see on the Unbound logs:

Loopback                2023-04-16T15:23:42     127.0.0.1:53    127.0.0.1:21181 udp     let out anything from firewall host itself
Loopback                2023-04-16T15:23:42     127.0.0.1:21181 127.0.0.1:53    udp     let out anything from firewall host itself


If I specify port 53530 with drill:

Loopback              2023-04-16T15:52:42     127.0.0.1:53530 127.0.0.1:7476  udp     let out anything from firewall host itself
Loopback              2023-04-16T15:52:42     127.0.0.1:7476  127.0.0.1:53530 udp     let out anything from firewall host itself


What I should see is a pair of those, in succession ie if i look for rt1.home.arpa on 127.0.0.1 53 ie with Unbound, as it should be at least attempting to search unbound for this domain instead of failing instantly with:

home.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800

April 16, 2023, 01:39:54 PM #9 Last Edit: April 16, 2023, 01:44:42 PM by aida
I installed DNSCrypt-proxy to test that. I can make queries with

drill -p 5353 @::1 google.com.

But as soon as I try to get unbound to do it. I get no replies. That leads me to believe this is an unbound issue and not BIND.


April 16, 2023, 02:46:28 PM #10 Last Edit: April 16, 2023, 02:51:44 PM by pmhausen
Does Unbound have any IPv6 listen address active? Could you switch to 127.0.0.1 instead?

Edit: thnking about that idea - do you have unbound configured for specific interfaces only? Could you change that back to "Any (recommended)"?
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

Quote from: pmhausen on April 16, 2023, 02:46:28 PM
Does Unbound have any IPv6 listen address active? Could you switch to 127.0.0.1 instead?

It does, and it was the same result with 127.0.0.1. I started with 127.0.0.1 but noticed the same thing with ::1. (That was less characters to type so I stuck with it).

Quote from: pmhausen on April 16, 2023, 02:46:28 PM
Edit: thnking about that idea - do you have unbound configured for specific interfaces only? Could you change that back to "Any (recommended)"?

"Network Interfaces", is set to all of my LAN side interfaces, VLANs etc. "Outgoing Network Interfaces" is set to my VPN Tunnel.

That shouldn't effect localhost though, in fact there's no option to select "lo". I think based on this reply, you have to have localhost.

Remove all the network interfaces to let it switch back to "any" or "all" however that is phrased - just for a test, please.
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

April 16, 2023, 04:48:07 PM #13 Last Edit: April 16, 2023, 04:50:37 PM by aida
Quote from: pmhausen on April 16, 2023, 04:30:30 PM
Remove all the network interfaces to let it switch back to "any" or "all" however that is phrased - just for a test, please.

Sure. I let the "Network Interfaces" and "Outgoing Network Interfaces" go back to "All (Recommended)" same issue.

Querying domain in Unbound.

# dig +short version.bind chaos txt
"unbound 1.17.1"

# drill rt1.home.arpa
;; ->>HEADER<<- opcode: QUERY, rcode: NXDOMAIN, id: 43511
;; flags: qr aa rd ra ; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;; rt1.home.arpa. IN A

;; ANSWER SECTION:

;; AUTHORITY SECTION:
home.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800

;; ADDITIONAL SECTION:

;; Query time: 0 msec
;; SERVER: 127.0.0.1
;; WHEN: Mon Apr 17 00:10:31 2023
;; MSG SIZE  rcvd: 90


Querying BIND directly:

# dig +short version.bind chaos txt -p 53530
"9.16.36"

# drill -p 53530 rt1.home.arpa
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 34820
;; flags: qr aa rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; rt1.home.arpa. IN A

;; ANSWER SECTION:
rt1.home.arpa. 86400 IN A 192.168.31.1

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 0 msec
;; SERVER: 127.0.0.1
;; WHEN: Mon Apr 17 00:10:53 2023
;; MSG SIZE  rcvd: 47


These settings



I'm starting to pull my hair out... as I'm running out of ideas.

In this case the second DNS server there 10.0.254.2 is my VPN server's DNS server

April 16, 2023, 04:58:54 PM #14 Last Edit: April 16, 2023, 05:57:06 PM by aida
I'm wondering whether or not I shouldn't be using a forward zone, and instead should be using a stub zone? I wish the documentation on OPNSense's manual was a bit more detailed. This particular guide mentioned:

QuoteUnbound DNS cluster with BIND or NSD master server

Unbound is the perfect front line soldier for DNS queries from LAN clients. It is fast, reliable, stable and very secure. BIND (named) or NSD (Name Server Daemon) can be kept on the back end network to be an authoritative DNS to the Unbound cluster. This way you keep your primary DNS data segregated and unencumbered on the BIND or NSD server while the Unbound cluster servers do the resolving, caching and validation of zones for clients.

The idea is to have a few Unbound validating, recursive and caching DNS servers which LAN clients can query. Then use BIND (named) as an authoritative server which can resolve internal LAN names only. LAN clients will NEVER access the BIND DNS server and BIND will never go out to the Internet. BIND's only job is to serve internal names to the Unbound DNS server cluster. The Unbound cluster will serve all LAN clients. If Unbound needs to resolve a private ip it will ask the BIND server for ips and then cache the response. If the client needs an external ip, lets say from google.com or cnn.com, Unbound will recursively query the Internet root DNS servers and cache the response.

QuoteLets say our private NSD or BIND server is authoritative for this internal LAN domain:

  • home.lan
We need to tell the Unbound cluster servers that if they are looking for the private home.lan domain to ask the authoritative DNS server, otherwise go check with the root DNS servers. The NSD server's ip is 10.0.0.111 as in the ASCII diagram.

Pay special attention to the stub-zone directive we are using. Stub-zone is only used to point queries to an authoritative server like a NSD dns server. The forward-zone directive can only be used to point queries to a resolving dns server like OpenDNS.com or you local ISP's caching server. The two are not interchangeable.

## Add this to the bottom of example #2's unbound.conf configuration
## Check out our NSD Tutorial at https://calomel.org/nsd_dns.html

   # This local-zone line will tell unbound that private addresses like
   # 10.0.0.0/8 can send queries to a stub zone authoritative server like NSD.
   local-zone: "10.in-addr.arpa." nodefault

   # This is the FORWARD lookup stub zone pointing to the NSD authoritative
   # server. When a client queries for firewall.home.lan the question is sent
   # to the NSD server located at 10.0.0.111 and NSD returns the answer
   # "10.0.0.1".
   stub-zone:
        name: "home.lan"
        stub-addr: 10.0.0.111

   # This is the REVERSE (rDNS) dns lookup for the home.lan zone. When a client
   # asks for the hostname belonging to the ip address 10.0.0.1 the NSD
   # authoritative server at 10.0.0.111 will send back the answer
   # "firewall.home.lan".
   stub-zone:
        name: "10.in-addr.arpa."
        stub-addr: 10.0.0.111


QuoteThat's about it. A client asking for an internal dns hostname like, laptop.home.lan.lan will make Unbound query the NSD server (10.0.0.111); the answer will be cached by Unbound for later queries. Any other queries for external hostnames (calomel.org for example) from LAN clients will have Unbound go to Internet servers for the answer. Clients can now query the Unbound cluster for any hostnames they want and we do not have to worry about our primary NSD dns servers being abused or overloaded. This setup is mainly designed to segregate the authoritative server off by itself and keep the primary DNS configuration safe.

I didn't see any way to add stub-zones in the Unbound interface, so I would probably need to use some kind of advanced configuration for that?