Retaining Source Address with WireGuard

By following the steps below you should be able to “proxy” requests from an external server, such as a VPS, to an internal server using WireGuard while retaining the original source IP address. I am personally using this to connect to a Minecraft server under a Pterodactyl Wing on my home server using my VPS’s IP address.

On Server

  1. Open the port for WireGuard (51820, UDP) on your NSG or firewall if you have one.
  2. Configure your WireGuard server (/etc/wireguard/wg0.conf).
[Interface]
PrivateKey = XYZ=
Address = 10.1.0.1/16
ListenPort = 51820

[Peer]
PublicKey = YZX=
AllowedIPs = 10.1.0.2/16

[Peer]
PublicKey = ZYX=
AllowedIPs = 10.1.0.3/16
  1. Enable WireGuard with systemctl enable wg-quick@wg0, then start it with systemctl start wg-quick@wg0.

  2. Configure nftables (/etc/nftables.conf). Replace:

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
	chain input {
		type filter hook input priority filter;
	}
	chain forward {
		type filter hook forward priority filter;
	}
	chain output {
		type filter hook output priority filter;
	}
}

table inet nat {
    chain prerouting {
        type nat hook prerouting priority dstnat; policy accept;

        # Changes the destination IP to 10.1.0.3 for all TCP requests on port 35000.
        meta iif enp0s3 tcp dport { 35000 } dnat ip to 10.1.0.3
    }

    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;

        # Importantly, this will route all traffic coming from the client device to wherever it needs to go on the public internet.
        oif enp0s3 masquerade
    }
}
  1. Reload nftables with sudo nft -f /etc/nftables.conf.

On Client

  1. Configure your WireGuard client (/etc/wireguard/wg0.conf).
[Interface]
PrivateKey = XYZ=
Address = 10.1.0.3/16

[Peer]
PublicKey = XYZ=
AllowedIPs = 0.0.0.0/0 # Makes sure that all traffic is sent back through to the server.
Endpoint = 123.123.123.123:51820
PersistentKeepalive = 25 # Necessary if your client is behind a NAT.
  1. Enable WireGuard with systemctl enable wg-quick@wg0, then start it with systemctl start wg-quick@wg0.

Notes