Using NAT sucks. An average homelabber might not need to use more than a single public IP, but in my case, I need to use more than just one. In addition to that, my ISP doesn't provide IPv6 connectivity at all. So I'm stuck with IPv4, and what do you do when you need IPv6? You overcomplicate your setup by making an entire separate publicly-routable network for it.
Things you will need in order to achieve the same result:
- A BGP-capable machine (optionally, you can get a normal IPv6-enabled VM)
- A little networking knowledge
- A lot of time and patience
- An AS number (optional)
- A IPv6 subnet
This entire project should only cost you around 5-10€ per month to sustain it. To get started, I heavily recommend you to read the Wireguard documentation, and to have a basic knowledge of how public networking works. This tutorial also assumes that you have a static IP address at home or you have the knowledge to correctly set up Wireguard to work even if the IP changes.
Step 1: Acquire an IPv6-enabled server
You can pick just about any provider that provides IPv6 connectivity. I recommend Vultr (this is a referral link) since they provide both IPv6 and BGP by default. After you've signed up, create a new server (type doesn't matter), and tick the enable IPv6 box under "Additional Features". For the sake of simplicity, I used a Debian-based VM, but you can use any other OS you like as long as it supports Wireguard.
Once the server is deployed, you'll see a new server pop up in the "Instance" section. It should look something like this:

Step 2: Configure Wireguard
Once you log in to the server, you'll be presented with a simple terminal prompt. On a Debian-based system, you can use the following commands to install Wireguard and its tools:
apt install wireguard wireguard-tools
When the installation is complete, you should create a new file in /etc/wireguard/
named wg0.conf
.
You can call it just about anything, but I recommend this since it's simple and easy to remember.
This can be done by executing this command:
cd /etc/wireguard && wg genkey | tee privatekey | wg pubkey > publickey
Repeat this on the server and note down the public key, you'll need it later to populate the client public key field. If you intend on using this with a Windows client, you'll need to generate it using the Windows program.
This command will generate a new private key and public key and will save them to the /etc/wireguard/
directory.
Once you've created the files, you can open them in a text editor and start populating the fields.
Please replace any values in <>
with your own. Here's an example of what the file should look like:
[Interface]
PrivateKey = <private key>
Address = <your private IPv4 address>/32 <your IPv6 address>/64
ListenPort = <desired port>
# <client comment>
[Peer]
PublicKey = <client public key>
AllowedIPs = <client IPv4 address>/32 <client IPv6 address>/96
A fully populated configuration file looks like this:
[Interface]
Address = 10.9.0.1/24, 2001:1000:6c01:2c33::1/64
ListenPort = 41194
PrivateKey = #redacted#
# Home computer
[Peer]
PublicKey = #redacted#
AllowedIPs = 10.9.0.2/32, 2001:1000:6c01:2c33::1000/128
Feel free to change around the masks and addresses as you see fit, but for my use case, I only needed a single IPv6 address on this client.
Step 3: Activate the tunnel and configure the client
Once you've configured the server, you'll need to tell it to use the configuration file we created earlier. To do this, you'll need to open the server's terminal and execute the following command:
wg-quick up wg0
If you did everything correctly, you should now see another network interface by executing ip link
. The bottom line should say wg0.
You can also verify that it's working, by checking its status:
root@de-router:~# wg show
interface: wg0
public key: (hidden)
private key: (hidden)
listening port: 41194
peer: (hidden)
allowed ips: 10.9.0.2/32, 2001:1000:6c01:2c33::1000/128
If you see something similar to this, you should be good to go.
Step 4: Configure the client
To configure the client, you'll need to open the client's terminal and execute the same command you used to install Wireguard.
Once that's done, create a new config file for the client in /etc/wireguard/
named wg0.conf
:
[Interface]
Address = <client IPv4 address>/32 <client IPv6 address>/128
PrivateKey = <client's privatekey file contents>
DNS = 2001:4860:4860::8888, 8.8.8.8
[Peer]
PublicKey = <server's publickey file contents>
AllowedIPs = ::0/0
Endpoint = <server's IP>:<server's port>
Just as before, you can change the values as you see fit. Here's an example of what a populated file should look like:
[Interface]
Address = 10.9.0.2/32, 2001:1000:6c01:2c33::1000/128
PrivateKey = #redacted#
DNS = 2001:4860:4860::8888, 8.8.8.8
[Peer]
PublicKey = #redacted#
AllowedIPs = ::0/0
Endpoint = 10.9.0.1:41194
Once the file is populated, you can start the tunnel by executing the following command:
wg-quick up wg0
Wait for a couple seconds then try pinging any IPv6-enabled site. I chose google.com:
[user@x570 ~]$ ping -6 google.com
PING google.com(mil41s04-in-x0e.1e100.net (2a00:1450:4002:406::200e)) 56 data bytes
64 bytes from mil41s04-in-x0e.1e100.net (2a00:1450:4002:406::200e): icmp_seq=1 ttl=117 time=16.0 ms
64 bytes from mil41s04-in-x0e.1e100.net (2a00:1450:4002:406::200e): icmp_seq=2 ttl=117 time=15.7 ms
64 bytes from mil41s04-in-x0e.1e100.net (2a00:1450:4002:406::200e): icmp_seq=3 ttl=117 time=14.6 ms
^C
--- google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 14.574/15.454/16.048/0.634 ms
If you see something like this, your client is working!
Step 5: Extra Proxmox configuration
If you're using a Proxmox server, you'll need to do the following changes to go through the normal set-up process as explained above, but with a few extra steps.
- Assign a "gateway" IP to the VM bridge interface
- Set up your virtual machine to use an IPv6 address
First, you need to log into Proxmox's management panel, then select the node you want to work on and select System -> Network.
Once you're there, you'll see a list of interfaces. The one you want to change is the bridge interface, usually named vmbr0
.
My network setup is a little different, but the process should be the same.
Here's a picture of how it looks:

Once you've assigned it to the bridge interface, all that's left to do is to assign the IPv6 address to VMs. You can do so by clicking on one of the virtual machines and clicking on the Network tab. From there, add a new IPv6 address as shown below:

If you followed the steps correctly, you should now be able to access IPv6 sites, congratulations!