Advanced SSH Techniques

SSH Series: Part 5
Posted by Munish Mehta on Saturday, January 25, 2025
Elevate Your Remote Access: Master Advanced SSH Techniques for a Smoother, More Secure Workflow!

This article is part of a series.

ssh

I hope you’ve been enjoying our journey through the world of SSH. So far, I’ve covered the basics, key-based authentication, and best practices for hardening your SSH setup. In this post, I’m going to guide you through advanced SSH techniques that can streamline your workflow and expand what’s possible with secure connections. I will dive into tunnelling and port forwarding, how to hop through jump hosts, customizing the ~/.ssh/config file to simplify your life, mounting remote directories via SSHFS, and even reusing connections with multiplexing.

SSH Tunnelling and Port Forwarding

What Is SSH Tunnelling?

SSH tunnelling, or port forwarding, is a method that uses an encrypted SSH connection to transmit data from one network port to another. This is incredibly useful if you need to securely access a service running on a remote machine or forward traffic through a secure channel.

Local Port Forwarding

Local port forwarding “forwards” traffic from a local port on your machine to a remote host/port through an SSH server.

ssh -L <local-port>:<target-host>:<target-port> user@ssh-server
  • <local-port>: Any free port on your local system (e.g., 8080).
  • <target-host>: The remote machine or service you want to reach (e.g., localhost or an internal IP).
  • <target-port>: The port on <target-host> that the service is running on.

Example
If you have a web server running on a remote private network accessible only from ssh-server, you can forward port 8080 on your local machine to port 80 on that remote web server:

ssh -L 8080:localhost:80 user@ssh-server

Now, when you open your local browser at http://localhost:8080, you’ll see the website served by ssh-server’s port 80. It’s a secure tunnel because all traffic travels over SSH.

Remote Port Forwarding

Remote port forwarding does the opposite: it opens a port on the SSH server and forwards traffic back to your local machine or another host. This is handy if you need to make a service on your local machine accessible to a remote server.

ssh -R <remote-port>:<target-host>:<target-port> user@ssh-server
  • <remote-port>: The port to open on the SSH server (e.g., 9000).
  • <target-host>: The machine where the service actually runs (often localhost if it’s on your local machine).
  • <target-port>: The service’s port on <target-host> Example
    If you have a web app running on your local machine’s port 3000, and you want a remote server to access it:
ssh -R 9000:localhost:3000 user@ssh-server

A process on ssh-server can then access your local web app at http://localhost:9000.

Dynamic Port Forwarding (SOCKS Proxy)

Dynamic port forwarding is like creating a SOCKS proxy on your local machine. This allows you to route traffic for multiple destinations via SSH, making it excellent for securely browsing or tunnelling various protocols through one port.

ssh -D <local-port> user@ssh-server
  • <local-port> is your local SOCKS proxy port, like 1080.

In your applications (like a web browser), configure a SOCKS proxy pointing to localhost on port 1080. All traffic is then routed securely through ssh-server.

Best Practices for Tunnelling

  • Limit Access: Use firewalls or AllowUsers rules so only authorized users can create tunnels.
  • Use Key Authentication: Prevent password-based brute force.
  • Monitor Usage: Tunnels can inadvertently expose internal services, so watch logs.

Jump Hosts, SSH Config, and Multiplexing

Using Jump Hosts / Bastion Hosts

Sometimes, you need to SSH into an internal server that’s only reachable via a bastion (or jump) host in a DMZ. Instead of manually SSHing into the bastion and then the internal server, you can simplify this with ProxyJump:

ssh -J user@bastion-host user@internal-server

This command tunnels your SSH session through bastion-host to internal-server, in one shot.

Alternatively, if you’re using older SSH versions that don’t support -J, you can use ProxyCommand in your SSH config file.

Customizing ~/.ssh/config

I find customizing my SSH config file a huge time saver. You can define aliases, specify different ports, and set advanced options for specific hosts.

Example ~/.ssh/config:

Host bastion
    HostName 198.51.100.10
    User jumpuser
    IdentityFile ~/.ssh/id_ed25519

Host internal
    HostName 10.0.0.5
    User admin
    ProxyJump bastion
    IdentityFile ~/.ssh/another_key
    Port 2222

Now, a simple ssh internal command takes you through bastion to 10.0.0.5. You don’t have to remember IPs, ports, or the jump command each time.

SSH Multiplexing

SSH multiplexing allows you to reuse existing SSH connections so you don’t have to create a new handshake each time. It’s particularly helpful if you frequently open multiple sessions to the same server or use scp/rsync in quick succession.

  1. Edit ~/.ssh/config:

        Host *
            ControlMaster auto
            ControlPath ~/.ssh/sockets/%r@%h:%p
            ControlPersist 5m
    
  2. Create the sockets directory if needed:

    mkdir -p ~/.ssh/sockets
    
  3. How It Works:

    • ControlMaster auto: Enables multiplexing if a master connection exists.
    • ControlPath: Defines where the master socket file is stored.
    • ControlPersist 5m: Keeps the master connection open for 5 minutes after the last session closes.

Now, when you initiate an SSH connection, subsequent SSH commands (like more terminals or scp) instantly reuse the open channel.

SSHFS — Mounting Remote Directories Locally

SSHFS (SSH File System) lets you mount a remote directory on your local machine over SSH. You can then access remote files as if they’re on your local filesystem.

Installing SSHFS

  • Ubuntu/Debian:

    sudo apt-get update
    sudo apt-get install sshfs
    
  • CentOS/Fedora:

    sudo yum install sshfs
    
  • MacOS: Install via Homebrew

    brew install sshfs
    

Mounting a Remote Folder

mkdir ~/remote_mount
sshfs user@remote-server:/path/to/folder ~/remote_mount
  • ~/remote_mount: A local directory where you want the remote folder to appear.
  • /path/to/folder: The directory on the remote server.

Now, you can read and write files in ~/remote_mount just like local files.
When done:

fusermount -u ~/remote_mount     # Linux
umount ~/remote_mount            # macOS or older distributions

Use Cases

  • Editing Remote Files
    • Seamlessly open remote project files in your local IDE.
  • Backing Up Data
    • Copy large files across servers without repeated SSH commands.

Best Practices and Tips

  • Security
    • Remember that all these advanced techniques (tunnels, jump hosts, SSHFS) are only as secure as your SSH setup. Ensure you follow best practices from our previous posts, like key-based auth and Fail2Ban.
  • Performance
    • Tunnelling can introduce overhead. If you notice lag, check ne
  • twork speeds, or adjust compression options with -C.
  • Automation
    • Combine advanced techniques with scripts or config files for seamless workflows. For instance, setting up a tunnel in a systemd service or an alias in your shell.

Wrapping Up

I hope I’ve shown you just how versatile SSH can be when you go beyond the basics. Whether you’re securely browsing the web with a SOCKS proxy, hopping through a bastion host, or mounting remote directories via SSHFS, these techniques can save you time and enhance your security.

  • Part 1: We explored SSH Tunneling & Port Forwarding (local, remote, dynamic).
  • Part 2: We looked at Jump Hosts, .ssh/config tricks, and Multiplexing.
  • Part 3: We finished with SSHFS for mounting remote directories locally.

In the next post, we’ll continue our exploration with more troubleshooting tips or automation strategies (depending on your reading path). Feel free to leave a comment if you have any questions or favourite SSH tips of your own. Happy connecting!

This article is part of a series.


comments powered by Disqus