Iptables – Port forwarding with iptables

iptablesport-forwarding

I have a weird network topology, and I'm trying unsuccessfully to forward ports.

The thing is, I have a public server, and all ports have to be forwarded from the router to the same server (sort of DMZ).

My topology:

   internet
      |
    router
      |
 /----+--+------\
 |       |      |
pc1   server   etc

The server runs linux (ubuntu) with iptables. The firewall is configured pretty much like this:

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT

# for every port I accept on the server (this part works perfectly)
iptables -A INPUT -p tcp --dport xxxx -j ACCEPT

# for every port I want to forward to pc1 (this is the part that doesn't work)
iptables -A FORWARD -p tcp --dport xxxx -j ACCEPT
iptables -t nat -P PREROUTING -p tcp --dport xxxx -j DNAT --to $PC1_IP
# I've also tried with the following line:
iptables -t nat -P POSTROUTING -p tcp --sport xxxx -j SNAT --to $PC1_IP

but forwarding just doesn't seem to work.

When I enable forwarding, connections can connect (or seem to be able to) but no data is trasferred. Perhaps they just time out.
When I don't enable said forwarding, connections are refused immediately.

The target pc has been checked and it can accept connections.

I've also tried sniffing a bit with Wireshark on both machines. On the server the packet is accepted, but no outgoing packet is found (I assume there should be one if DNAT rerouting actually happened). On pc1, no packet is received.

Can anyone suggest a fix? I've been googling for days, and I've tried several settings for this port – none of them worked.

Best Answer

try adding

echo 1 > /proc/sys/net/ipv4/ip_forward

to enable routing on the linux

add

iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

otherwise responses from local pcs will not be forwarded back to the internet.

also you might want to use:

iptables -t nat -P PREROUTING -p tcp --dport xxxx -d your.public.ip.addr -j DNAT --to $PC1_IP

if you keep your rule - any traffic sent on port xxxx from local network will be forwarded to $PC1_IP