Need a generic iptables tcp proxy?
Posted by JacobAppelbaum on Tue 13 May 2008 at 10:02
It's as easy as the following three iptables calls:
YourIP=220.127.116.11 YourPort=80 TargetIP=18.104.22.168 TargetPort=22 iptables -t nat -A PREROUTING --dst $YourIP -p tcp --dport $YourPort -j DNAT \ --to-destination $TargetIP:$TargetPort iptables -t nat -A POSTROUTING -p tcp --dst $TargetIP --dport $TargetPort -j SNAT \ --to-source $YourIP iptables -t nat -A OUTPUT --dst $YourIP -p tcp --dport $YourPort -j DNAT \ --to-destination $TargetIP:$TargetPort
In the example above, a user may now ssh to $YourIP (22.214.171.124) on $YourPort (port 80) and they'll be transparently redirected to the $TargetIP (126.96.36.199) on the $TargetPort (22). The remote host ($TargetIP) will see the connection as coming from the server doing the forwarding ($YourIP).
Why bother with this at all? Why not just change the port that sshd listens on?
This is useful when a network filters outgoing connections based on destination ports and you don't control the host you want to connect to. If such a network only allowed outgoing connections to port 80, you'd be able to circumvent their filtering. However, if the firewall is doing stateful layer seven inspection, all bets are off. It's trivial to make this work for any other protocol, there is nothing special about ssh - it's just used as an example.
As a general note, this may invite abuse. It is basically a single hop protocol agnostic TCP proxy in kernel space. It's fast and useful though. You may want to restrict forwarding by source IP addresses if you're worried about letting anyone using you as a single hop bounce. I'll leave that as an exercise for the comments.