My raspberry pi is my standard gateway, sitting between my router and the rest of my home network. When my desktop pc sends packets to a specific external IP, I want my raspberry pi to send them to another local machine instead. (Trying to emulate a game server, but the game has the server IP hardcoded) This needs to work for TCP and UDP.
I tried the following rules on my raspberry: (1337
= game port, 1.2.3.4
= game server, 192.168.0.169
= other local machine emulating server)
iptables -t nat -A PREROUTING -d 1.2.3.4/32 -p udp -m udp --dport 1337 -j DNAT --to-destination 192.168.0.169:1337
iptables -t nat -A PREROUTING -d 1.2.3.4/32 -p tcp -m tcp --dport 1337 -j DNAT --to-destination 192.168.0.169:1337
UDP works fine. Sent packets get routed to 192.168.0.169
and responses come back. However they don't come from 1.2.3.4
(the non existent game server) but from my emulated server 192.168.0.169
. For UDP this doesn't really matter, however with TCP this causes the handshake to fail:
(My desktop pc is 192.168.0.199
. Wireshark view from 192.168.0.169
, the emulated game server. From what I see the SYN ACK did not work, hence the retransmissions. I guess this is because the SYN ACK comes from an unexpected IP)
I tried rewriting the source ip for packets going back to 192.168.0.199
with this rule:
iptables -t nat -A POSTROUTING -s 192.168.0.169/32 -d 192.168.0.199/32 -p tcp -j SNAT --to-source 1.2.3.4
However it simply doesn't work. I am not good at iptables yet, so I probably did something wrong, but i'm not sure if rewriting the source of all packets from the game server to my desktop pc is a good idea anyways (other applications will porbably get messed up).
Bonus question: Isn't DNAT supposed to rewrite the source IP when there is a response anyway?
Best Answer
Yes it is, iptables NAT rules only operate on the first packet of a connection, later packets are handled according to the mappings established by the first rule.
The problem is that the NAT can't translate packets that are never sent to it. Here is what is happening in your scenario.
So what can we do about it? One solution is to MASQURADE the traffic from client to server so that the server sees the traffic as coming from the NAT box. I believe the following should do it