Skip to main content

Speed up SSH with connection sharing

·3 mins
Table of Contents

If you’re like me, you open a lot of different terminal sessions throughout your day. When it comes to SSH, I want these different sessions to share a connection rather than creating a new one each time.

This applies to all SSH based traffic. Whether you are using ansible, git or scp/rsync, every connection will now be instantaneous.

To make this happen, you just need to add a few lines to your SSH config that tells SSH to look for an existing master connection before trying to start a new one.

The Host * is a wildcard. It’s like saying, apply these settings to every connection I make:

Host *
    ControlMaster auto
    ControlPersist 10m
    ControlPath ~/.ssh/sockets/socket-%r@%h:%p

If you only want to use this for specific a Host , you would nest the settings like this:

Host homelab-testing
     HostName 192.168.100.210
     User kavish
     IdentityFile ~/.ssh/id_rsa
     ControlMaster auto
     ControlPersist 10m
     ControlPath ~/.ssh/sockets/socket-%r@%h:%p

For this configuration to work, the directory where the sockets are stored must exist on your machine and is writable only by your $USER:

mkdir -p ~/.ssh/sockets
chmod 700 ~/.ssh/sockets

While you can name the sockets directory anything and place it anywhere, there’s no need to make it complicated. Just keep in mind that if the folder doesn’t exist, SSH will fail to create the bridge and will fall back to a standard connection.

My settings #

My preferred settings:

Setting Option What it does
ControlMaster auto Automatically starts a “Master” connection if one doesn’t exist, or reuses one if it does over a single network connection
ControlPersist 10m Closes the connection after 10 minutes after you exit your last active terminal window.
ControlPath ~/.ssh/sockets/socket-%r@%h:%p Defines where the “socket” file lives. It uses your username (%r), host (%h), and port (%p) to keep connections to different servers separate.

To see what other settings are available, take a look at man ssh_config.

How It Works #

  1. You run ssh homelab-testing. SSH sees no socket exists, creates one in ~/.ssh/sockets/, and establishes the Master tunnel.

  2. You open a second terminal and run ssh homelab-testing. SSH sees the socket, skips the handshake/keys, and jumps right into the existing tunnel.

  3. You type exit in the first terminal. Since your second terminal is still using the tunnel, the Master connection stays alive. It essentially hands over the responsibility of keeping the tunnel open.

  4. You type exit in the last terminal. Since ControlPersist is set to 10m, SSH waits for 10 minutes of inactivity. Once that time passes with no new connections, it closes the connection to the server and deletes the socket file.

It is hard to fail, but it is worse never to have tried to succeed.
Theodore Roosevelt.