You are not logged in.

#1 2019-09-02 00:39:52

SleepyMan
Member
Registered: 2013-06-22
Posts: 2

Wireguard tunnel IPv6 to IPv4

Hi all,

I've been trying to set up a VPN across my family's houses to be able to access any device in any house from anywhere. Since I want to be able to access multiple IPv4 networks from anywhere, I was naturally drawn to IPv6 to solve IPv4 exhaustion. And since Wireguard is so damn easy to setup (even with IPv6), this was my first choice.

I setup a Wireguard server with proper ip forwaring, and a Wireguard client in each house's network, and allocated a IPv6 /96 range to each house to be able to ping any device in this network (IPv4 network). I can ping each client from anywhere, like dead:1234:1::1, and upon trying to ping an IPv6 like dead:1234:1::192.168.1.10, it routes correctly to the client, thus the connection (client 1 => server => client 2) is working correctly for the allocated IPv6 range. So far, I can reach all the way to the client in another house, now the next step, and hopefully last step, is to just forward this packet to the IPv4 within this client's network (client 1 => server => client 2 => device A).

Unfortunately, to route IPv6 to IPv4 doesn't seem to be as simple as a nftable rule, which upon creating an inet table with a rule like:

iif wg ip6 daddr dead:1234:1::/96 dnat ip to 192.168.1.10

nftables complains about incompatible protocols. Sure, I would understand if I tried to translate from ICMP to IPv4, but why from IPv6 to IPv4? Sure, there are additional headers, etc., but much like NAT, it could create tables to hold on to these info.

I didn't progress further, trying to make the dnat ip dynamic, according to the ip6 daddr since not even routing to a static IP was working.

Well, I was stumped that I was not able to achieve it with a simple nftables rule, but anyway, I tried going the NAT64 route. Looking at WrapSix, Tayga, and Jool, I immediately found it rather "ugly" that I needed "another" IPv4 (possibly a pool of it), other than the one the machine already got from the DHCP server.

So, before I go the NAT64 ugliness route with multiple IPv4/IPv6, was I doing anything wrong the nftables, or is it simply impossible to route IPv6 to IPv4 on the firewall? If impossible using nftables, is the answer to this routing NAT64?

Thanks for your attention.

Offline

#2 2019-09-02 08:28:07

Omar007
Member
Registered: 2015-04-09
Posts: 332

Re: Wireguard tunnel IPv6 to IPv4

SleepyMan wrote:

Sure, I would understand if I tried to translate from ICMP to IPv4, but why from IPv6 to IPv4?

You're missing a fundamental piece of information on what/how IPv4 and IPv6 work. ICMP is just one of the parts in the layer that goes together with IPv4 or IPv6. ICMP for IPv6 (ICMPv6) even has more features than ICMP had for IPv4.
Look at it like this:
BASE (a.k.a. OSI Layer 3) = IPv4+ICMP or IPv6+ICMPv6
TRANSPORT over $BASE (a.k.a. OSI Layer 4): TCP, UDP, ...

Moving IPv4 packets over an IPv6 network or viceversa is due to fundamental design differences at the core not possible without translating/wrapping them into the other. What it sounds like you're looking for is 6in4 (there's also 4in6 for the other way around wink ).
You may be able to use the following wiki page as inspiration for the configuration; https://wiki.archlinux.org/index.php/IP … oker_setup

EDIT: In your case I'd suspect you'd want to manage the tunnel yourself though since you're not really using it to access the IPv6 internet (which would normally be the use for a 3rd-party broker).
For your own networks you maybe have to look into IPsec+IKEv2 to set it all up (iirc IKEv2 can do IPv6). I'm afraid we have no wiki page for that (the best we have on the subject is on the StrongSwan software I think; https://wiki.archlinux.org/index.php/StrongSwan) so you'll have to do some searching online on this subject instead.

EDIT2: I'm reading that, in theory, you should also be able to set up WireGuard for 6in4 (so no need to switch VPN tooling in that case) but with just a few minutes of searching it's not immediately clear to me how, so I can't help you there.

Last edited by Omar007 (2019-09-02 09:03:53)

Offline

#3 2019-09-03 15:03:20

SleepyMan
Member
Registered: 2013-06-22
Posts: 2

Re: Wireguard tunnel IPv6 to IPv4

Hi Omar007,

Thanks for the reply, but I just can't understand why nftables' NAT (network address TRANSLATION) can't translate between the two. It feels like they just didn't care to update NAT to support IPv6 from IPv4, since one of the strong points of IPv6 is the abundance of addresses which makes NAT moot.

Sorry for rambling. I looked into 6in4 before, which apparently is to allow IPv4 clients to access IPv6 servers, within a specially configured IPv4 network. So I probably want 4in6, since I have my IPv6 client that I want to access an IPv4 device through an IPv6/IPv4 server (me (Wireguard IPv6) => main wireguard server (IPv6) => home server (Wireguard IPv6 and router IPv4) => device (router IPv4)). So to my understanding, I'm sending IPv4 packets in an IPv6 network (Wireguard network).

I looked into the kernel to find it supports 4in6 tunnels. OK, but not what I want, since I need to setup a tunnel for each of my servers both in the client (me) and in the server (home server) and have a dedicated IPv6 range for each tunnel:

me => wireguard server => home server A => device A
me => wireguard server => home server B => device B
me => wireguard server => home server C => device C

and so on

I wanted the server to translate them automatically without setting up tunnels, etc, like normal routing/forwarding. I wanted to use my prefix to translate, since dead:1234:1::/96 is already routed to the home server correctly, and I do not want my client (me) to have hundreds of tunnels with hundreds of IPv6 assigned.

dead:1234:a::192.168.1.10  =>  wireguard server => home server A => 192.168.1.10
dead:1234:a::192.168.1.20  =>  wireguard server => home server A => 192.168.1.20
dead:1234:b::192.168.1.10  =>  wireguard server => home server B => 192.168.1.10
dead:1234:b::192.168.1.20  =>  wireguard server => home server B => 192.168.1.20

Am I missing something if I wanted to have that?

EDIT2: I'm reading that, in theory, you should also be able to set up WireGuard for 6in4 (so no need to switch VPN tooling in that case) but with just a few minutes of searching it's not immediately clear to me how, so I can't help you there.

This seems to be what I want (if WireGuard would handle the translation without setting up tunnels with new IP's). It seems I would need to have Wireguard itself handle the 6in4, as the kernel doesn't seem to allow a tunnel to work in 2 modes at the same time, thus not making us use the already available code in kernel and having to duplicate the code in WireGuard. This doesn't seem to be right.

Any thoughts?

Offline

#4 2019-09-03 15:44:44

Omar007
Member
Registered: 2015-04-09
Posts: 332

Re: Wireguard tunnel IPv6 to IPv4

SleepyMan wrote:

NAT (network address TRANSLATION) can't translate between the two. It feels like they just didn't care to update NAT to support IPv6 from IPv4, since one of the strong points of IPv6 is the abundance of addresses which makes NAT moot.

Emphasis here in NAT is on NETWORK ADDRESS, not translation. NAT translates network addresses, not network protocols.
NAT can theoretically be done with IPv6 perfectly fine (dubbed NAT66, but don't ever use this. Please, be sane and spare us all) and it is indeed pointless due to the massive range of addresses that are available.
(numerous years ago there was a thing called NAT-PT (NAT-Protocol Translation) which theoretically could do protocol translations but it had too many severe issues so it was dropped/deprecated over 10 years ago).

SleepyMan wrote:

I looked into 6in4 before, which apparently is to allow IPv4 clients to access IPv6 servers, within a specially configured IPv4 network.

No it's not. 6in4 allows machines to talk with each other using IPv6 over an IPv4 network. IPv6 is wrapped into IPv4 packets to cross the IPv4 network then unwrapped at the other end before forwarding it to the destination. Both source and destination are IPv6.

SleepyMan wrote:

So I probably want 4in6, since I have my IPv6 client that I want to access an IPv4 device through an IPv6/IPv4 server (me (Wireguard IPv6) => main wireguard server (IPv6) => home server (Wireguard IPv6 and router IPv4) => device (router IPv4)). So to my understanding, I'm sending IPv4 packets in an IPv6 network (Wireguard network).

4in6 is not what you want either. This is the reverse of 6in4. It would allow machines to talk with each other using IPv4 over an IPv6 network. Instead wrapping IPv4 into IPv6 and unwrapping it at the other end before forwarding it to the destination. Both source and destination are IPv4 in this case.

Neither 6in4 or 4in6 change protocols. Both of those assume that both ends of the connection use the same protocol. A tunnel is set up between the two to cross an incompatible network by wrapping it but no translation/conversion ever happens.
If you really want to change protocols (IPv6 connecting to IPv4), you'll need NAT64. No way around that. Please note that with NAT64, the other way around is still impossible (IPv4 connecting to IPv6).

SleepyMan wrote:

I wanted the server to translate them automatically without setting up tunnels, etc, like normal routing/forwarding. I wanted to use my prefix to translate, since dead:1234:1::/96 is already routed to the home server correctly, and I do not want my client (me) to have hundreds of tunnels with hundreds of IPv6 assigned.

This is a technical impossibility. You can't route across protocols. That'd be like trying to send a physical mail and jamming it into a copper wire and hoping it ends up as an e-mail in the mailbox of the target. You need to do a protocol translation/conversion somewhere (mail to e-mail in this analogy).

SleepyMan wrote:

This seems to be what I want (if WireGuard would handle the translation without setting up tunnels with new IP's). It seems I would need to have Wireguard itself handle the 6in4, as the kernel doesn't seem to allow a tunnel to work in 2 modes at the same time, thus not making us use the already available code in kernel and having to duplicate the code in WireGuard. This doesn't seem to be right.

WireGuard would not do any protocol translation/conversion, it would just provide the tunnel. That makes it possible for all machines to have an IPv6 address, allowing you to connect them all together using IPv6 and stick to 1 protocol.

My WireGuard knowledge is very limited sadly so I can't really say much about how to set this up, but if in your earlier setup (client1 <-> server <-> client2 <-> device A), just make sure that any device connected to the client is assigned an IPv6 address from the same prefix as the client.
The client would have to 'advertise' the prefix it receives from the server into the network. Look into prefix delegation.

Your setup would then become something like this:
client1(ipv6) <-(wg tunnel)-> (ipv6)server(ipv6) <-(wg tunnel)-> client2(ipv6 (& ipv4)) <-ipv6-> deviceA(ipv6 (& ipv4))

Assuming client1 and client2 are the WireGuard clients that receive an IPv6 prefix/address from server, server the WireGuard host is with the prefix config for the clients and that client2 shares this prefix using prefix delegation into its network.
This of course also requires that all the devices connected to client2, that you also want to actually access, are IPv6 capable!
If that is not the case, I'd suggest to just use IPv4 for your internal communications. If you want to use the same range on all devices, regardless on what side of the VPN connection they are, just use the 10.0.0.0/8 range that is reserved for private use. That gives you 16777216 addresses to work with.


If you really want to do cross-protocol connections, you will not get around to setting up NAT64 for that. And that still would only solve the problem one way.


EDIT: punctuation, clarified a few points and added (& ipv4) to the setup expectation when using delegation to indicate that the devices would technically also still have their existing ipv4 but that the connections in this case would all happen with ipv6; <-ipv6->

Last edited by Omar007 (2019-09-03 16:48:10)

Offline

#5 2019-09-04 00:31:56

fukawi2
Administrator
From: .vic.au
Registered: 2007-09-28
Posts: 5,733
Website

Re: Wireguard tunnel IPv6 to IPv4

SleepyMan wrote:

nftables complains about incompatible protocols. Sure, I would understand if I tried to translate from ICMP to IPv4, but why from IPv6 to IPv4? Sure, there are additional headers, etc., but much like NAT, it could create tables to hold on to these info.

One of those headers is the source address. DNAT only changes the Destination Address - it doesn't make sense to send a packet to an IPv4 address with an IPv6 source address; how would the recipient be expected to reply? On top of that, the "source address" field in an IPv4 header is offset by 96 bits, whereas it's at the 64-bit offset in an IPv6 header so the IPv4 recipient wouldn't be able to make sense of the header at all if all you did was rewrite the destination address. (Ignoring that the first 4 bits of the header specify the IP version, which an IPv4 client would ignore a packet identified as Version 6).

So pretty much the whole header needs to be rewritten so the IPv4 destination can make sense of it - not what DNAT does, and where NAT64 comes in.

Offline

Board footer

Powered by FluxBB