Iptables – forward ssh port from one host to another host and different port on another interface

iptablesport-forwarding

i would like to forward a ssh port to another host and a different port and interface.

server1:22 -> server1:22

public internet -> eth0 -> server1:23 -> eth1 -> server2:22

i enabled ipv4 forwarding

sysctl -p
net.ipv4.ip_forward = 1

and created the following ip table rules

iptables -t nat -I PREROUTING -p tcp -i eth0 --dport 23 -j DNAT --to-destination 192.168.0.3:22
iptables -A FORWARD -i eth0 -o eth0 -p tcp --dport 23 -j ACCEPT

but i can't get it to work, what am i missing?


finaly with haukes help i got it to work

iptables -t mangle -A PREROUTING -d <Server1_eth0> -p tcp --dport 2223 -j MARK --set-mark 1 -i eth0
iptables -t nat -A PREROUTING -p tcp -m mark --mark 1 -j DNAT --to-destination <Server2>:2222 -i eth0
iptables -t nat -A POSTROUTING -m mark  --mark 1 -j SNAT --to-source <Server1_eth1> -o eth1 
iptables -A FORWARD -m mark --mark 1 -j ACCEPT -o eth1

where Server1_eth0 is my public ip

Best Answer

If server1 is not the gateway for server2 then you need SNAT, too. Otherwise server2 will send the reply to the client which doesn't recognize the packet as it doesn't have server1 as source address but server2.

iptables -t nat -A POSTROUTING -p tcp -m conntrack --ctstate DNAT --ctorigdst server1 --ctorigdstport 23 -j SNAT --to-source server1

A precise and easy to understand filter criteria for the rules in FORWARD, PREROUTING and POSTROUTING would be a packet mark:

iptables -t mangle -A PREROUTING -d $server1_ip -p tcp --dport 23 -j MARK --set-mark 22
iptables -t nat -A PREROUTING -p tcp -m mark --mark 22 -j DNAT --to-destination $server2_ip:22
iptables -t nat -A POSTROUTING -m mark --mark 22 -j SNAT --to-source $server1_ip
iptables -A FORWARD -m mark --mark 22 -j ACCEPT

Please note: If server1 has more than one interface and the DNATed packets are routed from one interface to another (like it turned out in this case) then the destination match IP and the SNAT IP are different.

"-p tcp" should not be necessary in the second line but iptables or Netfilter requires it. It may be useful to add e.g. -m comment --comment "DNAT SSH from port 23 to server2" in all lines to make the optput of iptables -L -nv easier to understand.