Ipv6 ULA acess between two subnets over wireguard with DNS name

Hi all,

this question is mostly in regards to best practices. I do have two sites (as in ipv6 site). Each has an OpenWrt router as it's wan up link. Both have there own ipv6 ULA subnet (call them s1 and s2 for not writing out ipv6 addresses). And I have a wireguard tunnel between them.

Now I want to access a client (c1) in s1 via the wireguard tunnel from client (c2) in s2 by DNS name. I configured everything so that nslookup on c2 for c1.domain gets

  • ipv4
  • ipv6 ULA
  • ipv6 GUA

address. When I now do a ping c1.domain on c2 what happens is that the c1 is pinged by its GUA address over the internet. That is not what I was expecting at first but kind of makes sense. But what I want to do is ssh into c1 (its OpenWirt device) which of cause does not work and in general I would prefer any communication over the encrypted tunnel.

From what I understand RFC6724 says ULAs like fdxx:: are always preferred over GUAs 2003::. What I can Imagine is that since both ULA subsets are different the GUA is chosen instead? Pleas correct me if I am wrong.

The c2 device is a Arch Linux machine. I had a quick look at /etc/gai.conf but it didn't work for me (maybe miss configured). But anyway I would prefer if my s2 OpenWrt device could somehow advertise the subnet or anything else so I don't need to configure clients?

Btw. the s2 Router can ping everything in s1 correctly by DNS name. Strangely that router can also ping c1 ipv4 address directly but c2 can't. Checking by ip command on the router I get the following.

> ip route get from c2 to c1
RTNETLINK answers: Network unreachable

Does anyone know why that is?. Anyway the solution to that would only be the cherry on top since I would be completely happy with working ipv6 ULAs

1 Like
# @c2
grep -e ^hosts: /etc/nsswitch.conf
getent hosts c1.domain
resolvectl query c1.domain
ip route get c1_ula
ping c1_ula
tracepath c1_ula
+=tun6
+=ula

The client should most likely have an explicit route to the server ULA subnet:

ip -6 route show table all

Otherwise, it may not be different from GUA.

What are the wireguard configs at each site (including peer configs)?

1 Like

sorry for missing out on the /etc/config/network configuration. Configs are greatly reduced to the information I felt like being related to the issue at hand.
I add wg indicating ipv6 subnet where only the wireguard interfaces live in. And I tried to consistently mask the ipv4 subnets with the same letters.

I am not with my c2 machine for the next two days so the the first check @vgaetera proposed I can not do right now.

s1 router:

config globals 'globals'                  
        option ula_prefix 's1/60'

config interface 'lan'                                                   
        option type 'bridge'            
        option proto 'static'                                           
        option netmask '255.255.255.0'  
        option ifname 'bat0.1 eth0.1' # c1 is another openwrt batman-adv mesh node
        option ip6assign '64'                                              
        option ip6hint '0'                                               
        option ipaddr 'y.y.y.y'

config interface 'wg0'                                                   
        option proto 'wireguard'       
        option private_key 'xxx'
        option listen_port 'xxx'        
        list addresses 'y.y.y.y/24'      
        list addresses 'wg_v4.2/24'  
        list addresses 'wg::2/64'  

config wireguard_wg0                                                    
        option description 's2'                                          
        option public_key 'xxx'   
        option preshared_key 'xxx'
        option endpoint_host 'external.dns'
        option endpoint_port 'xxx'                                    
        option route_allowed_ips '1'                                    
        list allowed_ips 'z.z.z.z/24'                                     
        list allowed_ips 'wg::1/128'  
        list allowed_ips 'wg_v4.1/24'                                   
        list allowed_ips 's2/64' 

s2 router:

config globals 'globals'
        option ula_prefix 's2/60'

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

config interface 'metrics'                
        option proto 'wireguard'        
        option private_key 'xxx'
        option listen_port 'xxx'    
        list addresses 'wg::1/64' 
        list addresses 'wg_v4.1/24'  

config wireguard_metrics            
        option description 'fewo'                                        
        option public_key 'xxx'
        option preshared_key 'xxx'
        option endpoint_port 'xxx'                              
        option endpoint_host 'other.external.dns'   
        option route_allowed_ips '1'                
        list allowed_ips 'y.y.y.y/24'                                  
        list allowed_ips 's1/56'                 
        list allowed_ips 'wg_v4.2/32'                        
        list allowed_ips 'wg::2/128'

so again correct me if I am wrong...

that I have done I think

@vgaetera what do you mean by that? If it is just configuring wireguard interfaces with ipv6 addresses then I would have done this as well (I am realizing how bad of a mistake it was to skip the config for this question)

If so that might be the problem since I can not imagine how c2 would now about that subnet (I was expecting the packets would go to the default gateway and that router decide where to hop next but when I think about it now that would be quite stupid for ipv6...)
What brings me back to the question... is there an option to make openwrt (or odhcpd) announce additional subnets?

1 Like

Note that you should change this to /32 if you have more than one peer section on the same interface.
The allowed IPs should not overlap with the other peers.

This does not look right if those subnets are the same.

Thanks @vgaetera for all the input.

Sorry for that. Your are right and I messed up. The lan and and the wg0 subnets are supposed to be on different devices

I was thinking the definition of the subnet like I did helps by creating routing rules to correctly capture all packets directed to this subnet by the wireguard interface. I think I had issues when using /32 but I will try again.

The part about each interface having ipv6 and ipv4 addresses....
I did that and in fact If I explicitly ping an address then routing works fine. It really is more the DNS issue here. For example if I do ssh c1.domain then it fails because the ipv6 GUA is choosen. But ssh -4 c1.domain works because the local ipv4 will be used. ssh c1-ULA works as well because there is no choice to made and routing works.

The interesting thing here is that when I want to ssh into the s1 router (the OpenWrt device with the wireguard interface that is) by name it works perfectly fine with the correct ipv6 ULA (same ipv6 subnet as c1 uses).

It seems working:
https://openwrt.org/docs/guide-user/services/vpn/wireguard/extras#ipv6_site-to-site

Merged the code to the wiki.

1 Like

If you're doing just a site to site VPN you're not gaining anything from giving the wireguard interface a separate subnet. In config interface 'wg0' you can safely delete

list addresses 'y.y.y.y/24'      
list addresses 'wg_v4.2/24'  
list addresses 'wg::2/64' 

and in config interface 'metrics' you can delete

list addresses 'wg::1/64' 
list addresses 'wg_v4.1/24'

The corresponding allowed_ips entries in each peer can also be removed.

With regard to DNS, is it selecting the GUA only when going between sites? Can you not route the GUA subnet over wireguard?

@vgaetera Just so that I understand correctly. You are proposing to have both lan networks in the same /48 subnet but different /64 subnets. And in terms of wireguard route the complete /48 over the tunnel?
So that should work since the local /64 networks have precedents over the remote /48 nets. But I don't see how this is different from my current setup. Well okay... currently they are not both in the same /48 subnet but it is not clear to me how that would fix the issue with which ip address is chosen from the dns query?

@krazeh I agree with you but it so happens that there are more wireguard peers and it works well for me to have a separate subnet for the interfaces to be in.

regarding dns:

# on c2
:~$ nslookup c1.domain
Server:         r1
Address:        r1#53

Name:   c1.domain
Address: ipv4
Name:   c1.domain
Address: ULA
Name:   c1.domain
Address: GUA

The GUA is chosen pretty much always except when pinging r1.domain. But the thing I just yet noticed... r1.does have an additional guest network which is the one which gets chosen. Even more strangely the dns query returns no GUA

# on c2
~$ nslookup r1.domain
Server:         r1
Address:        r1#53

Name:   r1.domain
Address: ipv4.lan
Name:   r1.domain
Address: ipv4.guest
Name:   r1.domain
Address: ULA.guest
Name:   r1.domain
Address: ULA.lan

The issue becomes more interesting then I thirst thought^^
dns configs for you if you are interested.

on r1

config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option expandhosts '1'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.auto'
        option localservice '1'
        option cachesize '500'
        option local '/fewo/'
        option domain 'fewo'
        list server '/tlan/r1'

config dhcp 'lan'
        option interface 'lan'
        option start '200'
        option limit '50'
        option leasetime '14d'
        option dhcpv6 'server'
        option ra 'server'
        option ra_management '1'

on r2

config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option expandhosts '1'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.auto'
        option localservice '0' # 1
        option cachesize '400'
        option local '/tlan/'
        option domain 'tlan'
        list rebind_domain 'fewo'
        list server '/fewo/r2'

config dhcp 'lan'
        option interface 'lan'
        option limit '150'
        option start '10'
        option leasetime '30d'
        option ra 'server'
        option dhcpv6 'server'

Your clients have no route to the other site's ULA.
That method makes odhcpd announce the route to /48 while issuing /64.

1 Like

well...
it took me a while to try it out but it worked exactly as @vgaetera said. So yea... not much more to say otherthan thank you !

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.