Score:0

Passthrough VPN Tunnel w/ iptables

ng flag

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.

Score:0
cn flag

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
ng flag
Exactly what I was looking for! Worked like a charm and the explanation will help me figure these types of situations out going forward. Thank You!
movabo avatar
gd flag
If you get the error `Bad argument 'ESTABLISHED,RELATED'` at the third command, add the `--state`-argument: `iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT`
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.