Assuming internet facing server (VPS) is Public IP 1.2.3.4
, which is VPN server internally at 10.10.0.1
Assuming home PC is VPN client internally at 10.10.0.2
(Public IP doesn't matter)
We want to expose home PC port 6969 to the internet via the VPS's port 6969.
+---------------------+ +----------------------+ +----------------------+
| | | | | |
| Client on +------------------>| Your VPS +---------------------->| your home PC |
| Internet | | | | |
| | | 1.2.3.4 | | |
| e.g. 4.4.4.4 | | | | |
| |<------------------+ (10.10.0.1) |<----------------------+ (10.10.0.2) |
| | | | | |
+---------------------+ +----------------------+ +----------------------+
iptables -A FORWARD -d 10.10.0.2/32 -p tcp -m tcp --dport 6969 -j ACCEPT
iptables -A PREROUTING -d 1.2.3.4/32 -p tcp -m tcp --dport 6969 -j DNAT --to-destination 10.10.0.2:6969 -t NAT
iptables -A POSTROUTING -o eth0 -j MASQUERADE -t NAT
They don't see anything. They send a packet to 1.2.3.4:6969
:
+------------------------------+
| |
| IP Packet |
| |
| |
| From: 4.4.4.4:XXXX |
| |
| To: 1.2.3.4:6969 |
| |
| |
+------------------------------+
And get a response from 1.2.3.4:6969
:
+------------------------------+
| |
| IP Packet |
| |
| |
| From: 1.2.3.4:6969 |
| |
| To: 4.4.4.4:XXXX |
| |
| |
+------------------------------+
It sees an incoming packet, on their VPN internal IP, from 4.4.4.4:XXXX
:
+------------------------------+
| |
| IP Packet |
| |
| |
| From: 4.4.4.4:XXXX |
| |
| To: 10.10.0.2:6969 |
| |
| |
+------------------------------+
they process it (e.g. HTTP server or whatever),
and they send the reply to 4.4.4.4:XXXX
, from their VPN internal IP:
+------------------------------+
| |
| IP Packet |
| |
| |
| From: 10.10.0.2:6969 |
| |
| To: 4.4.4.4:XXXX |
| |
| |
+------------------------------+
Note: I am not an IPTABLES / Netfilter expert, so at the lower level this may not be exactly how it works. If there is anything wrong please correct me.
- It sees an incoming packet for
1.2.3.4:6969
. In theNAT
table, it matches the rulePREROUTING -d 1.2.3.4/32 -p tcp -m tcp --dport 6969 -j DNAT --to-destination 10.10.0.2:6969 -t NAT
as follows: see the destination IP is1.2.3.4/32
and the port is6969
.
+------------------------------+
| |
| IP Packet |
| |
| |
| From: 4.4.4.4:XXXX |
| |
| To: 1.2.3.4:6969 |
| |
| |
+------------------------------+
- It applies DNAT aka Destination Network Address Translation, meaning it rewrites the destination to
10.10.0.2:6969
.
+------------------------------+
| |
| IP Packet |
| |
| |
| From: 4.4.4.4:XXXX |
| |
| To: 10.10.0.2:6969 |
| |
| |
+------------------------------+
-
Next, in
FILTER
(default) table, the ruleiptables -A FORWARD -d 10.10.0.2/32 -p tcp -m tcp --dport 6969 -j ACCEPT
allows the packet to be forwarded to the home PC. -
It then gets the reply from the Home PC, with destination
4.4.4.4:XXXX
.
+------------------------------+
| |
| IP Packet |
| |
| |
| From: 10.10.0.2:6969 |
| |
| To: 4.4.4.4:XXXX |
| |
| |
+------------------------------+
- it applies the
POSTROUTING -o eth0 -j MASQUERADE -t NAT
rule, and rewrites the source IP to the VPS's external IP automatically.
+------------------------------+
| |
| IP Packet |
| |
| |
| From: 1.2.3.4:6969 |
| |
| To: 4.4.4.4:XXXX |
| |
| |
+------------------------------+
- It then sends the packet back out to the internet!