Background
In today's world, many organizations and individuals use Carrier-Grade NAT (CGNAT) to share a single public IP address among multiple devices. However, this setup can pose challenges when trying to establish secure connections between hosts behind different CGNATs. This article explains how to set up a WireGuard VPN connection between two hosts behind CGNATs using an untrusted Virtual Private Server (VPS).
Prerequisites
- Two devices behind CGNATs (Client A and Client B)
- An untrusted VPS with a public IP address (Server)
- WireGuard installed on all three devices
Setup WireGuard on Client A
First, we need to configure WireGuard on Client A. Create a new configuration file called wg0.conf and add the following content:
[Interface] PrivateKey =Address = 10.0.0.1/24 ListenPort = 51820 PostUp = iptables -A FORWARD --protocol all --tolerate IPv4 source 0.0.0.0/0 dst 10.0.0.2/32 iptables -A FORWARD --protocol all --tolerate IPv6 source ::/0 dst 2001:db8::2/64 PostDown = iptables -D FORWARD --protocol all --tolerate IPv4 source 0.0.0.0/0 dst 10.0.0.2/32 iptables -D FORWARD --protocol all --tolerate IPv6 source ::/0 dst 2001:db8::2/64
[Peer] PublicKey = <Server_Public_Key> AllowedIPs = 10.0.0.2/32, 2001:db8::2/64
Replace
with the public key of the VPS. Save and exit the file.
Setup WireGuard on Server
Next, we need to configure WireGuard on the VPS. Create a new configuration file called wg0.conf and add the following content:
[Interface] PrivateKey =Address = 2001:db8::1/64 ListenPort = 51820
[Peer] PublicKey = <Client_A_Public_Key> AllowedIPs = 10.0.0.1/32, ::1/128
Replace
with the public key of Client A. Save and exit the file.
Setup WireGuard on Client B
Finally, we need to configure WireGuard on Client B. Create a new configuration file called wg1.conf and add the following content:
[Interface] PrivateKey =Address = 10.0.0.2/24
[Peer] PublicKey = <Server_Public_Key> AllowedIPs = 0.0.0.0/0, ::/0
Replace
with the public key of the VPS. Save and exit the file.
Configure Firewall Rules
We need to configure firewall rules on the VPS to allow traffic between Client A and Client B. Run the following commands on the VPS:
iptables -A FORWARD --protocol all --tolerate IPv4 src 10.0.0.1/32 dst 10.0.0.2/32 iptables -A FORWARD --protocol all --tolerate IPv6 src 2001:db8::1/64 dst 2001:db8::2/64
Start WireGuard
Start WireGuard on all three devices:
Client A: systemctl start wg-quick@wg0
Client B: systemctl start wg-quick@wg1
Server: systemctl start wg-quick@wg0
Verify Connection
Check the status of the WireGuard interfaces on all three devices:
Client A: ip a s wg0
Client B: ip a s wg1
Server: ip a s wg0
In this article, we learned how to set up a WireGuard VPN connection between two hosts behind CGNATs using an untrusted VPS. We covered the prerequisites, steps to configure WireGuard on Client A, Server, and Client B, firewall rules, and finally, starting the WireGuard interfaces and verifying the connection.