Sometimes you need to access your source code repository-server from a new server which hasn't been whitelisted yet. You check out the source over port 22, but you can't, because traffic from new-server to 22 is rejected.

The quick solution, you know this, is ssh port forwarding. Connect to old-server and forward connections to repository-server from there.

$ ssh old-server -L1234:repository-server:22

That works. For mercurial, at least.

$ hg clone ssh://walter@localhost:1234//srv/hg/myproject myproject
walter@localhost's password: 
requesting all changes
...

Okay, then a subversion project.

$ svn co svn+ssh://walter@localhost:1234/srv/svn/myproject/trunk myproject
svn: Network connection closed unexpectedly

What?

Running a tcpdump shows that what is really is going on, is that it's attempting to connect to host localhost:1234 on port 22!

20:34:42.436283 IP (tos 0x0, ttl 64, id 38321, offset 0, flags [DF], proto UDP (17), length 60)
    new-server.55451 > name-server.domain: 17380+ A? localhost:1234. (32)

Ok. So we need the forwarding on the right port. But we can hardly shut sshd down on the machine we're working on. What to do?

Selective port redirection using iptables.

Here you have to be aware that iptables does not do everything you might expect on the lo interface. Use a phony IP instead. The REDIRECT target ensures the traffic goes to 127.0.0.1 anyway.

$ nc localhost 22
SSH-2.0-OpenSSH_5.3p1 Debian-3ubuntu5  <-- self
^C
$ nc localhost 1234
SSH-2.0-OpenSSH_5.5p1 Debian-3  <-- repository-server
^C
$ sudo iptables -t nat -A OUTPUT -p tcp -d 1.2.3.4 --dport 22 -j REDIRECT --to-ports 1234
[sudo] password for user: 
$ nc 1.2.3.4 22
SSH-2.0-OpenSSH_5.5p1 Debian-3  <-- SUCCESS! the repository-server, on port 22
^C

$ svn co svn+ssh://walter@1.2.3.4/srv/svn/myproject/trunk myproject
walter@localhost's password: 
...

That was a PITA. Enough time wasted. Time to get some actual work done ;-)

shell