6in4 using henet and unbound

I copied this rule directly to my file, then checked from the web interface:
immagine

It is shown as IPV4-only. I have verified that I can still query an external server if I dig google's IPV6 dns server. I asked for my router's address using the local name, which google doesn't know about, and it failed as expected. If I query 8.8.8.8 for netflix, then there is no AAAA reply, thanks to your extra unbound config.

TLDR with those rules, the Netflix app is still able to bypass your DNS server, get an IPV6 answer and promptly send traffic through the tunnel.

I'd say it is time to study the example linked by @trendy

thanks for testing it out! I'll check out the examples that were linked. Seems my issue is some ipv6 dns queries can still bypass my local dns server.

I'm also looking at testing out the NextDNS.io client they have for OpenWRT and dropping Unbound.

I'm assuming by these results that all my ipv6 dns queries are only being resolved locally.

This is on my Windows 10 workstation (a client)

cylac@CHAOS:~$ nslookup gatekeeper.myprivdomainname.ca 8.8.8.8
Server:         8.8.8.8
Address:        8.8.8.8#53

Name:   gatekeeper.myprivdomainname.ca
Address: 192.168.76.1

cylac@CHAOS:~$ nslookup gatekeeper.myprivdomainname.ca 2001:4860:4860::8888
Server:         2001:4860:4860::8888
Address:        2001:4860:4860::8888#53

Name:   gatekeeper.myprivdomainname.ca
Address: 192.168.76.1

I followed the instructions found here: https://openwrt.org/docs/guide-user/services/dns/intercept

I wasn't sure if it worked since I got this once I reloaded the firewall:

* Populating IPv6 nat table
Warning: fw3_ipt_rule_append(): Can't find target 'prerouting_lan_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'postrouting_lan_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'prerouting_wan_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'postrouting_wan_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'prerouting_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'postrouting_rule'

It's probably not related.

Anyhow, I'm gonna guess that ANY ipv6 and ipv4 dns queries from any of my clients have to use my local dns.

Most likely so, that's why I am not sure switching server software will do anything beyond learning how to configure it :slight_smile:

Hmm, that guide doesn't look right, @trendy: only in UCI is the target "DNAT" or "SNAT", in iptables-save that becomes "REDIRECT" so the sed invocation for IPV6 would probably not work as intended, at least here it does not generate any IPV6 rules.

Assuming I don't have pi-hole and that the DNS server lives on the router, do I need all those rules or can one get by with a reduced set? For example that from the guide above, albeit with a revised "sed" translation?

The REDIRECT is almost the same as DNAT, but to redirect to the same device.

The REDIRECT target is used to redirect packets and streams to the machine itself. This means that we could for example REDIRECT all packets destined for the HTTP ports to an HTTP proxy like squid, on our own host. Locally generated packets are mapped to the 127.0.0.1 address. In other words, this rewrites the destination address to our own host for packets that are forwarded, or something alike. The REDIRECT target is extremely good to use when we want, for example, transparent proxying, where the LAN hosts do not know about the proxy at all.
Note that the REDIRECT target is only valid within the PREROUTING and OUTPUT chains of the nat table. It is also valid within user-defined chains that are only called from those chains, and nowhere else. The REDIRECT target takes only one option, as described below.
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

I know :slight_smile:
My question was on the "sed" string: I don't think it works as intended.

The sed string works as intended, to create the custom chains in the ip6tables from iptables.
Then it is up to you to add the redirect in the proper chain in ip6tables.
Does that cover you?

Have you tried it? Not just looked at it, like I also did at first :slight_smile:
I have copypasted the whole thing and it doesn't change anything, because on the current 19.07.2 this

uci -q delete firewall.dns_int
uci set firewall.dns_int="redirect"
uci set firewall.dns_int.name="Intercept-DNS"
uci set firewall.dns_int.src="lan"
uci set firewall.dns_int.src_dport="53"
uci set firewall.dns_int.family="ipv4"
uci set firewall.dns_int.proto="tcp udp"
uci set firewall.dns_int.target="DNAT"

becomes:

-A zone_lan_prerouting -p tcp -m tcp --dport 53 -m comment --comment "!fw3: Intercept-DNS" -j REDIRECT --to-ports 53
-A zone_lan_prerouting -p udp -m udp --dport 53 -m comment --comment "!fw3: Intercept-DNS" -j REDIRECT --to-ports 53

Then sed looks for either DNAT or SNAT, finds none and does not output MASQUERADE for IPV6.

I'm trying to understand if I have made a mistake somewhere, if I am missing something or somehow the guide was written for an older version of openwrt where the uci stanza above would be expanded as expected by sed. (EDIT: nope, see later)

EDIT: I have also tried "sed" by itself, feeding it input with DNAT or SNAT, but no luck, I'm stuck.

I am actually using it. If you compare the output between iptables-save -t nat and iptables-save -t nat | sed -e "/\s[DS]NAT\s/d;/\sMASQUERADE$/d" you'll verify that all DNAT, SNAT, and MASQUERADE rules are removed. So what is restored to ip6tables is the skeleton of the custom chains and whatever rules were created before you ran that, other than SNAT, DNAT, and MASQUERADE.
I am running my dns-hijack6 custom scripts after I run this firewall.nat6, so I need to create the DNAT and MASQUERADES in the dns-hijack6. I guess if you had run already the REDIRECT before, then it would be transferred over when firewall.nat6 runs, since REDIRECT is not a keyword in sed to be omitted.

1 Like

Ahhhhh, thanks! See, I was indeed missing something :stuck_out_tongue:
(old habit of using sed only to transform strings, not to remove them altogether... as a consequence, I didn't look at other lines, just those related to DNS)

I had a look at the post you linked but I haven't tried it, yet.

1 Like

Ok, I have the same results now. I have tried changing
option proto 'tcp udp'
to

list proto 'tcp'
list proto 'udp'

like I have in other rules but it doesn't make any difference (no, this time, I used diff, not my eyes!)

Yup, I also tried asking google via IPV6 about a local domain name and I got an answer, so the queries are being correctly intercepted.

Did you solve your original problem with Netflix? In my case it seems to be working fine, when I query google for netflix I only get answers with IPV4.

@trendy funny thing happens, though:

nslookup www.netflix.com
DNS request timed out.
    timeout was 2 seconds.
Server:  UnKnown
Address:  fdcf......

DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
*** Tempo scaduto per la richiesta a UnKnown

However if I run this same query against the non-ULA IPV6 address it works just fine.
According to netstat, unbound is listening for all interfaces:

netstat -a |grep domain
tcp        0      0 0.0.0.0:domain          0.0.0.0:*               LISTEN
tcp        0      0 :::domain               :::*                    LISTEN
udp        0      0 0.0.0.0:domain          0.0.0.0:*
udp        0      0 :::domain               :::*

I can get an answer using the ULA-address on the router itself, not on the laptop (with firewall off) or on my phone. Weird.

I remember I came across something similar lately. User was complaining that Android device does not work when advertised nameserver is a ULA address.

1 Like

Oh, nice, not :smiley:

I'm still puzzled that Windows is also having trouble with that (direct nslookup) but now I see that my Debian desktop barfs, too: a dig to the ULA address returns the "reply from unexpected source" error, which you already encountered.

I have tried with this line:
ip6tables -t nat -A POSTROUTING -d <ULA-address of router> -p udp -m udp --dport 53 -m comment --comment "!fw3: Intercept-DNS - lan" -j MASQUERADE
but I still get the message: it seems the issue is the port number of the reply, the host is correct.

I guess I need a closer look at the rest of your script and account for the fact that I don't have an external DNS server. Out of curiosity, do you reckon it would be possible to express that script only through UCI?

You need the DNAT too, not just the MASQUERADE.

I am not sure how to express the redirect in UCI.

1 Like

Oh, I see, thanks.

Looks like it isn't possible :frowning:

To no one in particular: simply blocking outside DNS servers sure is a lot easier :smiley: :smiley:

It is, however you'll have some delay each time the hosts are going to reach out to them.

Thing is, I was trying to solve a problem for the fun of it, not because I had noticed this delay.
I should first log the rejections then identify the devices, if any, and only then try to do something about it.

EDIT: apparently the Android phones are not making much of a fuss, the lone attempt I have seen was from the xiaomi tv box, I can live with that

The typetransparent classification is correct (original design goal) for filtering out responses like AAAA and CNAME that cause you grief. That will force Netflix to use IP4. You can also use IPSET to load the firewall with IP6 resolved to "that domain" and block them.

Ensuring your clients only use your Unbound services on your router is different. First you need dnsmasq and odhcpd to announce the router. They may not do this right if dnsmasq isn't treated as primary. Make sure to set option dns ... to your router under UCI dhcp. Second you need to block deviant clients from going to google, quad9, and such. You can use firewall or routing rules to block, black hole, or even funnel queries to Unbound (i.e. all destination ports 53,853 from any LAN on any protocol must only go to Unbound).