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.
Credits Header Photo by Thomas Jensen on Unsplash.