A simple setup for SSH connection multiplexing using ControlMaster, plus a watchdog script that checks the master connection and restarts it when needed.
Useful when you frequently create short-lived SSH sessions but want them to reuse one long-lived underlying SSH connection.
Add to:
~/.ssh/config
Host server.example.com
User myuser
ControlMaster auto
ControlPath ~/.ssh/cm-%C
ControlPersist 8h
ServerAliveInterval 30
ServerAliveCountMax 3For multiple servers:
Host server1.example.com server2.example.com server3.example.com
User myuser
ControlMaster auto
ControlPath ~/.ssh/cm-%C
ControlPersist 8h
ServerAliveInterval 30
ServerAliveCountMax 3Each destination gets its own ControlMaster connection/socket.
ControlMaster auto— reuse an existing master connection when possible.ControlPath ~/.ssh/cm-%C— store the multiplexing socket using SSH's hashed connection identifier.ControlPersist 8h— keep the master alive after the last SSH session exits.ServerAliveInterval 30— send a keep-alive message every 30 seconds when needed.ServerAliveCountMax 3— consider the connection dead after 3 unanswered keep-alives.
Start a background master connection:
ssh -MNf myuser@server.example.comOptions:
-M— explicitly request a master connection.-N— don't execute a remote command.-f— move SSH into the background after authentication.
Check it:
ssh -O check myuser@server.example.comExample:
Master running (pid=48217)
Stop it gracefully:
ssh -O exit myuser@server.example.comSave as:
ssh-watchdog.sh
#!/bin/sh
HOST="server.example.com"
SSH_USER="myuser"
DELAY=10
TARGET="${SSH_USER}@${HOST}"
while true; do
STATUS=$(ssh -O check "$TARGET" 2>&1)
if [ $? -eq 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - $TARGET - $STATUS"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') - $TARGET - ControlMaster down - starting..."
if ssh -MNf "$TARGET"; then
STATUS=$(ssh -O check "$TARGET" 2>&1)
echo "$(date '+%Y-%m-%d %H:%M:%S') - $TARGET - $STATUS"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') - $TARGET - Failed to start ControlMaster"
fi
fi
sleep "$DELAY"
doneMake it executable:
chmod +x ssh-watchdog.shRun it:
./ssh-watchdog.shExample output:
2026-09-04 09:18:01 - myuser@server.example.com - Master running (pid=48217)
2026-09-04 09:18:11 - myuser@server.example.com - Master running (pid=48217)
2026-09-04 09:18:21 - myuser@server.example.com - Master running (pid=48217)
If the master dies:
2026-09-04 09:18:31 - myuser@server.example.com - ControlMaster down - starting...
2026-09-04 09:18:32 - myuser@server.example.com - Master running (pid=49103)
The PID change makes it easy to see that a new underlying SSH master connection was created.
For normal use, a longer check interval is usually enough:
DELAY=30or:
DELAY=60SSH can show the configuration it resolved for a host:
ssh -G myuser@server.example.com | grep -Ei '^(user|controlmaster|controlpath|controlpersist|serveralive)'Example:
user myuser
controlmaster auto
controlpath /home/myuser/.ssh/cm-...
controlpersist 28800
serveralivecountmax 3
serveraliveinterval 30
Start the master:
ssh -MNf myuser@server.example.comCheck its PID:
ssh -O check myuser@server.example.comExample:
Master running (pid=48217)
Now create several sessions:
ssh myuser@server.example.com
ssh myuser@server.example.com "hostname"
ssh myuser@server.example.com "uptime"Or copy a file:
scp file.txt myuser@server.example.com:/tmp/Check again:
ssh -O check myuser@server.example.comYou should still see the same master PID:
Master running (pid=48217)
The individual SSH commands are separate logical sessions, but they reuse the same underlying SSH connection.
SSH ControlMaster has existed for a long time, but it is easy to overlook.
It is especially useful for tools and agents that create many short-lived SSH sessions. Instead of creating a new TCP connection, SSH handshake, and authentication for every command, multiple sessions can be multiplexed over one existing SSH connection.
This is also useful to remember from a security perspective.
Many short-lived SSH commands do not necessarily mean many new network connections or SSH authentications. With ControlMaster enabled, they may all be logical sessions multiplexed over one long-lived SSH connection.
Start:
ssh -MNf myuser@server.example.comCheck:
ssh -O check myuser@server.example.comConnect normally:
ssh myuser@server.example.comRun a command:
ssh myuser@server.example.com "uptime"Stop the master:
ssh -O exit myuser@server.example.comInspect effective configuration:
ssh -G myuser@server.example.com | grep -Ei '^(user|controlmaster|controlpath|controlpersist|serveralive)'