To Be or Not To Be!!!

Just another weblog

Port-forwarding with ssh

How do I do port-forwarding with ssh?

If you can ssh out from a firewalled machine, you can ask ssh to set up a tunnel back to that machine, so that it can be reached from the outside world.

Here's how.

the purposes of this explanation, the "inside" machine is the machine inside the firewall — the one you want to be able to reach. The "outside" machine is the one that will be forwarding connections to the inside one. Also note that when I say "ssh", I mean ssh version 1. There is an ssh version 2, but it's commercial and nobody uses it (and it's incompatible with version 1) — so to avoid confusing yourself, don't even look at it. Use ssh version 1.

1. Create a key

The first thing you need to do is create an ssh "identity" key that doesn't have a password set — it just uses RSA keys to authenticate. (You need this because you're going to be running ssh in the background and you don't want it asking you for a password when you're not around.)

On the inside machine, go into your .ssh/ directory (the one inside your home directory — if you don't have one, go ahead and create it) and type:

ssh-keygen -f tunnel -C "tunnel key"

It will do a little song and dance, and ask you for a password. Just hit enter here — you don't want a password set on this key.

When you're done, you'll have a file tunnel (this is your private key — protect it!) and a file (the public key).

2. Add the key to the outside machine

You need to let the outside machine know this new public key, so it'll let you login without a password (using this key). On the outside machine, go into your .ssh/ directory and edit the file authorized_keys. (If this file doesn't exist, it's okay to create it.) This is somewhat annoying, but what you want to do is copy the contents of (from the inside machine) into one line of your authorized_keys file. It's important that the line be identical, and that it be one line. (Sometimes cut-and-paste will insert linefeeds — be careful and check it.) It should work now.

But to be safe, you ought to also limit the places this key can be used from. Since you're only going to use this key to set up an automatic tunnel from the inside machine, you can set this key so that it will only work for connections coming from there. To do that, add a from= section to the beginning of the line in authorized_keys.

For example, if your inside box is, the line in authorized_keys should look like this:

from="" 1024 37 1283091749021[…]923492

In other words, you want from="inside IP", followed by a space, to be at the front of the line. This is optional, but highly recommended.

3. Checkpoint

If you've done everything right up till now, you should be able to use this command on the inside machine:

ssh -i ~/.ssh/tunnel

and ssh should connect you to the outside machine and login as you, without asking you for a password. If that isn't what happened, something got messed up along the way — start over. If that is what happened, you're halfway there.

4. Backwards port redirect

This is the interesting part. Ssh has the ability to, after connecting to a machine, listen to a TCP port on that machine, and redirect traffic over the ssh connection back to the ssh client's machine. It's done with the -R option:

-R far-port:local-address:local-port

If the inside machine is named "squirtle", and the outside machine is named "", you can type this command:

ssh -i ~/.ssh/tunnel -R 3939:squirtle:23

It will connect you to, as before, but this time it also starts listening on port 3939 on, and forwarding traffic to squirtle's port 23 (the telnet port). So, anyone who telnets to port 3939, is effectively telnet'ing to squirtle's login prompt. Hopefully this makes you nervous. You should be really careful about this, because now anyone that finds this port can try to login to squirtle. And it's not exactly hard to find the port. 

It would be even better if you used port 22 (the ssh port) instead of port 23 (the telnet port) since most systems have sshd running now. That's definitely more secure.

5. Automating it

One thing you can do, if you don't give a crap about the security of squirtle (the inside machine), is to just leave the connection up 24/7. I know at least one (unnamed) company where this is happening. To do that, just run a script like this one the inside machine:


while `true`; do

     ssh -i ~/.ssh/tunnel -R 3939:squirtle:23 sleep 32000

     sleep 1


Adding the sleep 32000 to the ssh command makes it execute that command (on the remote machine — i.e. the outside machine) instead of giving you a login shell. This is what you want for scripts. Another thing you could do is set up a "time window" that the tunnel will be open. Set it up as a cron job that goes off at, say, every 2-3 hours and leaves the connection up for 15 minutes (just change the sleep time on the ssh command line to 900). If you're really perverse like me, you could run a bot on the inside machine, and run some Tcl scripts on a botnet so that anyone on the botnet could do a command that causes the bot on the inside machine to open up the tunnel. If that sounds cool to you, go write it yourself — don't ask me for help. 🙂



Tháng Sáu 23, 2006 - Posted by | Network and Security

Không có bình luận

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập: Logo

Bạn đang bình luận bằng tài khoản Đăng xuất /  Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Đăng xuất /  Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất /  Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất /  Thay đổi )


Connecting to %s

%d bloggers like this: