I wanted a PF rule so all DNS / NTP traffic on my network
not going to my OPNsense would be redirected to localhost (the OPNsense box itself) in order to transparantly redirect this traffic. I have a dual stack (IPv4/IPv6) setup.
Easy enough for IPv4, for example DNS, but same for NTP (but different ports and only UDP).
I have allow rules for DNS / NTP under Firewall-Rules-WhateverInterface
NAT Port Forward:
- Interface: Interfaces I want
- TCP/IP: IPv4
- Protocol: TCP/UDP
- Destination / Invert: selected
- Destination: Alias of my OpnSense box
- Destination Port Range: DNS-DNS
- Redirect target IP: Single host or Network: 127.0.0.1
- Redirect target Port: DNS
Works perfectly for IPv4.
For
IPv6 however, I would expect that the only things I have to change are:
The 2nd one:
TCP/IP: IPv6 The 7th one:
Redirect target IP: Single host or Network: ::1I found out this is not working. Unbound and Chrony, which I use for DNS/NTP, apparently bind on
127.0.0.1, but not on the IPv6 counterpart
::1.
I already found a workaround after too many hours of research and trying:
- Under Interfaces-Virtual IP's make a virtual IPv6 ULA on the Loopback interface, for example fd08::1/128.
- Restart Unbound and Chrony (they now bind to fd08::1/128).
Make a NAT Port Forward rule:
- Interface: Interfaces I want
- TCP/IP: IPv6
- Protocol: TCP/UDP
- Destination / Invert: selected
- Destination: Alias of my OpnSense box
- Destination Port Range: DNS-DNS
- Redirect target IP: Single host or Network: fd08::1/128
- Redirect target Port: DNS
To make things easier you could also make an alias under Firewall-Aliases to fd08::1/128 or whatever ULA you choose.
All set and done. Posted this for the benefit of the earth but also: I can't handle that I don't understand why it doesn't work with
::1? Or did I accidentally found a bug (probably not)? Maybe someone here could explain that, so I can sleep and give my brain some rest.
Thanks and cheers!
Cannot confirm this regarding Unbound. No idea about chrony.
# sockstat -n | grep :53
59 unbound 75740 5 udp6 *:53 *:*
59 unbound 75740 6 tcp6 *:53 *:*
59 unbound 75740 7 udp4 *:53 *:*
59 unbound 75740 8 tcp4 *:53 *:*
Quote from: doktornotor on August 25, 2024, 10:17:02 AM
Cannot confirm this regarding Unbound. No idea about chrony.
# sockstat -n | grep :53
59 unbound 75740 5 udp6 *:53 *:*
59 unbound 75740 6 tcp6 *:53 *:*
59 unbound 75740 7 udp4 *:53 *:*
59 unbound 75740 8 tcp4 *:53 *:*
I found that out too! And SSH'ing in the OPNsense box you van easily do
nslookup whatever.com ::1
And that works!
But in practice, doing an nslookup to an arbitrary IPv6 dns server (using the IPv6-address, not the hostname) from a node in my network fails with the ::1 rule in place, while the same succeeds for IPv4 (due to the 127.0.0.1 rule). It's almost if ::1 in this case does not redirect to OPNsense itself but to the machine asking? Weird.
Exact the same goes for Chrony and probably every service. ::1 does not work the way I think it works from a remote host in my network - not the same as 127.0.0.1, I suspect.
Using the ULA for loopback is a great solution. When I was setting this up, I ended up creating a Dynamic IPv6 Host alias (https://docs.opnsense.org/manual/aliases.html#dynamic-ipv6-host) of my WAN SLAAC, and using that as my redirect target. I might switch to using your method instead.
For AdguardHome users, the /128 is not needed - service won't start otherwise
dns:
bind_hosts:
- 127.0.0.1
- fd08::1