How to make better use of SSH

I have seen this more often than not: even technical or advanced users who use SSH almost daily, do not understand how versatile this can be and for what scenarios it is more than suitable.

Not only they don't appreciate the key-based authentication, but are unaware of all the benefits of the encryption that's used there. So next time your sysadmin says "I can't make the access secure..." make him read this.


Secure shell

We all know the SSH stands for "secure shell", an encrypted remote connection to a server. We also know that it uses both symmetric and asymmetric crypto:

the asymmetric cryptography handles SSH's initial key exchange and authentication: the client and server use public-private key pairs to negotiate a shared secret securely without prior secrets. Symmetric cryptography then encrypts the entire session's data (commands, outputs) using that pre-established shared secret because symmetric encryption is must faster than asymmetric encryption.

So far so good, but how can we use SSH for something else than remote connection? What about tunneling other traffic, like http? Would it be useful? You bet, especially for connections where we don't want to expose sensitive data.

When your database admin needs to access a database remotely and the database or the system on which it is running can't provide an encrypted transport, like via https, then SSH can come to rescue.

SSH Tunneling: using SSH as a secure transport layer

With SSH we can access services that were never designed to be exposed securely: internal application login screens, legacy admin interfaces, or applications that still rely on plain HTTP. These systems are often “protected” by network placement rather than encryption, which breaks down as soon as traffic crosses an untrusted network.

SSH in practice is really a general-purpose encrypted and authenticated transport for TCP connections. Once an SSH session is established, it can carry arbitrary network traffic securely between two endpoints, through an encrypted "tunnel".

SSH tunneling uses port forwarding and works by changing where a connection appears to originate. A local port is opened on the client machine and bound to a service reachable from the SSH server. When an application connects to that local port, SSH encrypts the traffic and forwards it through the existing SSH session, delivering it to the target service as if the connection came from the SSH server itself. ("SSH server" = host where our application/database with an insecure interface is running)

For example, an internal web interface that only supports HTTP can be accessed safely by forwarding a local port to the remote web server over SSH. The browser connects to localhost, while the actual HTTP traffic is encrypted in transit. The web application remains unchanged, but credentials and session data are protected on the wire.

SSH tunneling is not a substitute for proper application-level security such as HTTPS, but it is a powerful tool for securing legacy systems, restricting access paths, and safely operating services that were never designed to face hostile networks.

Examples

The standard form of a SSH tunnel may look like this (omitting the localhost part):

ssh -N -L 8081:127.0.0.1:3306 user@host

but this one is more precise (specifies the localhost or local IP address to bind to):

ssh -N -L 127.0.0.1:8081:127.0.0.1:3306 user@host

This command forwards a local TCP port (8081) to a service listening on port 3306 on the remote host (a typical mysql/mariadb port). By explicitly binding the local end of the tunnel to 127.0.0.1, the forwarded port is only accessible from the local machine.

  • 127.0.0.1:8081- is the local system, from which we are creating the tunnel,
  • 127.0.0.1:3306 - is the remote system, where the tunnel ends; why 127.0.0.1 also there? That's because the remote system listens on port 3306 only locally (that's important to know and do), 0.0.0.0:3306 would make it listen on the network (which we want to avoid)

If the binding address is omitted:

ssh -N -L 8081:127.0.0.1:3306 user@host

SSH may bind the local port to all available interfaces. On modern dual-stack systems, this can include IPv6 (::) as well as IPv4, potentially making the forwarded port reachable from outside the host, depending on system configuration and firewall rules.

Explicitly specifying 127.0.0.1 ensures that the tunnel is strictly local, avoids ambiguity across IPv4/IPv6 implementations, and makes the security properties of the tunnel obvious to both the user and the system.

When using SSH as a transport, being explicit about addresses is part of the security boundary.