HASH32 Engineering

SSH Tunnels - How to, with examples

January 31, 2019 | 8 Minute Read

SSH is secure shell, but its name is very misleading. It can be used for purposes other than as a shell. It provides an authenticated and encrypted channel to hosts in a network.

In this post, lets see how it can be used for port forwarding between servers. Port forwarding is also called tunneling.

Local Port Forwarding

With local port forwarding, you can access a remote server locally.

Lets consider an example of local port forwarding from localhost:8080 to remote-server:80. Then accessing localhost:8080 in your browser, will show the contents of remote-server:80.

Note: If you are using EC2, open port 80 on the server by adding it to the Inbound Rules in the Security Policy.

local="localhost:8080"
remote="remote-server:80"

ssh -L ${local}:${remote} remote-server

To run this in the background use the following:

ssh -fNn -L ${local}:${remote} remote-server

# -f      Requests ssh to go to background just before command execution.
# -N      Do not execute a remote command.
# -n      Redirects stdin from /dev/null (actually, prevents reading from stdin)

Remote Port forwarding

Remote port forwarding allows you to access a server running on your local machine from a remote address.

Example: If you are running a Rails server at localhost:3000, doing a remote port forwarding from a public-host to localhost, will allow you to access the server with the http://public-host url.

Due to security reasons, only the loopback interface is enabled for remote port forwarding. Change this in the SSH config file(located at /etc/ssh/sshd_config) of the public-host by changing GatewayPorts yes.

local="localhost:3000"
remote="*:80"

# Run this in local server
ssh -R ${remote}:${local} public-host

# Run in background
ssh -fNn -R ${remote}:${local} public-host

Usecases

Here are some of the usecases for port forwarding.

Encrypted traffic between app server and database

When the traffic between a DB client and server is not encrypted, hackers can sniff passwords. And manipulate queries, injecting unwanted SQL queries. Watch this video that shows how a hacker can access unencrypted SQL Server traffic.

To leverage performance, web servers and database servers are hosted in separate machines. So it is ideal to encrypt the traffic between the web and DB servers. Using SSL is one way to encrypt the connections. All popular databases provides options for configuring SSL. The other easier option is SSH tunneling.

For example, lets say a webserver is running on an EC2 instance with hostname webserver and a postgres database server is running on port 5432 on another EC2 instance, with the hostname dbserver.

To create a tunnel between these, run the following from webserver.

ssh -fNn -L 4321:dbserver:5432 -i pemfile.pem ec2-user@dbserver

Now, the webserver’s database connection should be configured to use localhost:4321.

Note: For security purposes run the sshd daemon in the dbserver in a port number other than the default 22. Also, block access to all other ports in the security rules for your machine (or a firewall).

Read about configuring encrypted connections with SSH tunneling in MySQL v5.7 and PostgreSQL v11.

Access your local dev machine from a domain

You can route the traffic in a server port to your local machine.

Say, a sinatra server is running on port 4567 in your personal laptop, and you have SSH access to a server with the domain name my-domain.com.

Create a SSH tunnel to this server with the following command:

ssh -fNn -R my-domain.com:33770:127.0.0.1:4567 -i pemfile.pem ec2-user@my-domain.com

This will allow you to access the sinatra app at port 33770 in http://my-domain.com:33770.

You can also substitute my-domain.com with the publicly facing IP address of the machine.

Note: When running the remote domain on EC2, I faced a SSH connection issue, which got resolved when using an ephemeral port like 33770. Read about it in this SuperUser answer.

You do not need a server with sshd daemon running for this. Use a service like Serveo, which provides servers you can ssh into.

Security concerns

You can use port forwarding to access servers in the enterprise from the local machine, which is a blessing in disguise. This can expose the organization to security risks and backdoor attacks. System admins should disable port forwarding to critical systems in the enterprise network. Also, update systems regularly to fix security issues in SSH or other services. Such steps can help mitigate exploitations of known CVEs.

Fun Projects

You can do all kinds of fun things with SSH. Checkout ssh-chat, written in go-lang to chat via ssh, that shows up a chat prompt.

The header Photo by Thomas Jensen on Unsplash.

Subscribe to our Newsletter

Get stories like the directly to your inbox once every two weeks.
Tips and tricks, news about tech tools, recent blog entries and exclusive email only stories.