Passthrough VPN Tunnel with Iptables

iptablespassthroughtunnelingvpn

My email VPS is getting to its limit but it's dedicated IP is well nurtured and I just cant part with it. I'm trying to setup a test environment where I establish a VPN server on the VPS just to passthrough incoming and outgoing traffic back to a VM with the goal of using the external IP on the VPS for all internet communication while tunneling that traffic back to a VM.
My troubles are with iptables. I cannot figure this one out and im sure its just my lack of knowledge with using iptables to this extent. Both my VPS and VM are running Debian 10.

I've tried a few different variations of rules which i've found from various posts on here.

Variation (I changed the adapter name and ports when using these rules)

iptables -A FORWARD -m conntrack --ctstate NEW -s $PRIVATE_SUBNET -m policy --pol none --dir in -j ACCEPT
iptables -t nat -A POSTROUTING -s $PRIVATE_SUBNET -m policy --pol none --dir out -j MASQUERADE
iptables -A INPUT -p udp --dport $SERVER_PORT -j ACCEPT
iptables -A FORWARD -i eth0 -o wg0 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -i eth0 -o wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i wg0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth0 -o wg0 -p tcp --syn --dport 443 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -i eth0 -o wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i wg0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination $WIREGUARD_CLIENT_ADDRESS
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination $WIREGUARD_CLIENT_ADDRESS

I've also tried writing my own rules but even after watching some great tutorial videos that cover stuff more then just the filter table. I don't seem to have the right mental picture of how traffic flows.

Also because I want to receive NEW traffic from the VPN server I know I have to make changes to the iptables on the "client" VM and that could very well be where my problem lies as well. I was hoping someone could shed some light on a few basic concepts I might be missing to solve this puzzle.

Best Answer

If I remember correctly, the 'flow' for a packet coming in would be:

diagram of header rewrites

I've tested this on some EC2 instances: one public and one private. Both running apache with a simple webpage, one saying 'gateway' and one saying 'node'.

Before adding IP tables rules I can curl a simple webpage and it correctly shows it's from my 'gateway' instance. I then do the following on the gateway:

echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/10-forwarding.conf
sudo sysctl -w net.ipv4.ip_forward=1

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.0.100.154
sudo iptables -A FORWARD -i eth0 -p tcp --dport 80 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -p tcp --dport 80 -j SNAT --to 10.0.0.160

This allows me to curl the public IP, where it's NAT'd to the target internal VM and correctly forwarded/NAT'd for the response. I've set up the private subnet without any external routing, so unless it's routing to the internal range, it's not going anywhere. It works as hoped!

If you've multiple interfaces then you should be able to lock down the FORWARD rule a bit better with additions of -i eth0 -o wg0 to some rules, and the POSTROUTING rule with a -o wg0.

So I think your rules should be:

# dnat to target VPN VM
iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport --dports 80,443 -j DNAT --to-destination $WIREGUARD_CLIENT_ADDRESS

# forward between interfaces for new conns
iptables -A FORWARD -i eth0 -o wg0 -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW -j ACCEPT
# allow forwarding related traffic - no need for both sets of -i/-o as we can just allow related
iptables -A FORWARD -m state ESTABLISHED,RELATED -j ACCEPT

# postrouting for VPN
iptables -t nat -A POSTROUTING -o wg0 -p tcp -m multiport --dports 80,443 -j MASQUERADE
Related Topic