How to Set Up SSH Tunnel

I was setting up a distributed monitoring system recently. At local machine, I has a program named “proga”, trying to access a remote server named “remote” at port 5667. However, the port is blocked by the enterprise firewall.

This is easy to solve by SSH tunneling.

ssh -f roman10@remote -L 5668:remote:5667 –N

This command sets up the SSH tunnel for accessing port 5667 of remote server from my localhost.

-f: ssh goes to background before it executes the command.

roman10: my user name at remote server

-L 5668:remote:5667: forward the traffic received at localhost 5668 to remote server at 5667. More generally, -L [bind_address:]port:host:hostport: Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side.

-N: do not execute a remote command.

After authentication, the tunnel will be set up. After that, I can simply access the remote port by sending traffic to 5668 at localhost.

One can make sure the remote 5667 port is open by the command at remote host,

netstat -nan | grep 5667

After that, use telnet to test the tunnel at localhost,

telnet localhost 5668

If it connects, we have set up the SSH tunnel successfully.

How to Set up Reverse SSH

In my work, I used SSH a lot for remote access, including Amazon cloud server. It works with the following simple command,

ssh dest_user_name@dest_ip_or_domain_name

For example, the remote machine has an IP of 137.175.128.23, and the user name is test, then we simply enter the following command,

ssh test@137.175.128.23

This requires the remote side to have a public IP address. If we want to ssh to a computer which sits behind firewall and NAT, then the computer won’t be visible to us and SSH won’t work.

That’s where the reverse SSH comes into play.

Reverse SSH doesn’t require the destination to have a public IP address, instead the public IP address could be with the source side, or a middle machine between source and destination. We’ll cover both cases below.

(Throughout this tutorial, we’ll use 137.175.128.23 as public IP for our machine, no matter it’s at the source side or dest side, and “test” as the username for the machine with public IP.)

1. Access Remote Side from Source with Public IP

First, consider the case we have a public IP address at source, and we want to access a destination computer in a private network.

At the destination, type the command below,

ssh –R 12345:localhost:22 test@137.175.128.23

This command will create a tunnel between the source addr (137.175.128.23:12345) and the destination address (localhost[with private ip]:22).

Then at the source side, we ssh to local port 12345 by,

ssh dest_user_name@localhost –p 12345

This command will ssh to source port 12345, which has been connected with the remote side in previous step.

Therefore, the SSH tunnel is established as below,

dest addr (private_ip:22) <= source addr 1 (137.175.128.23:12345) <= source addr 2(137.175.128.23 : port_used_by_source_ssh_client)

Note that you’ll need both connections active to access the destination. In order to keep it alive, you can run command like “top” and “watch” to ensure there’s some data transmission.

Or you can add the following line to the /etc/ssh/ssh_config file:

ServerAliveInterval 60

The client will send keep alive message every 60 seconds in this case.

2. Connect Remote Side using Private IP, with Public IP as Middle Man

Now consider a situation where both source and dest have private IP addresses, then the public IP machine can serve as middle man.

We simply SSH to middle man first, then the reset is the same as previous case.

So first at source computer,

ssh test@137.175.128.23

After ssh to middle computer, at the middle computer,

ssh –R 12345:localhost:22 test@137.175.28.23

Finally, at source computer (probably you’ll need to open another console window),

ssh localhost –p 12345

How to Set up SSH Key Authentication

ssh is a great tool for remote access, especially under Linux. The command line based remote access can run smoothly on a slow network link.

Sometimes we access a remote machine so frequently that we want to get rid of the step of entering password every time. SSH actually allows key authentication, and it’s very easy to set up.

If you’re in a rush, a three-step quick guide is give below,

ssh-keygen –t dsa

cat ~/.ssh/id_dsa.pub | ssh remote_user_name@remote_ip “cat >> ~/.ssh/authorized_keys2”

ssh remote_user_name@remote _ip

For more details about each step, please read the explanation for each step below.

1. Generate Key Pair

Simple enter the following command,

ssh-keygen –t dsa

or, if you prefer rsa encryption,

ssh-keygen –t rsa

This will generate a public key (the file with .pub extension) and a private key (without .pub extension). You’ll need to put the public key to the remote side and keep the private key in a safe place.

2. Copy Public Key to Remote .ssh Directory

If remote server doesn’t have .ssh folder at home directory, run ssh-keygen on remote side to create one.

If there’s no authorized_keys2 file under .ssh folder, copy the public key to the remote side.

scp ~/.ssh/id_dsa.pub remote_user_name@remote_ip:~/.ssh/authorized_keys2

If there’s already a authorized_keys2 file, append the public key file content to the end of the authorized_keys2 file.

One can use a single command,

cat ~/.ssh/id_dsa.pub | ssh remote_user_name@remote_ip “cat >> ~/.ssh/authorized_keys2”

or execute the following steps.

First, copy the public key file to a temporary file at remote side,

scp ~/.ssh/id_dsa.pub remote_user_name@remote_ip:~/.ssh/tmpfile

Next ssh to remote side,

ssh remote_user_name@remote_ip

Finally, append the temporary file content to the end of authorized_keys2 file,

cat ~/.ssh/tmpfile >> ~/.ssh/authorized_keys2

3. SSH to remote Server without Password

Now you can ssh to remote side without password.

Note that if the first time you failed to ssh to remote side, you can simply log out from your computer and log in again. I don’t know why this works, but it fixes the issue.