DEV Community

dpm_bush
dpm_bush

Posted on

SSH ControlMaster: Reuse Connections Without Creating a Mess of Sockets

If you regularly connect to the same server, each ssh, scp, or rsync command normally starts a new SSH connection. That means another handshake and, depending on your setup, another authentication prompt.

OpenSSH can reuse an existing connection instead. This is called connection multiplexing. It can make repeated commands quicker and reduce the number of separate connections, but it also introduces a socket file that you need to manage safely.

How connection multiplexing works

The first SSH connection acts as the master. OpenSSH creates a local Unix-domain socket, and later SSH commands connect to that socket rather than negotiating a separate SSH session.

The master connection still communicates with the server. Reuse does not bypass SSH authentication or encryption; it lets additional local client processes share the already-authenticated transport.

A minimal configuration looks like this:

Host build-vps
  HostName 203.0.113.25
  User deploy
  ControlMaster auto
  ControlPath ~/.ssh/control-%C
  ControlPersist 10m
Enter fullscreen mode Exit fullscreen mode

Connect as usual:

ssh build-vps
Enter fullscreen mode Exit fullscreen mode

While that connection is open, a second terminal can run another command using the same transport:

ssh build-vps 'uptime'
Enter fullscreen mode Exit fullscreen mode

The Host alias and the other connection settings belong in your SSH client configuration, which is also where you can define keys, ports, and jump hosts.

What the options mean

  • ControlMaster auto lets a connection become the master if one does not already exist, or reuse an existing master.
  • ControlPath is the local socket path clients use to find the master.
  • ControlPersist 10m keeps the master available for ten minutes after its initial session ends. A value of yes keeps it around until explicitly closed or the connection fails.
  • %C expands to a hash based on connection details, helping give different destinations distinct socket names without long paths.

The socket path must fit within the operating system's Unix socket path limit. Using a short path under ~/.ssh helps avoid errors such as ControlPath too long. Ensure the directory is private:

chmod 700 ~/.ssh
Enter fullscreen mode Exit fullscreen mode

Do not put a shared control socket in a directory writable by other users. A user who can access the socket may be able to use the authenticated connection.

Check whether a connection is being reused

Run SSH with verbose output:

ssh -v build-vps 'hostname'
Enter fullscreen mode Exit fullscreen mode

Look for a message indicating that an existing master connection is being used. If SSH opens a fresh connection instead, check that the Host pattern matches the name you are connecting to and that both commands use the same effective connection settings.

You can ask the master for its status with the control socket command:

ssh -O check build-vps
Enter fullscreen mode Exit fullscreen mode

To close it deliberately:

ssh -O exit build-vps
Enter fullscreen mode Exit fullscreen mode

These commands use the configuration’s ControlPath. If the alias or configuration has changed since the master was started, the client might not find the socket. In that case, inspect the socket path configured for the host and remove a stale socket only after confirming the master is gone.

Avoid accidental sharing across different connections

The control socket identifies a connection, not merely a server name. If you reuse the same socket path for connections with different users, ports, or jump-host routes, one connection can conflict with another.

Using %C in ControlPath is a practical way to avoid many collisions. You can also use a dedicated directory and include a hash:

Host *
  ControlMaster auto
  ControlPath ~/.ssh/cm-%C
  ControlPersist 5m
Enter fullscreen mode Exit fullscreen mode

Global settings can be convenient, but consider whether every host should keep a reusable connection open. For example, a short-lived automation command may not need persistence. You can disable it for a specific host:

Host temporary-host
  ControlMaster no
  ControlPersist no
Enter fullscreen mode Exit fullscreen mode

If you already use SSH configuration for per-host behavior, keep multiplexing rules there rather than maintaining slightly different command-line flags in scripts. The SSH command reference explains how command-line options interact with configuration values.

Understand the security and lifecycle tradeoff

With ControlPersist, logging out of the original terminal does not necessarily close the network connection. The master remains available until its persistence period expires, it is explicitly closed, or the connection drops.

That can be useful for a sequence of deployment commands, but it may not fit a shared workstation or a workflow where leaving an authenticated connection behind is undesirable. Set a finite persistence period, close the master when finished, and avoid forwarding the agent unless you specifically need it. Connection reuse does not require agent forwarding.

If the network drops, the master can become unusable. New commands then fail or attempt a new connection, depending on the situation. Multiplexing does not automatically reconnect a lost session. SSH keepalives can help detect an unresponsive connection, but they do not guarantee recovery; see this guide to SSH keepalive settings for what those options do and do not solve.

When it is worth enabling

Multiplexing is most useful when several commands run against the same host in a short period: deployment scripts, repeated remote checks, or a workflow that opens a shell and transfers files alongside it. It is less useful for occasional connections, and persistence may be unnecessary for one-off jobs.

Start with a short ControlPersist interval, test the configuration on a non-critical host, and verify that you can close the master. That gives you the speed benefit without leaving an authenticated connection open indefinitely.

I'm building SSHFlow — an SSH client that organizes terminals, SFTP, code editing, and server tools into workspaces.

Top comments (0)