IPv6 Issues (DNS Resolution & OpenVPN) [tunX dual stack]

I enabled IPv6 on my ISP's modem and am struggling to configure it correctly.

The first thing I notice is that my ISP's modem/router is providing my OpenWRT with (if I'm reading this correctly) a /60 range to divide among the clients. So all clients have their own public IP. Which is fine, I suppose.

Next, I was trying to configure my OpenVPN to use IPv6 and I came across a resolver-issue. Whenever I do a nslookup on a hostname that has an IPv4 but not an IPv6 address, it errors out on the DNS6 lookup. Taking a VPN server I'm testing for example:

nslookup nl3.vpn.airdns.org
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:      nl3.vpn.airdns.org
Address 1: 134.19.179.197
*** Can't find nl3.vpn.airdns.org: No answer

Which is fine as well, I suppose. Maybe it does two lookups, one for A and one for AAAA.

But, if I use that same hostname in the OpenVPN config with protocol UDP6, it errors out:

RESOLVE: Cannot resolve host address: nl3.vpn.airdns.org:443 (Name does not resolve)

Using UDP4 it works just fine.

At first I figured maybe it was a bug in OpenVPN, but on my Windows Client it works just fine. Although it is a mystery to me how he starts out resolving an IPv4 address and ends up connecting to an IPv6 server.

So something is going wrong somewhere.


Next, after setting a static IPv6 address to get connected, then going to ipleak.net I notice that my IPv4 traffic is coming out at the tunnel, but my IPv6 traffic is still happily using my own PC's own IPv6 address and bypassing the tunnel. First it used Window's own Temporary IPv6Address that it came up with all by itself. Once disabled, it used it given address.

Is that because it is a public address? That it bypasses the tunnel?

I set network.wan6.reqprefix='no' to see what that would do. Windows still generate the public IP for itself, but it stops communicating over IPv6 to the Internet altogether.

Maybe that is a routing issue?

One thing I notice is that the VPN server pushes an IPv4 address, but not an IPv6 address, even though it has one for the client. From its overview I can see both internal and external IPv4 and IPv6 addresses. Maybe that's why it no longer communicates over IPv6? Because OpenVPN doesn't know it has an IPv6 address?

The whole thing has weird errors...

openvpn(airvpn)[6400]: PUSH: Received control message: 'PUSH_REPLY,comp-lzo no,redirect-gateway  def1 bypass-dhcp,dhcp-option DNS 10.33.234.1,route-gateway 10.33.234.1,topology subnet,ping 10,ping-restart 60,ifconfig 10.33.234.148 255.255.255.0,peer-id 2,cipher AES-256-GCM'
/sbin/ifconfig tun0 10.33.234.148 netmask 255.255.255.0 mtu 1500 broadcast 10.33.234.255
dnsmasq[6686]: using nameserver 10.33.234.1#53
openvpn(airvpn)[6400]: write UDPv6: Permission denied (code=13)
openvpn(airvpn)[6400]: TLS Error: local/remote TLS keys are out of sync: [AF_INET6]2a00:1688:2460:1110:c505:13fd:8827:ea57:443 [5]
openvpn(airvpn)[6400]: [Gobbels] Inactivity timeout (--ping-restart), restarting

Maybe the VPN server had a hiccup there. It reconnected just fine. I'll check if they come again.

I'm a bit lost here. Either way, I think I am missing some kind of configuration for IPv6 on OpenWRT that makes for good routing. I check the user guide, but most of the IPv6 articles are before IPv6 was part of the default install.

Correct, the "No answer" is about AAAA record.

By default OpenWrt uses source routing in IPv6. Hence the traffic sourcing from the public IPv6 allocated by your ISP will go through your ISP. Even if it did go through the tunnel, the internet would not route it back via the VPN, but via your ISP. Chances are the VPN would drop it anyway due to spoofed source address.

However to ip version that you will use to connect to the VPN shouldn't matter anyway. What matters is which ip version the VPN is offering for you to use.

1 Like

According to the VPN provider's page:
Your VPN IPv6: fde6:7a:7d20 etc etc

I have an internal IPv4 and IPv6 and an external one. But it appears OpenVPN only knows about the IPv4, or I'm not seeing it. Nor do I see the IPv6 DNS server that should be there.

What I want is for my traffic to route through the tunnel, just like IPv4 is doing.

I can choose whether I wish to connect to the VPN server using IPv4 or IPv6. If the latter, I get both addresses. I can also choose if I want to have an IPv4 and/or IPv6 exit, where the end of the tunnel also gets those addresses.

So right now I am connected using a static IPv6 address, because OpenVPN won't resolve the DDNS hostname to an IPv6 server if I choose to connect using IPv6.

To be clear, I should keep network.wan6.reqprefix at no to prevent my clients from getting a routable IPv6 address and force them to instead use the ULA assigned by OpenWRT?

I am not sure why they allocated just one IPv6, but anyway.
First of all post here the following:
uci export network; uci export dhcp; ip -6 addr; ip -6 ru; ip -6 ro
Cover sensitive date like user/pass/keys and slightly change the IP addresses if they are public.

config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fda9:6d75:b7b6::/48'

config interface 'lan'
        option type 'bridge'
        option ifname 'eth0.1'
        option proto 'static'
        option netmask '255.255.255.0'
        option ip6assign '60'
        option ipaddr '172.16.17.23'

config interface 'wan'
        option ifname 'eth1.2'
        option proto 'dhcp'

config interface 'wan6'
        option ifname 'eth1.2'
        option proto 'dhcpv6'
        option reqaddress 'try'
        option reqprefix 'no'

config switch
        option name 'switch0'
        option reset '1'
        option enable_vlan '1'

config switch_vlan
        option device 'switch0'
        option vlan '1'
        option ports '0 1 2 3 5t'

config switch_vlan
        option device 'switch0'
        option vlan '2'
        option ports '4 6t'

config interface 'vpn'
        option proto 'none'
        option ifname 'tun0'
config dnsmasq 'dnsmasq'
        option domainneeded '1'
        option boguspriv '1'
        option filterwin2k '0'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option expandhosts '1'
        option nonegcache '0'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option nonwildcard '1'
        option localservice '1'
        option local '/domain.local/'
        option domain 'domain.local'
        list server '/ad.domain.local/172.16.17.18'
        list rebind_domain '/ad.domain.local/'
        option confdir '/tmp/dnsmasq.d'
        option resolvfile '/tmp/resolv.conf.vpn'

config dhcp 'lan'
        option interface 'lan'
        option leasetime '12h'
        option dhcpv6 'server'
        option ra 'server'
        option start '101'
        option limit '50'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'

config odhcpd 'odhcpd'
        option maindhcp '0'
        option leasefile '/tmp/hosts/odhcpd'
        option leasetrigger '/usr/sbin/odhcpd-update'
        option loglevel '4'
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 532
    inet6 fe80::6238:e0ff:feda:5316/64 scope link
       valid_lft forever preferred_lft forever
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 532
    inet6 fe80::6038:e0ff:feda:5316/64 scope link
       valid_lft forever preferred_lft forever
7: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fda9:6d65:b7b6::1/60 scope global noprefixroute
       valid_lft forever preferred_lft forever
    inet6 fe80::6038:e0ff:feda:5316/64 scope link
       valid_lft forever preferred_lft forever
9: eth1.2@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 2001:1c00:f14:fe00:6238:e0ff:feda:5326/64 scope global dynamic noprefixroute
       valid_lft 42158sec preferred_lft 13358sec
    inet6 2001:1c00:f14:fe00:9b10:e71d:7176:c2ad/128 scope global dynamic noprefixroute
       valid_lft 52896sec preferred_lft 24096sec
    inet6 fe80::6238:e0ff:feda:5316/64 scope link
       valid_lft forever preferred_lft forever
10: wlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fe80::6038:e0ff:feda:5317/64 scope link
       valid_lft forever preferred_lft forever
11: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fe80::6038:e0ff:feda:5318/64 scope link
       valid_lft forever preferred_lft forever
12: wlan1-1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fe80::225:9cff:fe14:2895/64 scope link
       valid_lft forever preferred_lft forever
0:      from all lookup local
32766:  from all lookup main
4200000001:     from all iif lo failed_policy
4200000007:     from all iif br-lan failed_policy
4200000009:     from all iif eth1.2 failed_policy
4200000009:     from all iif eth1.2 failed_policy
default from 2001:1c00:f14:fe00:9b10:e71d:7176:c2ad via fe80::ae22:5ff:fe50:6cc0 dev eth1.2 proto static metric 384 pref medium
default from 2001:1c00:f14:fe00::/64 via fe80::ae22:5ff:fe50:6cc0 dev eth1.2 proto static metric 384 pref medium
2001:1c00:f14:fe00::/64 dev eth1.2 proto static metric 256 pref medium
2001:1c00:f14:fe00::/64 via fe80::ae22:5ff:fe50:6cc0 dev eth1.2 proto static metric 512 pref medium
fda9:6d65:b7b6::/64 dev br-lan proto static metric 1024 pref medium
unreachable fda9:6d65:b8b6::/48 dev lo proto static metric 2147483647 error 4294967183 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev eth1 proto kernel metric 256 pref medium
fe80::/64 dev eth1.2 proto kernel metric 256 pref medium
fe80::/64 dev br-lan proto kernel metric 256 pref medium
fe80::/64 dev wlan0 proto kernel metric 256 pref medium
fe80::/64 dev wlan1 proto kernel metric 256 pref medium
fe80::/64 dev wlan1-1 proto kernel metric 256 pref medium

Just want to say that slightly changing IPv6 addresses is a nightmare. :slightly_smiling_face:

he last few are without the OpenVPN tunnel. It seems that it won't start on boot right now, I'll have to test to see why. It starts just find if I click on Start.

If I not give out the public range provided by the ISP (option reqprefix 'no'), my clients no longer seem to be routed to the Internet by IPv6. So it seems anyway. I guess it's not doing IPv6 NAT or routing or whatever is needed.

I don't see any ipv6 in tun, so I guess they don't allocate you any.
One solution is not to request for prefix, as you mentioned. Or disable wan6 on boot. Another is to disable the ip6assign in lan interface.

Well, I brought the tunnel up...

Removing the ones already present above:

13: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 state UNKNOWN qlen 100
    inet6 fe80::ad73:f47f:2b80:7d49/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

4200000013:     from all iif tun0 failed_policy

fe80::/64 dev tun0 proto kernel metric 256 pref medium

fe80 is link local, consider it doesn't exist for your case.

And yet, according to the provider, it should have Your VPN IPv6: fde6:7a: etc etc

Somehow, OpenVPN is supposed to get it. If it is not pushed, is OpenVPN supposed to ask for it?

On my Windows-OpenVPN it does get pushed. By the same server even. It pushes both an ifconfig for the IPv6 and a DNS6 option.

EDIT: I just copied the vpn provider's conf file over to the OpenWRT and execute it manually from the CLI: openvpn --cd /etc/openvpn --config /etc/openvpn/AirVPN.conf

Lo and behold:

PUSH: Received control message: 'PUSH_REPLY,comp-lzo no,redirect-gateway ipv6 def1 bypass-dhcp,dhcp-option DNS 10.7.148.1,dhcp-option DNS6 fde6:7a:7d20:38e::1,tun-ipv6,route-gateway 10.7.148.1,topology subnet,ping 10,ping-restart 60,ifconfig-ipv6 fde6:7a:7d20:38e::1054/64 fde6:7a:7d20:38e::1,ifconfig 10.7.148.86 255.255.255.0,peer-id 4,cipher AES-256-GCM'

GDG6: remote_host_ipv6=2a00:1678:2460:29:1636:4986:4c28:ca88
GDG6: NLMSG_ERROR: error Permission denied

ROUTE6: 2000::/4 overlaps IPv6 remote 2a00:1678:2460:29:1636:4986:4c28:ca88, adding host route to VPN endpoint
ROUTE6: IPv6 route overlaps with IPv6 remote address, but could not determine IPv6 gateway address + interface, expect failure

/sbin/ifconfig tun0 10.7.148.86 netmask 255.255.255.0 mtu 1500 broadcast 10.7.148.255
/sbin/ifconfig tun0 add fde6:7a:7d20:38e::1054/64
/sbin/route add -net 0.0.0.0 netmask 128.0.0.0 gw 10.7.148.1
/sbin/route add -net 128.0.0.0 netmask 128.0.0.0 gw 10.7.148.1
add_route_ipv6(::/3 -> fde6:7a:7d20:38e::1 metric -1) dev tun0
/sbin/route -A inet6 add ::/3 dev tun0
add_route_ipv6(2000::/4 -> fde6:7a:7d20:38e::1 metric -1) dev tun0
/sbin/route -A inet6 add 2000::/4 dev tun0
add_route_ipv6(3000::/4 -> fde6:7a:7d20:38e::1 metric -1) dev tun0
/sbin/route -A inet6 add 3000::/4 dev tun0
add_route_ipv6(fc00::/7 -> fde6:7a:7d20:38e::1 metric -1) dev tun0
/sbin/route -A inet6 add fc00::/7 dev tun0
Initialization Sequence Completed

This push is a lot bigger. But since I copied the conf file option-by-option to uci, it should - in theory - respond the same. Unless OpenWRT is neglecting to pass some of the options through to OpenVPN. I will investigate some more.

Can somebody explain those 2 errors?

So, I checked. Literally did a cat /etc/openvpn/AirVPN.conf and translated each of those options to UCI format. No IPv6 push. So, I am going to create a bug report for the maintainers of the openvpn-openssl package. Part of the config is not getting pushed to OpenVPN. My guess is the setenv 'UV_IPV6 yes' since it is the only one that explicitly states IPv6.

First, I'll try and create a UCI config that refers to the config file though. It's not my preferred way, but if it works, at least I am yet another step closer to being back online and one step further away from yet another sleepless night figuring stuff out that should have just worked....

This is NUTS!

I completely removed both the openvpn package and config from my system, but as soon as I install the package, openvpn starts again on boot with a config that doesn't even exist anymore. I can't set any config active because he will always start this one first.

What is going on with this thing?!

the way it has been implemented is similar to;

  • use traditional ( daemon general ) init... so if you have an .ovpn in /etc/openvpn/XYZ a starting daemon will fire that up.
  • !if! there is a uci reference to that config... ( /etc/confg/openvpn -> "connection" -> enabled=1 ) then use that to either enable or disable the specific connection.

So,

  • when you uninstalled... because your /etc/openvpn/XYZ.ovpn was not part of the original package install, it left it there... ( remove and ls -lah /etc/openvpn/
    to verify this behavior )
  • when you re-installed... it created a new /etc/config/openvpn ( uci config ) which has no reference to that .ovpn so it defaulted to the native daemon behavior.

( another thing is that files in /etc/openvpn/ named .conf VS .ovpn are treated differently... but the meaning escapes me right now )

If I recall correctly, one of them gets imported upon being loaded. Something like that.

Well since I couldn't get rid of it I just did a reset to defaults. My config is stored in a uci-script anyways.

At this point, avoiding previously made mistakes, it still won't route correctly:

cat /tmp/resolv.conf.vpn
nameserver 10.7.158.1
nameserver fde6:7a:7d20:38e::1

ping6 fde6:7a:7d20:38e::1
PING fde6:7a:7d20:38e::1 (fde6:7a:7d20:38e::1): 56 data bytes
--- fde6:7a:7d20:38e::1 ping statistics ---
6 packets transmitted, 0 packets received, 100% packet loss

ip -6 addr; ip -6 ru; ip -6 ro
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 532
    inet6 fe80::6288:e0ff:feda:5316/64 scope link
       valid_lft forever preferred_lft forever
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 532
    inet6 fe80::6088:e0ff:feda:5316/64 scope link
       valid_lft forever preferred_lft forever
7: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fd30:89fc:4487::1/60 scope global noprefixroute
       valid_lft forever preferred_lft forever
    inet6 fe80::6088:e0ff:feda:5316/64 scope link
       valid_lft forever preferred_lft forever
9: eth1.2@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 2001:1c00:f24:fe00:6288:e0ff:feda:5316/64 scope global dynamic noprefixroute
       valid_lft 47418sec preferred_lft 18618sec
    inet6 2001:1c00:f24:fe00:8b10:e71d:7176:c6ad/128 scope global dynamic noprefixroute
       valid_lft 52880sec preferred_lft 24080sec
    inet6 fe80::6288:e0ff:feda:5316/64 scope link
       valid_lft forever preferred_lft forever
10: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 state UNKNOWN qlen 100
    inet6 fde6:7a:7d20:38e::1054/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::8c85:c6e1:3990:5c8d/64 scope link stable-privacy
       valid_lft forever preferred_lft forever
0:      from all lookup local
32766:  from all lookup main
4200000001:     from all iif lo failed_policy
4200000007:     from all iif br-lan failed_policy
4200000009:     from all iif eth1.2 failed_policy
4200000009:     from all iif eth1.2 failed_policy
default from 2001:1c00:f24:fe00:8b10:e71d:7176:c6ad via fe80::ae22:5ff:fe50:6cc0 dev eth1.2 proto static metric 384 pref medium
default from 2001:1c00:f24:fe00::/64 via fe80::ae22:5ff:fe50:6cc0 dev eth1.2 proto static metric 384 pref medium
::/3 dev tun0 metric 1 pref medium
2001:1c00:f24:fe00::/64 dev eth1.2 proto static metric 256 pref medium
2001:1c00:f24:fe00::/64 via fe80::ae22:5ff:fe50:6cc0 dev eth1.2 proto static metric 512 pref medium
2000::/4 dev tun0 metric 1 pref medium
3000::/4 dev tun0 metric 1 pref medium
fd30:89fc:44e7::/64 dev br-lan proto static metric 1024 pref medium
unreachable fd30:89fc:44e7::/48 dev lo proto static metric 2147483647 error 4294967183 pref medium
fde6:7a:7d20:38e::/64 dev tun0 proto kernel metric 256 pref medium
fc00::/7 dev tun0 metric 1 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev eth1 proto kernel metric 256 pref medium
fe80::/64 dev eth1.2 proto kernel metric 256 pref medium
fe80::/64 dev br-lan proto kernel metric 256 pref medium
fe80::/64 dev tun0 proto kernel metric 256 pref medium

EDIT: Could something to do with the public ipv6 gateway endpoint setting ( tunnel outside )

or

Do you have a vpnfirewall stanza in /etc/config/firewall... that is set to masq=1?

Would you be really upset and refuse to help any further if I told you that after working on this for 13 hours straight and being extremely frustrated at what is now almost 6 in the morning... I forgot to add the TUN-interface and associated firewall rules?

I have now set the vpn over IPv4 using a static IP address without passing me any IPv6 information. I am going to slowly, very slowly re-add IPv6.

By the way, that error has been appearing since the start. I have no clue what it means...

I wouldn't stress too much at this point... there is enough info for a guru to spot what is going on... so take a break me thinks... give it a day or two for learnered eyes to spot the glitch.

( there are known working ipv6(only) configs... but i'm not sure about dual stack... )

This one keeps popping up too:
odhcpd[1596]: A default route is present but there is no public prefix on lan thus we don't announce a default route!

Oh, and as soon as I tell the VPN server to give me an IPv6 address, it stops working. So I can build an IPv6 tunnel just fine, but I can't have an IPv6 address at the end of that tunnel, it will stop all form of routing.

I also tried vpn-policy-routing with IPv6 support enabled. But nothing seems to work.

I really hope somebody can help out. It shouldn't be this hard to get this working.

I have not used IPv6 over OpenVPN tunnel like this, but I can spot a few things.

  1. You are still getting IPv6 from your provider and the default route you receive from VPN overlaps with that. It might be nothing, but if you decide to use only VPN for IPv6, you could disable wan6 in total.
  2. In principal default gateway will not be advertised if there is no public prefix. The error from odhcpd can be bypassed by instructing to always announce the default route (under lan interface, dhcp server tab, ipv6 settings)

@trendy
My ISP Hands out a public /64 range to its clients. OpenWRT by default requests a /60 block to hand out to its clients. As a matter of fact, I can't even disable the modem's DHCP6 server. I could - in theory - change the range my modem hands out into a private range, much like how it hands out a 192.168 address to OpenWRT. I have no idea what that would do to Internet connectivity though.

I would think that the scenario where an Internet-facing OpenWRT has a publicly routable IP but still would like to route certain traffic over the VPN tunnel is not uncommon and can be made to work.

If I disable WAN6, I would get no more IPv6 address, which would prevent me from establishing an IPv6 tunnel to my VPN provider. The reason why I got a new modem was to get an IPv6 address from my ISP and take advantage of it to build an IPv6 tunnel.

So the fact that the tunnel is pushing routes for 2000 and 3000 is causing a conflict then because my OpenWRT is 2001? Of course, there's little to do about the fe80's everywhere.

@anon50098793
My body took your advice a little too literally. I was so stressed out at that point I slept for almost 24 hours straight. I feel very weak right now.

Correction, I'm not allowed to set an fd-range on my ISP's modem. Guess I am stuck with the public IPv6 addresses. So how do I work around that? There has to be a way, right?