SSH Multiplexing on Linux: Share One Connection

Deepak Prasad
Tested on RHEL 10.2 (Coughlan) — vm2.lab.example (192.168.56.220) as client to vm1.lab.example (192.168.56.116)
Package openssh-clients 9.9p1-25.el10_2
Applies to RHEL, Rocky Linux, AlmaLinux, Fedora, Ubuntu, Debian, and other Linux hosts with OpenSSH client support for connection sharing
Privilege SSH login to the remote host; write access to ~/.ssh/config and the control socket directory on the client
Scope Client-side ControlMaster, ControlPath, ControlPersist, verification with ssh -O, scp over a shared master, and closing the master. Does not cover ssh-agent setup, jump hosts, or server hardening beyond default session limits.
Related guides ssh command
Copy folder over SSH
scp command
OpenSSH authentication methods
Test SSH connection

Every new ssh session normally pays for TCP setup, key exchange, and authentication. SSH multiplexing skips that overhead on repeat visits: the first connection becomes a master, later ssh, scp, and sftp clients talk to it through a local control socket. SSH multiplexing is client-side — configure it on whichever host initiates the SSH, SCP, or SFTP connections. This walkthrough uses vm2.lab.example as the client and vm1.lab.example as the server.


What to configure on the client and server

Multiplexing is a client feature. The remote server does not have an "enable multiplexing" switch; it accepts one TCP connection and carries multiple channels the way SSH always has.

Where What you do Files or commands
Client (machine that runs ssh, scp, or sftp) Enable sharing, set the control socket path, open and close the master ~/.ssh/config, ~/.ssh/sockets/, ssh, scp, ssh -O check, ssh -O exit
Server (remote host you log into) Nothing required for multiplexing to work Normal sshd service and your usual SSH login
Server (optional) Raise per-connection session limits only if you hit them /etc/ssh/sshd_configMaxSessions, then reload sshd

Every procedural section below states whether you run it on the client or server. Unless noted, commands run on vm2.lab.example toward vm1.lab.example.


What SSH multiplexing does

OpenSSH connection sharing works entirely on the client. You point several tools at the same control socket path; they ride one encrypted TCP link to the server as separate channels.

The flow looks like this:

text
Client A (ssh master)  ──creates──►  control socket  ──►  one TCP connection  ──►  sshd
Client B (ssh/scp)     ──reuses───►  control socket  ──►       same TCP         ──►  sshd

The server does not need a multiplexing toggle. It accepts one connection and multiplexes channels the way SSH always has; the client decides whether to open a fresh TCP session or attach to an existing master.

Three client options matter most:

Option Typical value What it controls
ControlMaster auto First client opens the master; later clients reuse it when the socket exists
ControlPath ~/.ssh/sockets/%r@%h-%p Filesystem path to the control socket; must be unique per user, host, and port
ControlPersist 120 (seconds) Keeps the master alive after the last session closes so the next client can attach without re-authenticating

Placeholders in ControlPath keep socket names unique when you connect to the same host as different users or on non-default ports:

  • %r — remote username
  • %h — target hostname
  • %p — target port
  • %C — hash of %l, %h, %p, and %r (handy when paths must stay short)

Configure multiplexing in ~/.ssh/config (client)

On the client (vm2.lab.example in this lab), scope multiplexing to one remote host so the rest of your SSH targets stay unchanged. Edit ~/.ssh/config on the machine that initiates connections:

text
Host lab-server
    HostName 192.168.56.116
    User root
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 120

ControlMaster auto creates a master on the first ssh lab-server and reuses it afterward. ControlPersist 120 leaves the master up for two minutes after the last multiplexed session exits, which is long enough for a burst of scp copies without keeping the socket open all day.

You can pass the same options on the command line with -o ControlMaster=auto when a script should not depend on ~/.ssh/config.


Create the control socket directory (client)

On the client, OpenSSH does not create the directory in ControlPath for you. The socket file must live somewhere only your user can write:

bash
mkdir -p ~/.ssh/sockets

Set the directory mode so other users cannot reach your sockets:

bash
chmod 700 ~/.ssh/sockets

A mode of 700 on ~/.ssh/sockets matches what OpenSSH expects for private control state.


Open the first connection (client)

On the client, the first ssh to lab-server establishes the master connection and places a socket file under ~/.ssh/sockets/:

bash
ssh lab-server hostname

Sample output:

output
vm1.lab.example

That hostname confirms the session reached vm1.lab.example. The first hop always performs the full handshake; later hops attach through the socket you create here.


Verify the control socket (client)

Still on the client, list the socket directory to confirm OpenSSH created a control socket for this user, host, and port:

bash
ls -la ~/.ssh/sockets/

Sample output:

output
total 0
drwx------. 2 root root  36 Aug 21 13:15 .
drwx------. 3 root root 117 Aug 21 13:13 ..
srw-------. 1 root root   0 Aug 21 13:15 root@192.168.56.116-22

The s at the start of the mode column marks a socket file. The name root@192.168.56.116-22 comes from %r@%h-%p in ControlPath.

Ask OpenSSH whether a master is still running for this host block:

bash
ssh -O check lab-server

Sample output:

output
Master running (pid=12624)

The PID belongs to the background master process. While that line appears, new clients can multiplex without repeating authentication.


Reuse the master for another SSH session (client)

From the client, open a second session to the same host. With verbose logging, OpenSSH reports that it found an existing master:

bash
ssh -vv lab-server 'uptime -s'

Sample output (trimmed):

output
debug1: auto-mux: Trying existing master at '/root/.ssh/sockets/root@192.168.56.116-22'
debug1: mux_client_request_session: master session id: 2
2026-08-21 11:14:34

The auto-mux line is the signal that multiplexing worked. The remote command output (uptime -s here) still prints normally after the debug lines when you use -vv.

On a slow link or when authentication involves a hardware token, the time saved is mostly skipped handshakes rather than microseconds on a LAN. The bigger win is fewer password or MFA prompts during a deployment script.


Copy files over the shared connection (client)

On the client, scp honors the same ControlPath as ssh when both use the same Host block. With a master already running from the steps above, run verbose scp so OpenSSH prints whether it attached to that master:

bash
scp -v /etc/hosts lab-server:/tmp/hosts-copy

Sample output (trimmed):

output
debug1: auto-mux: Trying existing master at '/root/.ssh/sockets/root@192.168.56.116-22'
debug1: mux_client_request_session: master session id: 2
scp: debug1: truncating at 415

The auto-mux line is the proof that scp reused the existing connection. A successful copy alone only shows that the transfer worked; verbose multiplexing output shows it did not open a second TCP session.


Multiplex from the command line (client, no config file)

On the client, automation sometimes needs a dedicated socket outside ~/.ssh/config. Pick a path under your private socket directory, start a background master, then point later commands at it with -S:

bash
ssh -fN -M -S ~/.ssh/sockets/manual-mux.sock root@192.168.56.116

The flags mean:

  • -M — master mode for connection sharing
  • -fN — go to background without running a remote command
  • -S — control socket path (same as ControlPath)

Confirm the socket exists:

bash
ls -la ~/.ssh/sockets/manual-mux.sock

Sample output:

output
srw-------. 1 root root 0 Aug 21 13:22 /root/.ssh/sockets/manual-mux.sock

Run a command through that socket:

bash
ssh -S ~/.ssh/sockets/manual-mux.sock root@192.168.56.116 hostname

Sample output:

output
vm1.lab.example

Close the master and remove the socket when the script finishes:

bash
ssh -O exit -S ~/.ssh/sockets/manual-mux.sock root@192.168.56.116

Sample output:

output
Exit request sent.

After exit, the socket file disappears:

bash
ls ~/.ssh/sockets/manual-mux.sock

Sample output:

output
ls: cannot access '/root/.ssh/sockets/manual-mux.sock': No such file or directory

Close the master from ~/.ssh/config (client)

On the client, send an explicit exit request when you finish a work block and do not want ControlPersist to keep the master alive:

bash
ssh -O exit lab-server

Sample output:

output
Exit request sent.

The control socket under ~/.ssh/sockets/ is removed and the TCP connection to the server closes. The next ssh lab-server performs a full login again.

If you only close an interactive shell but leave other multiplexed sessions open, the master stays up until the last channel closes (or until ControlPersist expires).


Server session limits (server, usually unchanged)

On the server (vm1.lab.example), multiplexing needs no sshd toggle, but each multiplexed channel still counts against per-connection limits. From the client, query those limits over SSH:

bash
ssh lab-server 'sshd -T | grep maxsessions'

If you are already logged into the server, the same check is sshd -T | grep maxsessions in that shell.

Sample output:

output
maxsessions 10

Each multiplexed shell or subsystem session consumes a session channel on the existing TCP connection. The default MaxSessions 10 is normally sufficient; change it only if you actually hit that limit. Edit /etc/ssh/sshd_config on the server and reload sshd when you need more channels on one link.

You do not enable multiplexing in sshd_config; the daemon already multiplexes channels on any SSH connection.


Security notes (client)

On the client, the control socket is as sensitive as an authenticated session. Treat it like a private key file:

  • Keep ControlPath inside ~/.ssh/ (mode 700) or another directory only your user owns.
  • Prefer %C or %r@%h-%p so socket names do not collide between hosts.
  • Set ControlPersist to a finite value instead of yes on laptops and shared machines.
  • Run ssh -O exit before walking away from an unlocked console.

Multiplexing does not replace strong SSH authentication. Public key auth with a passphrase-protected key remains the baseline; multiplexing only avoids repeating that work within the persist window.


Troubleshooting

Symptom Likely cause Fix (where)
Control socket connect(...): No such file or directory No master running, or wrong ControlPath Client: run a first ssh with ControlMaster auto, or match the -S path the master used
Too many open sessions on the server More channels than MaxSessions on one TCP link Server: raise MaxSessions in sshd_config and reload sshd; client: close unused sessions
Second ssh still prompts for a password Different ControlPath, user, host, or port than the master Client: align %r, %h, and %p placeholders; connect with the same Host block
Permission denied on the socket file ControlPath directory writable by other users Client: chmod 700 on the directory; never place sockets in /tmp on multi-user systems
Master never dies ControlPersist yes or a long timeout Client: use a numeric timeout, or ssh -O exit when done
auto-mux never appears in -vv output Multiplexing disabled or ControlMaster no Client: set ControlMaster auto in config or -o ControlMaster=auto on the command line

References


Summary

SSH multiplexing keeps one authenticated TCP connection open on the client and lets later ssh, scp, and sftp sessions attach through a control socket. You enable it on the initiating host with ControlMaster, point clients at a unique ControlPath, and optionally keep the master alive with ControlPersist between bursts of work. The server needs no multiplexing setup beyond normal sshd. On the lab hosts, the client ssh lab-server created root@192.168.56.116-22 under ~/.ssh/sockets/, ssh -O check reported a running master, and scp -v showed auto-mux attaching to that same master.

The detail that trips people up is socket matching: the user, hostname, port, and ControlPath pattern must match exactly between the master and every multiplexed client. A typo in HostName or a socket path in a world-writable directory silently forces a fresh login. When you finish, ssh -O exit tears down the master so the next connection performs a full authentication cycle, which matters on shared workstations even when ControlPersist would eventually time out on its own.

For day-to-day use, a per-host block in ~/.ssh/config is enough. Reserve explicit -M and -S flags for scripts that need an isolated socket path under ~/.ssh/sockets/. Server-side changes are rare unless you stack many channels on one link and hit MaxSessions.


Frequently Asked Questions

1. What is SSH multiplexing?

SSH multiplexing lets later ssh, scp, or sftp clients attach to an existing master connection through a local control socket instead of opening a new TCP session and repeating the full handshake.

2. Do I need to change sshd on the server for multiplexing?

No. Multiplexing is configured on the SSH client. The server only sees one TCP connection carrying multiple channels. Default MaxSessions on sshd is usually enough unless you open many sessions over one connection.

3. What does ControlMaster auto do?

With ControlMaster auto, the first ssh to a host becomes the master and creates the control socket. Later clients to the same ControlPath reuse that master when it is still running.

4. How do I close a multiplexed master connection?

Run ssh -O exit against the same host and ControlPath you used to create the master. That removes the control socket and closes the underlying TCP connection.

5. Is SSH multiplexing safe on shared workstations?

Anyone who can access your control socket can reuse your authenticated session. Keep the socket directory mode 700, use ControlPersist timeouts, and run ssh -O exit when you leave a shared machine.
Omer Cakmak

Linux Administrator

Highly skilled at managing Debian, Ubuntu, CentOS, Oracle Linux, and Red Hat servers. Proficient in bash scripting, Ansible, and AWX central server management, he handles server operations on OpenStack, KVM, Proxmox, and VMware.

  • Debian
  • Ubuntu
  • Linux
  • Red Hat Enterprise Linux
  • Shell Script
  • System Administration