Iptables – source address with iptables port forwarding

iptablesport-forwardingsocket

I set up port forwarding for port 80 with iptables:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 10080  

Additionally, I have ip forwarding enabled to route connections from a different subnet.

I am running my own standard socket server on port 10080 on the same machine and when I receive an incoming connection to port 80 it is forwarded to my server as expected.

My problem is that when I print out the socket information using getsockname and getpeername, the source address is always the server's. If I connect to the server directly through a port that is not affected by the iptables rule I see the client address as expected. Why is port forwarding affecting the source address?

Best Answer

I don't think the redirect target is the right one to use in this case, the dynamic NAT target would be more appropriate.

An excerpt from https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Security_Guide/s1-firewall-ipt-fwd.html:

If you have a server on your internal network that you want make available externally, you can use the -j DNAT target of the PREROUTING chain in NAT to specify a destination IP address and port where incoming packets requesting a connection to your internal service can be forwarded. For example, if you wanted to forward incoming HTTP requests to your dedicated Apache HTTP Server server system at 172.31.0.23, run the following command:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT \
  --to 172.31.0.23:80