I am setting up a Linux server as a VPN using Wireguard (previously configured via Algo, now doing it myself). My goal is to have two different public IP addresses: one for ingress (VPN clients connect here, e.g. 192.0.2.10
), and one for egress (websites accessed from the VPN will see this as the client's IP address, e.g. 198.51.100.20
).
I have tried doing this in various ways, and at one point in the past I had it working flawlessly. However, I have since then deleted that old Algo VPN server and now can't figure out how to get it working again. For context, when it worked before, both IPs were attached to the same NIC, and I don't think I needed to do anything tricky with routing or iptables. I think this was on a pre-netplan Ubuntu distro though, and now getting the interface setup correctly for this situation with netplan is tricky.
I've tried adding both IPs to the same interface (single NIC), with the egress IP as the primary and the ingress as the secondary (so all outbound traffic will use the egress IP by default). I have also tried adding two NICs (eth0
and eth1
), where each one uses a different IP.
It sometimes works, but the problem I'm running into is that Wireguard's UDP packets back to the client sometimes go out over the egress IP, meaning the Wireguard client doesn't receive them through NAT. The client logs show messages like these: Handshake did not complete after 5 seconds, retrying (try 4)
, and using tcpdump
I can see that the response packets are sent from the egress source IP instead of the ingress one.
I've tried to setup symmetric routing using a combination of ip route
and ip rule
commands and using a separate routing table number for each interface/ip, but I've always run into problems trying to do that.
To further complicate things, I'm doing this in Azure, so the VM is on a VNet and only sees an internal IP address (10.10.0.4
, for example). So in the dual-NIC setup, the egress IP may be translated to 10.10.0.4
, and then ingress IP may be translated to 10.10.0.5
. I've also tried having each NIC be on its own /24
subnet, like 10.10.0.4
and 10.10.1.4
.
I've tried using iptables to change the source address to the ingress IP when sending UDP traffic to port 51820 (Wireguard). I've also thought about setting up the ingress IP as the default and then having an iptables FORWARD rule to make anything coming from wg0
go out over (the egress NIC / the egress IP).
I'm still learning about networking and routing, so maybe I'm approaching this the wrong way, overcomplicating it, or missing something obvious. My question is what is a "correct" or "proper" solution to solve this problem?