Unbound forward to BIND tips and tricks?

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

Previous topic - Next topic
It's dawning at me ... do you have home.arpa set as the local domain of your firewall? There's quite some "magic" in the unbound setup pulling configuration bits from all possible places, not only Services > Unbound as one might expect but also System > Settings > General.

And if I am not completely wrong - and the SOA returned by your query example corroborates that - your Unbound thinks it's authoritative for home.arpa and neither the domain override nor the forward domain entry actually override that.

Since it doesn't really matter what the firewall itself thinks its domain is, you can set that to some other arbitrary value and still hand out home.arpa explicitly with DHCP.

That's my last idea but it is at least perfectly consistent with your observation that the forward queries just never happen.

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

Slightly off-topic but since Patrick is here as well... in 23.1.6 you will be able to run BIND (or Dnscrypt-proxy) as a stand-alone core DNS server when using both of the listening addresses 0.0.0.0:53 and [::]:53 at the same time.

So juggling Unbound to forward might not even be necessary anymore.


Cheers,
Franco

April 16, 2023, 08:39:00 PM #17 Last Edit: April 16, 2023, 08:47:32 PM by netnut
I'm using Unbound with local zones in Bind successfully for many OPNsense releases, should be straight forward. While I still use the "Domain Overrides" option in Unbound, just tested it with a domain defined in "Query Forwarding" which also works flawless. Things to check:

Unbound
- Listen on all interfaces
- Use System Nameservers (disabled)
- Query Forwarding:
- Domain: domain.tld
- Address: 127.0.0.1
- Port: 53053 (whatever you running Bind on)

BIND
- Create ACL
- Name: BIND-LOCALHOST
- Networks: 127.0.0.1,::1   

- Master Zone
- Zone Name: domain.tld
- Allow Query: BIND-LOCALHOST (ACL created above)
- [other zone options]

- Records
- Create a valid zone file with NS records (127.0.0.1) and your hosts, be sure to finish FQDN's with a . (dot)
- Optional create reverse zones (in-addr.arpa) as master


Query from OPNsense shell to Unbound


dig ns.domain.tld

; <<>> DiG 9.18.13 <<>> ns.domain.tld
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 493
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;ns.domain.tld. IN A

;; ANSWER SECTION:
ns.domain.tld. 86343 IN A 127.0.0.1

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Sun Apr 16 20:34:33 CEST 2023
;; MSG SIZE  rcvd: 58



Query from OPNsense shell to BIND directly:


dig @127.0.0.1 -p 53053 ns.domain.tld

; <<>> DiG 9.18.13 <<>> @127.0.0.1 -p 53053 ns.domain.tld
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47716
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 1fe998ef4f90f8d001000000643c3fe6bf801d59489e799b (good)
;; QUESTION SECTION:
;ns.domain.tld. IN A

;; ANSWER SECTION:
ns.domain.tld. 86400 IN A 127.0.0.1

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53053(127.0.0.1) (UDP)
;; WHEN: Sun Apr 16 20:35:18 CEST 2023
;; MSG SIZE  rcvd: 86



Query from random client OPNsense internal network to Unbound:


dig ns.domain.tld

; <<>> DiG 9.10.6 <<>> ns.domain.tld
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14726
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;ns.domain.tld. IN A

;; ANSWER SECTION:
ns.domain.tld. 86135 IN A 127.0.0.1

;; Query time: 51 msec
;; SERVER: 10.10.10.254#53(10.10.10.254)
;; WHEN: Sun Apr 16 20:38:01 CEST 2023
;; MSG SIZE  rcvd: 58



Be sure to check your BIND logs if your zone is successfully loaded.

April 18, 2023, 06:16:06 PM #18 Last Edit: April 18, 2023, 07:33:08 PM by aida
Quote from: pmhausen on April 16, 2023, 06:19:19 PM
do you have home.arpa set as the local domain of your firewall? There's quite some "magic" in the unbound setup pulling configuration bits from all possible places, not only Services > Unbound as one might expect but also System > Settings > General.

And if I am not completely wrong - and the SOA returned by your query example corroborates that - your Unbound thinks it's authoritative for home.arpa and neither the domain override nor the forward domain entry actually override that.

Since it doesn't really matter what the firewall itself thinks its domain is, you can set that to some other arbitrary value and still hand out home.arpa explicitly with DHCP.

That's my last idea but it is at least perfectly consistent with your observation that the forward queries just never happen.

I thought System A/AAAA records would fix that. The stub-zone thing does sound like what I want. That guide says there is an expectation that Query Forwarding expects to be able to recurse up to the internet root servers.

In my case I am not doing that. The below description describes what I'm trying to do 100%.

QuoteThe 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.

Here is a rough ASCII diagram of the setup. LAN Clients are all the internal machines of the local area network (LAN). The Internet DNS is basically any external DNS server. The entries for Unbound #1 through #3 are separate machines with Unbound running on them. The final machine is the Private BIND LAN DNS.

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.


                 INTERNET
                       |
                       |
                -- Unbound #1 --
              /                  \   private authoritative only
LAN Clients -- --- Unbound #2 --  --   BIND or NSD dns server
              \                  /        ( 10.0.0.111 )
                -- Unbound #3 --

I have this subnet which currently has rules that work: ie if I query BIND directly with -p 53530

I decided to test out the stub-zone method above, in fact I found this gist which looks to be much the same thing. In this case the user has forwarded their LAN zone to dnsmasq instead.


/usr/local/etc/namedb/master/31.168.192.in-addr.arpa.db
$TTL 86400
@       IN      SOA    ns1.rt1.home.arpa. admin.srv1.home.arpa. ( 2304171944 21600 3600 3542400 3600 )
                NS ns1.rt1.home.arpa.
1                PTR rt1.home.arpa.
1                PTR ns1.rt1.home.arpa.
1                PTR opnsense.rt1.home.arpa.


/usr/local/etc/namedb/master/home.arpa.db
$TTL 86400
@       IN      SOA    ns1.rt1.home.arpa. admin.srv1.home.arpa. ( 2304172310 21600 3600 3542400 3600 )
                 A 192.168.31.1
                 NS ns1
ns1              A 192.168.31.1
opnsense         A 192.168.31.1


So the stub zone I created was using the advanced configuration:
/usr/local/etc/unbound.opnsense.d
# Local DNS options
do-not-query-localhost: no
private-domain: "home.arpa"
domain-insecure: "home.arpa"

stub-zone:
  name: "home.arpa"
  stub-addr: 127.0.0.1@53530

local-zone: "10.168.192.in-addr.arpa." nodefault
domain-insecure: "10.168.192.in-addr.arpa"
private-address: 192.168.10.0/24

stub-zone:
  name: "10.168.192.in-addr.arpa."
  stub-addr: 127.0.0.1@53530


What I found was when saving the advanced configuration, my query forwarding stopped working period, all DNS lookups failed.

I think I am close but haven't quite cracked this...

The settings netnut describes there look to me much what I tried before going the stub-zone method.

I think that will only work if you let BIND query internet servers. I didn't really want to do that.

April 20, 2023, 09:15:21 PM #19 Last Edit: April 20, 2023, 09:39:11 PM by netnut
Quote
The settings netnut describes there look to me much what I tried before going the stub-zone method.

Instead of using "advanced" configs you only need to use the built in capabilities of the standard OPNsense web interface. Your use-case isn't that special, all you want to do is configurable with a few clicks in the OPNsense GUI.

Quote
I think that will only work if you let BIND query internet servers. I didn't really want to do that.

No, in my example only Unbound does query internet servers and will contact your local BIND instance when you request (local) domains defined in the "Domain Override" and/or "Query Forwarding" config.

Again, what your trying to do is pretty straight forward. I suggest you start with a clean config and create both Unbound and BIND configs in the web interface (it's all there). When that's working you always can tweak your config with manual custom stuff (but I don't see any reason, because it's all there in the GUI).



Quote from: netnut on April 20, 2023, 09:15:21 PM
Quote from: aida on April 18, 2023, 06:16:06 PM
The settings netnut describes there look to me much what I tried before going the stub-zone method.

Instead of using "advanced" configs you only need to use the built in capabilities of the standard OPNsense web interface. Your use-case isn't that special, all you want to do is configurable with a few clicks in the OPNsense GUI.

That would be my preference as I wouldn't need to store any configuration files elsewhere. I like them being backed up in the single XML file that OPNSense makes.

Quote from: netnut on April 20, 2023, 09:15:21 PM
Quote from: aida on April 18, 2023, 06:16:06 PM
I think that will only work if you let BIND query internet servers. I didn't really want to do that.

No, in my example only Unbound does query internet servers and will contact your local BIND instance when you request (local) domains defined in the "Domain Override" and/or "Query Forwarding" config.

Again, what your trying to do is pretty straight forward. I suggest you start with a clean config and create both Unbound and BIND configs in the web interface (it's all there). When that's working you always can tweak your config with manual custom stuff (but I don't see any reason, because it's all there in the GUI).

I did think so however I have no idea why it doesn't work for me.

Unbound seems to return a SOA localhost. nobody.invalid. for anything in my BIND instance.

There also seems to be nothing in the logs when doing a .home.arpa query to Unbound, even on level 5 verbosity. This is the configuration I tried.









Really not sure why this is so complex. Nothing I've tried seems to get unbound to query the BIND instance.

I decided to test this on my archlinux machine and was able to reproduce. I was able to fix it and the problematic parts of the unbound config was this:


# By default, for a number of zones a small default 'nothing here'
# reply is built-in.  Query traffic is thus blocked.  If you
# wish to serve such zone you can unblock them by uncommenting one
# of the nodefault statements below.
# You may also have to use domain-insecure: zone to make DNSSEC work,
# unless you have your own trust anchors for this zone.
# local-zone: "localhost." nodefault
# local-zone: "127.in-addr.arpa." nodefault
# local-zone: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." nodefault
local-zone: "home.arpa." nodefault


By default it seems unbound does something with home.arpa domains. I didn't see a method to uncomment that last line in the opnsense web interface.

That's why I have never beeb able to reproduce this problem. Jesus tapdancing christ! Special treatment of any particular zone by "magic" should be punished. In BIND you setup regular zone files for e.g. localhost.

Another remark: I always recommend using a subdomain of a real domain name for internal networks. This way you won't get a conflict when your "private" domain unexpectedly has some special meaning (".local") or a new top level domain is introduced or suddenly you need split DNS because you run AD but marketing insists the external webserver must be "company.com", etc.

So the name and domain of my company is punkt.de. Our internal network is intern.punkt.de. No entry for anything in intern.punkt.de is published on the Internet. My private domain is hausen.com. My homelab uses ettlingen.hausen.com, the place where I live. Again no ettlingen.hausen.com anywhere public.

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

April 24, 2023, 06:05:57 PM #23 Last Edit: April 24, 2023, 08:08:22 PM by aida
Quote from: pmhausen on April 23, 2023, 07:05:18 PM
Special treatment of any particular zone by "magic" should be punished.

I actually think it violates the Section 3 of RFC 8375 Special-Use Domain 'home.arpa.'

Quote
   1.  Users can use names ending with '.home.arpa.' just as they would
       use any other domain name.  The 'home.arpa.' name is chosen to be
       readily recognized by users as signifying that the name is
       addressing a service on the homenet to which the user's device is
       connected.

   2.  Application software SHOULD NOT treat names ending in
       '.home.arpa.' differently than other names.  In particular, there
       is no basis for trusting names that are subdomains of
       'home.arpa.' (see Section 6).

   3.  Name resolution APIs and libraries MUST NOT recognize names that
       end in '.home.arpa.' as special and MUST NOT treat them as having
       special significance, except that it may be necessary that such
       APIs not bypass the locally configured recursive resolvers.

Quote from: pmhausen on April 23, 2023, 07:05:18 PM
In BIND you setup regular zone files for e.g. localhost.

Which I have done.

Anyway I was able to disable this with:

printf 'server:\n\tlocal-zone: "home.arpa." nodefault\n' > /usr/local/etc/unbound.opnsense.d/local-zone.conf

Anyway I found that wasn't working correctly as the A record shows up as empty. That was because I had the Outgoing Interface set to my VPN interface which sets:

# Outgoing interfaces to be used
outgoing-interface: 10.82.40.3


The intention here was to prevent leaking to my ISP. It seems it always did regardless of if " Use System Nameservers" was selected or not. In hindsight, it would have been better to do something like https://forum.opnsense.org/index.php?topic=9245.0

When I had that set to any I was finding

This seems related to the outgoing interface, because I was using my VPN provider's internal interface.

Quote from: pmhausen on April 23, 2023, 07:05:18 PM
Another remark: I always recommend using a subdomain of a real domain name for internal networks. This way you won't get a conflict when your "private" domain unexpectedly has some special meaning (".local") or a new top level domain is introduced or suddenly you need split DNS because you run AD but marketing insists the external webserver must be "company.com", etc.

So the name and domain of my company is punkt.de. Our internal network is intern.punkt.de. No entry for anything in intern.punkt.de is published on the Internet. My private domain is hausen.com. My homelab uses ettlingen.hausen.com, the place where I live. Again no ettlingen.hausen.com anywhere public.

That is one option, but as this is a small home network with only internal services, I didn't really want to register a domain just for that.

QuoteThat is one option, but as this is a small home network with only internal services, I didn't really want to register a domain just for that.

Good you have it fixed, because you're in full control of your name resolution you can use any domain you like (except .arpa off course  8)). Like pmhausen already addressed stay away from specials like .local , but you're free to make up anything you like, for instance .lan , .home , .internal , .l33t etc.

I hijack several public domains locally just because I like the name or need to emulate/demo stuff.

We had another user report problems trying to use .lan as the local domain and host names directly under that. As soon as they switched to .myname.lan everything worked as expected. Ah ... yes, I remember: browsers do not accept wildcard certificates for TLDs like *.lan.

Possibly it's only .home.arpa that gets a special treatment but .myname.home.arpa works ok?
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

April 24, 2023, 11:57:37 PM #26 Last Edit: April 25, 2023, 12:07:41 AM by netnut
QuoteAh ... yes, I remember: browsers do not accept wildcard certificates for TLDs like *.lan.

With a public CA (like Lets Encrypt), no, you never get a certificate for non-existent domains or IP addresses in the CN or SAN...

But if you run your own DNS, your next step could be running your own Private / Corporate PKI. Browers will check certificate based on address (valid if you run your own DNS), Date/Time and Trusted Root CA.

So with your private CA you can sign valid certs with IP addresses or, in this case when running your private DNS, non-public domain names. I'm even running my internal OCSP responder on a domain with a .PKI tld. It's shady and non-standard, but you sure can have a fully functional PKI without public validated domain names.

QuotePossibly it's only .home.arpa that gets a special treatment but .myname.home.arpa works ok?

Yeah, never knew Unbound is that picky about .arpa, so thanks aida for the insight ;-). Thinking about it, it makes sense not f***ing up your reverse zones by accident.

@netnut, even with a private CA the browser will not accept a wildcard cert for *.lan, only for *.foo.lan ... that was the problem of that other person as it turned out.
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

April 25, 2023, 08:49:37 AM #28 Last Edit: April 25, 2023, 08:52:26 AM by aida
Quote from: netnut on April 24, 2023, 08:31:17 PM
but you're free to make up anything you like, for instance .lan , .home , .internal , .l33t etc.

Yeah best not to do that .home.arpa is intended for homenets. I am pretty sure I've seen recommendations against using .home and .internal on HN, partly because of old Microsoft documentation suggested that.

Quote from: pmhausen on April 24, 2023, 10:35:08 PM
We had another user report problems trying to use .lan as the local domain and host names directly under that. As soon as they switched to .myname.lan everything worked as expected. Ah ... yes, I remember: browsers do not accept wildcard certificates for TLDs like *.lan.

Possibly it's only .home.arpa that gets a special treatment but .myname.home.arpa works ok?

No the point is .home.arpa should not get any special treatment behind being non routable upstream. The RFC is only from 2018 so people are a little stuck in the past.

Quote from: pmhausen on April 25, 2023, 05:22:39 AM
@netnut, even with a private CA the browser will not accept a wildcard cert for *.lan, only for *.foo.lan ... that was the problem of that other person as it turned out.

.home.arpa certainly works with Chrome and Firefox if you have your own root.


But yes, the TLDR of this thread is that local-zone should be configurable in the web UI for Unbound. When you use a host-override that automatically overrides it, but if you're using a nameserver upstream like BIND you'll need to have that set to nondefault.

printf 'server:\n\tlocal-zone: "home.arpa." nodefault\n' > /usr/local/etc/unbound.opnsense.d/local-zone.conf

April 26, 2023, 07:17:16 PM #29 Last Edit: April 26, 2023, 07:55:46 PM by aida
So I had another look at this.

Without using the Outgoing Interface on Unbound, I need a rule which directs this traffic into my VPN. If I use the Outgoing Interface as my Wireguard tunnel (so that requests go over the VPN), then the issue is that I can't access the BIND instance on localhost. I tried the policy match rule on anything from localhost with a destination port of 53, but it seems to be not picked up.

On a separate note:

I used this method to redirect all IPv4 DNS unencrypted requests to my OPNSense router. This is because some devices are hardcoded to use things like 8.8.8.8. Unfortunately the same method did not work for IPv6.