Skip to content

Instantly share code, notes, and snippets.

@MartinBrugnara
Last active March 26, 2024 03:50
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save MartinBrugnara/cb0cd5b53a55861d92ecba77c80ba729 to your computer and use it in GitHub Desktop.
Save MartinBrugnara/cb0cd5b53a55861d92ecba77c80ba729 to your computer and use it in GitHub Desktop.
DigitalOcean, assign public ipv6 to wireguard clients
# /etc/sysctl.d/wireguard.conf
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.eth0.proxy_ndp=1
#/etc/wireguard/wg0.conf (DO virtual machine)
[Interface]
# The server interface does not actually need an ipv6.
# The 2 following must be repeated for each used addres [0, 1]
PostUp=ip -6 neigh add proxy 2a03:b0c0:2:f0::2c:2002 dev eth0
PostDown=ip -6 neigh del proxy 2a03:b0c0:2:f0::2c:2002 dev eth0
[Peer]
# This must be one of the ips assigned by DO,
# usually they assign a /124 thus only
# the last 4 bits can vary for a total of 16 addresses.
# Example for a vm with ip -> 2a03:b0c0:2:f0::2c:2001
AllowedIps = 10.200.200.2/32, 2a03:b0c0:2:f0::2c:2002/128
#/etc/wireguard/wg0.conf (client)
[Interface]
Address = 10.200.200.2/32, 2a03:b0c0:2:f0::2c:2002/64
[Peer]
# ...
AllowedIPs = 0.0.0.0/0, ::/0
# Refs and Resources
[0] https://www.linuxquestions.org/questions/linux-networking-3/how-do-i-enable-proxy-ndp-proxy-arp-works-933174/
[1] https://manpages.debian.org/unstable/wireguard-tools/wg-quick.8.en.html
[*] https://www.reddit.com/r/WireGuard/comments/egik62/give_hosts_in_a_wg_interface_a_public_ipv6_address
@MartinBrugnara
Copy link
Author

You must assign such ipv6 to the interface that is actually connected to internet (e.g. eth0)

That's already done right from the VM creation instance by DO in this case.

Indeed

For the first solution, use the ipv6 of the gateway (dose not have to be in the same pool as they one you are "roouting") in the clients [Peer] /Endpoint configuration parameter.

WireGuard Client App/Config syntax does not accept IPv6 addresses as a valid syntax.

Doesn't make any sense... Never tested though, cannot confirm.

For the second solution, set the domain name (e.g. vpn.example.org) in the clients [Peer] /Endpoint . Then add both ipv4 and ipv6 to the domain address, respectively to the A record and to the AAA record.

As discussed here, the WireGuard client never resolves the AAAA record.

This statement does not seams to be correct. Please read the comments and additional resources, one of the first on gsearch https://pmcc.net/posts/automated-wireguard-endpoint-updates-reachability-checks .

This is likely because now both your eth0 and your wg0 have that same address.

That's not the case. eth0 has its own static IPv6 address, wg0 has its own unique IPv6 address. For some reason, IPv6 dies completely on WireGuard clients the moment I assigned the public IPv6 address to the wg0 interface.

Ok, you said you were assigning /64 . You sure that's the correct mask?
I cannot help further here, but I can suggest you to check the resulting routing table.

I am not sure what you are asking here... I will give a pair of hints, than feel free to replay if it's not enough.

On this part, basically, I want a true IPv6 to IPv6 tunnel. The reason being I want to eliminate 6to4 tunnelling which is the current setup on WireGuard by default. So Client A has IPv6 native, connects to Server A via their IPv6 native, no IPv4 tunnel is ever created. Which goes back to the AAAA resolving problem and the Reddit thread mentioned there along with the wg0 interface not working with public IPv6 assigned to it.

Just removing ipv4 should do it, make sure route discorivery protocol are working .

Unfortunately, I believe, Netflix has mapped all DO ips as "vpn" services, so you cannot use them to stream.

That's not true. I actively use DO IPs and use Netflix through DO. At least it works in my country.

That's nice to know ;)
May I ask on which DO region are exiting? I was talking about AMS.

Nevertheless Path MTU Discovery (PMTUD) should still work; that said, accordingly to random posts, it seams like many devices on the network break it (something to do with "All ICMPs packets are bad" - lol). Thus it may be necessary to force it like you did.
Maybe @CristianCantoro , or someone else can help with this; I would be interested too.

Found a solution, first, wg0 interface should default to 1420 MTU which is the proper WireGuard MTU as per the creator. Next on the client .conf file, manually specific MTU=1420. Leaving it blank/auto will never work as there's no mechanism to negotiate MTU over TCP/UDP, this is something that usually works only between layer 2.5-layer 2 protocols as far as I know. That's it, no more MTU problems with WireGuard. Assuming your WAN interface has MTU= 1492 (typical PPPoE without RFC4638) or greater or the standard 1500.

Thanks for sharing.

@daryll-swer
Copy link

daryll-swer commented Apr 18, 2021

Doesn't make any sense... Never tested though, cannot confirm.

Figured it out from the iOS app. The syntax for static IPv6 is [ipv6]:port. Solved.

This statement does not seams to be correct. Please read the comments and additional resources, one of the first on gsearch https://pmcc.net/posts/automated-wireguard-endpoint-updates-reachability-checks .

Yeah I've read it before. You can test it yourself on a client with native IPv6 if you get the chance. The client app will refuse to resolve AAAA records. Solution? I used static IPv6 address.

Ok, you said you were assigning /64 . You sure that's the correct mask?
I cannot help further here, but I can suggest you to check the resulting routing table.

Mask? You mean prefix size? Yes, /64 is the correct prefix size. Anyway I solved the IPv6 issue.

  1. Give wg0 interface a /64 ULA in the wg0.conf file along with a /[whatever] for the classic IPv4 NAT/subnet
  2. Do what your original document has suggested with NDP proxying/giving static IPs to clients manually (we need an automated solution for this really)
  3. Use destination NAT to map any incoming traffic to host on Public IPv6:[port] to wg0 IPv6:port like
    ip6tables -A PREROUTING -d 2400:6280:100:d0::7e0:4001 -p udp --dport 51820 -j DNAT --to-destination [fddd:2c4:2c4:2c4::1]:51820
  4. Now client that has the static IPv6 end-point configured can connect via IPv6 if they have IPv6 connectivity. And benefit is you will get 4to6 functionality so it's all neatly dual-stacked without any bugs (with my MTU solution above).
    The only issue is Xbox's Networking/Teredo implementation refuses to work with NATted IPv4 (no port forwarding/it's like a CGNAT) and does not take advantage of IPv6.

That's nice to know ;)
May I ask on which DO region are exiting? I was talking about AMS.

DO, Bangalore, India

@MartinBrugnara
Copy link
Author

Thanks for sharing what you found =)

@luciaDary46
Copy link

Just use the auto-install script wireguard created by @Nyr , make sure your virtual server has ipv6 configured... that solves the problem.

@daryll-swer
Copy link

@luciaDary46 all that does is NAT66 IPv6. It does not configure NDP-Proxying nor ensure each client gets a proper IPv6 address instead of NAT66.

@Nyr
Copy link

Nyr commented Dec 9, 2021

@daryll-swer it is not possible to automate provision a "proper" IPv6 address for each client when almost all of the cloud and dedi providers do not provide a routed IPv6 subnet, and most IPv6 implementations are broken somehow. That is why I do NAT for IPv6 (which was already the case for IPv4 anyway).

@daryll-swer
Copy link

(which was already the case for IPv4 anyway).

Agreed. But I don't see why you are promoting NAT for IPv6! @Nyr

Anyways, you can automate it via your scripting with dynamic variables, ask the user to input the non routed subnet/prefix range available and you can automatically inject those for NDP Proxy and mapping of each client in a serial/chronological order. That's basically what I do manually on DigitalOcean with their broken /124.

@Nyr
Copy link

Nyr commented Dec 9, 2021

@daryll-swer I am not promoting anything, just doing what I can to provide working IPv6 connectivity.

There are a lot of providers giving a single /128 address per server, your proposal would not work in many places and is less user-friendly. There are also many providers which require to route each /128 manually from their control panel, this is actually how SolusVM works (SolusVM is the industry standard for VPS providers).

@daryll-swer
Copy link

daryll-swer commented Dec 9, 2021

Oh boy, I would strongly recommend avoiding such crappy providers! Defeats the purpose of IPv6!

Not ALL cloud providers are bad with IPv6, this an example that provides routed /64s to the customer's host: https://twitter.com/ungleich

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment