Creating a quick wireguard tunnel to my VPS

This is a quick setup to create an ipv6 tunnel over ipv4. Well, kinda because the idea here is to route all traffic through my VPS but most important, to enable my machine to also have a valid ipv6 address on the internet. I’ll follow the same model as my previous article where I’ll provide the steps first and the explanation later, since I have received some feedback that this format is much appreciated.

## Motivation

Simple one: My ISP sucks and does not provide ipv6.

Not only that but, some games and technologies rely heavily on ipv6 for user session, connecting peers directly, and because of this limitation on my ISP I was not able to join these sessions.

## Requirements

This is the bare minimum you need for this setup:

  • A client. In my case, I’m using Linux but you can adapt it to work on macOS, Windows, FreeBSD, OpenBSD, etc.
  • A VPS or a remote server with a valid ipv6 address.
  • ipv4 in both client and server, of course.
  • Wireguard tools installed on both ends. Most distributions call it wireguard-tools. The wireguard technology itself is already baked into the Linux kernel.

## Setup

Server Side Configuration:

  • As root user or using sudo/doas, edit the file /etc/wireguard/wg0.conf, and add the following content.
[Interface]
Address = 10.20.0.1/24, fd42:42:42::1/64
ListenPort = 51820
PrivateKey = SERVER_PUBLIC_KEY

# Enable forwarding + NAT for both IPv4 and IPv6
PostUp = sysctl  -w net.ipv4.ip_forward=1; sysctl  -w net.ipv6.conf.all.forwarding=1; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -A FORWARD -o wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -D FORWARD -o wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.20.0.2/32, fd42:42:42::2/128

Note: Change eth0 to the interface on your server that has valid ipv4 and ipv6 addresses on the PostUp and PostDown firewall rules.

Client Side Configuration:

  • As root user or using sudo/doas, edit the file /etc/wireguard/wg0.conf, and add the following content.
[Interface]
Address = 10.20.0.2/24, fd42:42:42::2/64
PrivateKey = CLIENT_PRIVATE_KEY

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = SERVER_IPV4_INTERNET_ADDRESS_OR_DNS:51820

# Route EVERYTHING through the tunnel
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

Both Sides Configuration:

As you may have noticed, I have used the SERVER_PRIVATE_KEY, SERVER_PUBLIC_KEY, CLIENT_PRIVATE_KEY and CLIENT_PUBLIC_KEY placeholders. Execute the following command as root user inside your /etc/wireguard directory on both your server and client

cd /etc/wireguard
wg genkey | tee privatekey | wg pubkey > publickey

I’m using the /etc/wireguard folder because it is only accessible by the root user being a safe place to hold your keypair.

The command above will generate a private+public keypair on both sides. Now, you just need to correctly configure the public key from one side into the other (client has the server public key, and server has the client public key).

Also, don’t forget to replace SERVER_IPV4_INTERNET_ADDRESS_OR_DNS with your VPS valid ipv4 address.

Start the tunnels:

You can bring both tunnels up on the client and server by using the following command as root user, or using sudo/doas:

wg-quick up wg0

Obviously, bring the server interface up first and then the client. Now, if you want to have this enabled or started using systemd:

systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0

And last, if you want to check for statistics on both sides:

wg show

## Explanation - FAQ

  1. What port does wireguard uses, and do I need to allow it in my firewall? Answer: wireguard uses udp/51820 and if you have more restrictive firewall rules or a default DROP policy please use iptables -A INPUT -p udp --dport 51820 -j ACCEPT to allow that traffic. You might also use the -i eth0 to limit this input to the interface with a valid ipv4 address that will service wireguard traffic.

  2. What are the PostUp and PostDown iptables and ip6tables rules on the server side about? Answer: These are rules to force incoming traffic on wg0, the wireguard interface to be routed and masqueraded through eth0, effectivelly creating a NAT.

  3. Is this solution scalable? Answer: I don’t know neither I care. It was good enough so I had private ipv4+6 networks that would be masqueraded through my VPS. Some of the most common VPN providers either don’t support ipv6, or they only support ipv6 tunnels if you have a valid ipv6 address already.

  4. What if I want to add more clients to my server? Answer: Generate a new keypair with wg genkey on the new client only, and add a new client on the AllowedIPs parameter of the server. Use the next IP available on both networks (ipv4 and ipv6) as the new client ip.

That’s all folks. Stay safe!