Ssh forwarding is powerful stuff, but using it can be confusing.
For example, let's say we have a machine that our firewall will send
traffic to, but we actually want to ssh to another internal machine.
To be specific: 192.168.2.1 is the machine that we can access from
outside using "server.xyz.com", but we really want to ssh to
192.168.2.10 with user "fred". To make it even more interesting,
"fred" isn't a valid username on 192.168.2.1, but "john" is. We know
passwords for both accounts.
The first step is to ssh to the server:
ssh [email protected]
That lands us on 192.168.2.1. We now want to create a port that
will get us to the other machine:
ssh -L 11601:192.168.2.10:22 -l john localhost
That says to take traffic coming in on port 11601 and send it
along to port 22 on machine 192.168.2.10. Ssh requires a user
name to do this, so we give it john (the local user).
If we now go to another machine and do:
ssh -p 11601 [email protected]
(If you are playing with this from the same machine, it's going to
get confused about "[email protected]" and you may have to edit
your known_hosts file to convince it that it's ok to connect.)
The ssh forwarding passes us over to 192.168.2.10. Notice
that we used "[email protected]" even though "fred" has no account
at this server. Remember that it's being forward to the machine where fred
does have an account.
Before we go on, if you've actually tried this, try logging
out of the shell that you started with "ssh -L 11601:192.168.2.10:22 -l john localhost". Notice that it hangs until you quit out of your
"fred" ssh or kill it here (ctrl-C should work). I used
that behaviour to advantage at Spamassassin on Mac OS X to secure a pop
connection with ssh forwarding.
Using port 11601 may be fine, but we're assuming that all
Internet traffic comes to this machine - perhaps it is a dual-nic
gateway. Perhaps instead it is behind a router and only some ports
are allowed through. In that case, perhaps what we really want
to do is forward port 22 itself. But we can't do that as "john":
ssh -L 22:192.168.2.10:22 -l john localhost
Privileged ports can only be forwarded by root.
For security reasons, only root can over-ride the "well-known"
or "privileged" ports.
Well, no problem: we have root's password or can sudo:
$ sudo ssh -L 22:192.168.2.10:22 -l john localhost
Last login: Wed Jun 14 19:19:46 2006 from localhost
Welcome to App2!
Notice the two login prompts: the first was for sudo. Also notice
that we're still using john for the second: we need to be root to
forward port 22 but we still can use the ordinary user account for the login.
We can fork that forwarding off into background:
$ sudo ssh -f -N -L 22:192.168.2.10:22 -l john localhost
The "-f" does the fork, the -N removes the need to run a command
(forking would ordinarily require that).
Just because you can forward a port doesn't mean that the application
you want to use will be happy with your mangling. For example,
I have a customer with a router that can be accessed with a web
browser through the local lan only. I can access a machine on their lan with
ssh, but the router doesn't work with Lynx. Therefore,
I'd like to forward a port to 80 on the router. More restrictions,
though: we only pass a few ports inward. One of those is ftp, so
you'd think I could do:
$ sudo ssh -L 20:220.127.116.11:80 -l admin localhost
and indeed I can, but Firefox won't play along. If you try
"http://xyz.com:20", Firefox refuses you outright.
You don't necessarily need to do these forwardings manually. They
can be added to your .ssh/config file:
LocalForward 11601 192.168.2.10:22
That sets up the forwarding as we log in. You can get much
trickier with that; see Breaking Firewalls with OpenSSH and PuTTY. That
could get around the problem I described above with limited ports (though
I use VNC for this).
Ssh forwarding is indeed powerful stuff.
Got something to add? Send me email.
Increase ad revenue 50-250% with Ezoic
More Articles by Anthony Lawrence
Find me on Google+
© 2012-07-13 Anthony Lawrence