My question is almost perfectly summarised here: Preserve connecting clients IP address through an OpenVPN tunnel And the solution provided in that post hints at what I need to do, and have been trying to do for days now.
Some environment information: The VPS is not behind NAT or anything like that, just like most setups. The game server IS behind NAT, in my home network. My understanding is that this shouldn't matter due to the VPN tunnel. The game server is running in a docker container, due to the fact that I manage these game servers using a tool call Pterodactyl, which you may have heard of. Pterodactyl should be, and appears to be, managing the internal networking on the host required for traffic on the host to reach the game server inside the container. I know this works because I can connect successfully with the VPN in the normal config.
Both the VPS and the Game server are running Ubuntu server 22.04
I have succeeded in configuring the wireguard tunnel and am able to use it to connect to my game server using the VPS's public IP, however the logs in said game server shows my connection address as being from the internal VPN IP of the VPS. This makes perfect sense as to achieve the routing, the packets coming from VPS have their source IP updated using an iptables rule to the VPS's internal VPN IP so the packets can route back over the VPN.
However, I want to preserve the source IP of the client connecting. My googling for days now indicate this is possible, but when I reconfigure wireguard / ip rules to a different config that my research online shows should work, I can't connect any more, and frankly my understanding of the networking is too poor for me to know what's going wrong. I don't even know how to diagnose it.
Below is an example of the original working config where the source IP is overwritten on the VPS.
VPS Wireguard config (/etc/wireguard/wg0.conf):
PrivateKey = [Redacted]
ListenPort = 51080
Address = 10.1.1.2
PostUp = iptables -t nat -A PREROUTING -p tcp --dport 25560 -j DNAT --to-destination 10.1.1.1
PostUp = iptables -t nat -A POSTROUTING -o wg0 -d 10.1.1.1 -j SNAT --to-source 10.1.1.2
PostDown = iptables -t nat -D PREROUTING -p tcp --dport 25560 -j DNAT --to-destination 10.1.1.1
PostDown = iptables -t nat -D POSTROUTING -o wg0 -d 10.1.1.1 -j SNAT --to-source 10.1.1.2
[Peer]
PublicKey = [Redacted]
AllowedIPs = 10.1.1.1/24
Game server Wireguard config (/etc/wireguard/wg0.conf):
[Interface]
PrivateKey = [Redacted]
Address = 10.1.1.1
[Peer]
PublicKey = [Redacted]
AllowedIPs = 10.1.1.2/24
Endpoint = [VPS Public IP]:51080
PersistentKeepalive = 25
And now below a modified config that I hoped would do what I wanted but doesn't work. I have tried many configurations, this is just one of them.
VPS Wireguard config (/etc/wireguard/wg0.conf):
PrivateKey = [Redacted]
ListenPort = 51080
Address = 10.1.1.2
#No longer changing source address on the packet so as not to overwrite
#the client's connecting address when sending the packet to the game server.
PostUp = iptables -t nat -A PREROUTING -p tcp --dport 25560 -j DNAT --to-destination 10.1.1.1
#PostUp = iptables -t nat -A POSTROUTING -o wg0 -d 10.1.1.1 -j SNAT --to-source 10.1.1.2
PostDown = iptables -t nat -D PREROUTING -p tcp --dport 25560 -j DNAT --to-destination 10.1.1.1
#PostDown = iptables -t nat -D POSTROUTING -o wg0 -d 10.1.1.1 -j SNAT --to-source 10.1.1.2
[Peer]
PublicKey = [Redacted]
AllowedIPs = 10.1.1.1/24
In the below I'm 'letting' wireguard create the routing table for me, I have also tried doing this separately / manually outside of wireguard (i.e. creating a default route in the table used for the VPN connection that directs traffic to 10.1.1.1) with no luck.
Game server Wireguard config (/etc/wireguard/wg0.conf):
[Interface]
PrivateKey = [Redacted]
Address = 10.1.1.1
Table = 1
#Since we no longer have source address as the VPN we need to manually route packets from the VPN back to it.
#As far as I understand, 'if packet coming from 10.1.1.1, route via table 1'
#which wireguard creates because of the above.
#i.e. if it came the VPN, send it back to the VPN
PostUp = ip rule add from 10.1.1.1 lookup 1
PostDown = ip rule del from 10.1.1.1 lookup 1
[Peer]
PublicKey = [Redacted]
AllowedIPs = 0.0.0.0/0
Endpoint = [VPS Public IP]:51080
PersistentKeepalive = 25
What am I missing here? I believe what is happening is that response packets from the game server aren't going to the right place but really I have no idea.
ip rule
show the correct rule? Doesip route get <dst> from <src>
show the correct route being chosen? Doeswg
show the correct (0/0) AllowedIPs? Doestcpdump -n -i <if>
show packets arriving and packets exiting?sudo sysctl net.ipv4.conf.wg0.rp_filter
? If it's1
, doessudo sysctl -w net.ipv4.conf.wg0.rp_filter=2
solve the problem? (Just in case, all so check thatsudo sysctl net.ipv4.conf.all.rp_filter
is0
.)