A Guide for Common SSH Use Cases

A Guide for Common SSH Use Cases

What is SSH

SSH is a network protocol allowing two machines (physical or virtual) to establish an encrypted connection and comminucate with each other over an unsecure network without compromising the confidentiality and integrity of the exchanged messages. The protocol uses public-key (a.k.a. asymmetric) cryptography to authenticate an SSH client that wants to connect to an SSH server.

OpenSSH is an implementation of the SSH protocol. All the usage examples given in the next sections are based on it.

SSH Basic Usage

A very common usage of SSH is to login to a remote server. Assuming you have a private/public key pair on your local machine and the public key is also distributed on the server you are trying to login to, then connecting is as simple as running:

ssh <server domain name>
ssh myserver.com

This assumes two things:

  • you have an SSH agent running with the appropriate private key added or the path to the private key follows a standard naming convention (e.g. ~/.ssh/id_rsa) - you might need to run ssh-add <path to private key> if this is not the case
    • ~/.ssh/id_rsa is one of the standard naming conventions that the SSH client automatically attempts to use when authenticating with a server
  • you want to authenticate with the username on your local machine
    • this assumption will not hold if on my laptop I use something like nikolay as the username but on a server running Ubuntu only the ubuntu user exists

The following command can be used to change the username to authenticate with:

ssh <username>@<server domain name>
ssh ubuntu@myserver.com

Advanced SSH Usage - Tunneling

A more advanced usage of SSH is the so called SSH tunneling (a.k.a. SSH port forwarding). SSH tunneling is a process of establishing communication between a client (in this case, your local machine) and a server (a remote machine) through a jump server (the machine running an SSH server). This is achieved by mapping ports between the client and the SSH server (hence the name "port forwarding").

This can be visualized with the following diagram:

Screenshot 2022-06-13 at 10.10.58.png

Keep in mind that the remote machine might be the jump server itself.

There are 3 types of port forwarding, the behavior of which will be illustrated in the following sections. All the example commands assume that the client's public key is already distributed to the SSH server and that the client can successfully login to the SSH server using the command given in the previous section.

N.B. remember that if using a different username on your local machine and on the SSH server, then you need to include <SSH server username>@ in front of all the "jump server" references for the examples below to work - for example, instead of mysshserver.com you might have to use something like user@mysshserver.com

Local Port Forwarding

Local port forwarding is the process of tunneling connections initiated by the client machine through a jump server and forwarding these connections to a remote server or the jump server itself.

To initiate this, run the command below on your local machine:

ssh -N -f -L <local port>:<target server domain name>:<remote port> <jump server domain name>
ssh -N -f -L 5001:mytargetapp.com:5002  mysshserver.com

With the example above, all connections to port 5001 on your local machine will be tunneled (in an encrypted manner) to the SSH jump server (mysshserver.com) and then forwarded to mytargetapp.com at port 5002.

Screenshot 2022-06-13 at 11.35.09.png

The CLI flags are explained below:

  • -L - this is the key flag that instructs the SSH client to execute local port forwarding
  • -N - by default the SSH client will open a session even when executing local port forwarding; this flag instructs the client to not execute a remote command (i.e. only forward ports)
  • -f - this instructs the ssh client to run in the background (so that you don't need to keep your terminal open while port forwarding is running)

Another example where we are not forwarding to a remote machine but to the jump server itself:

ssh -N -f -L 5001:localhost:5002  mysshserver.com

With this, any connections to port 5001 on your local machine are tunneled to port 5002 on the jump server itself (mysshserver.com).

Screenshot 2022-06-13 at 11.47.18.png

Remote Port Forwarding

Remote port forwarding is the reverse process of local port forwarding - forwarding connections initiated by a remote machine (or the jump server itself) through the jump server and tunneling these connections back to your local machine on the specified target port.

To initiate this, run the command below on your local machine:

ssh -N -f -R <remote port>:localhost:<local port> <jump server domain name>
ssh -N -f -R 5001:localhost:5002  mysshserver.com

The example above shows a scenario where port 5001 will be open for connections on the jump server (mysshserver.com), any connection to it will be tunneled back to your local machine (in an encrypted manner), and then forwarded to the application listening on the target port - 5002.

Screenshot 2022-06-13 at 11.04.30.png

The only new CLI flag in this case is -R which instructs the SSH client to execute remote port forwarding. Remote port forwarding is a very common solution if you want to temporarily expose an application running on your local machine to the public (assuming the SSH server is publicly available on the internet) or to someone that has network access to the SSH server in general (for example, through a VPN).

Dynamic Port Forwarding

Dynamic port forwarding is similar to local port forwarding in the sense that local connections are tunneled (in an encrypted manner) to the SSH jump server. The difference is that with dynamic port forwarding you don't need to specify a target host or port - all connections are forwarded to the original target host and target port through the SSH server. In technical terms, dynamic port forwarding is the process of using the SSH server as a SOCKS5 proxy server.

To initiate this run:

ssh -N -f -D <local proxy port> <jump server domain name>
ssh -N -f -D 1080 mysshserver.com

The new CLI flag in this case is -D which instructs the SSH client to execute dynamic port forwarding. The recommendation is to use port 1080 as it is the standard SOCKS protocol port number.

Then you can configure your browser (say Firefox - see this tutorial) or any other application that supports SOCKS/SOCKS5 proxies to use this tunnel and securely forward your network traffic through the SSH jump server (mysshserver.com). In essense, this gives you a very basic VPN functionality by hiding data about your local machine - websites you visit will see traffic that seems to be coming from the SSH server.

Screenshot 2022-06-13 at 12.21.48.png

The diagram above illustrates an example where the client is accessing somewebsite.com through dynamic port forwarding. The browser uses the proxy to connect to the website. The communciation between the local machine and the SSH server (mysshserver.com) is encrypted. The SSH server then forwards the request to the actual website. From the perspective of somewebsite.com the conenction was initiated from the SSH server rather than the local machine.