Writing

Software, technology, sysadmin war stories, and more. Feed
Saturday, December 24, 2011

A sneaky way to bounce TCP connections with Linux

I was once in a situation where I needed to ssh from point A to point B but I didn't want them to know about each other. That is, A shouldn't find out that I'm talking to B, and B shouldn't find out that I'm at location A. I also wanted to leave behind as few traces as possible.

Basically, I didn't want to rig up some kind of userspace port forwarding hack with something like datapipe (the star of another hack some years before) on a third machine. It would have left behind something in the process table that random other people could see. It would invite them to play with it, in other words.

Instead, I did something really evil with iptables. It worked like this: any packet from the external IP address of A bound for port 22000 on my machine at home (point C) was sent through the iptables SNAT target. There, it was rewritten to have the source address of C. Then it was also sent to the iptables DNAT target to set the destination address to point B's IP address and port 22.

Once this was in place, all I had to do was ssh from A to C:22000, and I'd automatically connect to B:22. A just saw a connection from me to my machine at home, which was not surprising. People did that all the time. B just saw a connection from my machine at home, which was also unsurprising to them.

Even ordinary users on C itself (my machine at home) couldn't see anything magic. You have to be root to run the iptables commands to see what sort of rules are in place. Besides that rule, the only other trace it left was a entry in /proc/net/ip_conntrack, approximately like this:

tcp 6 123456 ESTABLISHED src=A dst=C sport=12345 dport=22000 src=B dst=C sport=22 dport=23456 [ASSURED] use=1

It's been quite a few years, so I forget if I had to do anything special to make the flip side work. I may have had to allow the incoming packets back in to let SNAT and DNAT and the connection tracking stuff do its thing.

I only used it for good, but here's the thing -- you could easily use this for evil. If you wanted to use a host as a trampoline into other places, a bunch of rules like this would make it possible. Nothing would show up in the process table or even the usual netstat views. It wouldn't even show up in the default 'iptables -L' view, since you have to specify '-t nat' to see SNAT and DNAT stuff.

Be careful out there.