What's Actually Happening
You've configured SSH connection multiplexing (ControlMaster) to speed up connections, but new connections fail with socket-related errors. The control socket might be stale, have wrong permissions, or be in an inaccessible location. These errors prevent both new connections and the cleanup of old ones.
The Error You'll See
When attempting to connect:
Control socket connect(/home/user/.ssh/sockets/user@host-22): Connection refusedOr:
ControlPath /home/user/.ssh/sockets/user@host-22 is not a socketOr permission errors:
Control socket connect(/home/user/.ssh/sockets/user@host-22): Permission deniedOr with verbose output:
ssh -v user@serverShows:
debug1: Control socket "/home/user/.ssh/sockets/user@host-22" does not exist
debug1: Creating new control socket
debug1: control_persist_detach: forked into background
debug1: channel 0: new session
unix_listener: cannot bind to path /home/user/.ssh/sockets/user@host-22: No such file or directoryWhy This Happens
ControlMaster creates a Unix socket file that subsequent connections use. Problems occur when:
- 1.The socket file exists but the master process has died (stale socket)
- 2.The socket directory doesn't exist or has wrong permissions
- 3.The socket file has wrong ownership (created by different user)
- 4.Disk is full or filesystem doesn't support sockets
- 5.The previous connection wasn't cleaned up properly
Step 1: Identify Control Socket Path
Check your SSH configuration for the socket path:
grep -E "ControlPath|ControlMaster" ~/.ssh/configCommon configurations:
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600The %r is remote user, %h is hostname, %p is port.
Step 2: Check Socket Directory
Verify the socket directory exists:
ls -la ~/.ssh/sockets/If it doesn't exist:
mkdir -p ~/.ssh/sockets
chmod 700 ~/.ssh/socketsThe directory must have restrictive permissions (700 or 755).
Step 3: Check for Stale Sockets
List existing socket files:
ls -la ~/.ssh/sockets/You'll see something like:
srw------- 1 user user 0 Apr 3 10:00 user@server-22The 's' at the start indicates a socket file.
Check if the master process is still running:
ssh -O check user@serverIf it returns:
Control socket connect(/home/user/.ssh/sockets/user@server-22): Connection refusedThe socket is stale. Remove it:
rm ~/.ssh/sockets/user@server-22Or remove all stale sockets at once:
find ~/.ssh/sockets -type s -exec rm {} \;Step 4: Fix Socket Permissions
If socket files have wrong permissions:
ls -la ~/.ssh/sockets/Should show:
srw------- 1 user user 0 Apr 3 10:00 user@server-22If owned by root or another user:
sudo rm ~/.ssh/sockets/user@server-22Fix directory ownership:
chown -R $USER:$USER ~/.ssh/sockets
chmod 700 ~/.ssh/socketsStep 5: Check Running Master Processes
Find any SSH master processes:
ps aux | grep ssh | grep -v grepLook for:
user 12345 0.0 0.0 12345 6789 ? Ss 10:00 0:00 ssh: /home/user/.ssh/sockets/user@server-22 [mux]The [mux] indicates a ControlMaster process.
Kill zombie master processes:
ssh -O exit user@serverIf that fails, kill the process:
kill 12345Then remove the stale socket.
Step 6: Check Disk Space and Filesystem
Ensure the filesystem can create sockets:
df -h ~/.ssh/sockets/If disk is full, clean up:
rm -f ~/.ssh/sockets/*Some filesystems (like NTFS or FAT) don't support Unix sockets. Check your mount:
mount | grep $(df ~/.ssh | tail -1 | awk '{print $1}')If you see ntfs or vfat, create the socket directory elsewhere:
mkdir -p /tmp/ssh-sockets-$USER
chmod 700 /tmp/ssh-sockets-$USERUpdate your SSH config:
ControlPath /tmp/ssh-sockets-%r@%h-%pStep 7: Reset All ControlMaster Connections
To completely reset your multiplexing setup:
```bash # Stop all master connections for socket in ~/.ssh/sockets/*; do ssh -O exit $(basename "$socket" | sed 's/-/:/' | sed 's/@/:/g') done 2>/dev/null
# Remove all socket files rm -f ~/.ssh/sockets/*
# Kill any remaining SSH processes (use carefully) pkill -u $USER -f 'ssh.*ControlMaster' ```
Step 8: Update SSH Config for Reliability
Use a robust configuration:
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600The ControlPersist 600 keeps the master running for 10 minutes after the last session closes, allowing for reconnection without the stale socket issue.
For even better reliability:
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p-%C
ControlPersist yesThe %C creates a unique hash, preventing conflicts when parameters differ slightly.
Step 9: Test Multiplexing
Test that multiplexing works:
```bash # First connection creates master time ssh user@server exit
# Second connection uses existing master time ssh user@server exit ```
The second connection should be much faster (under 0.1 seconds).
Check the socket exists:
ls -la ~/.ssh/sockets/Verify the Fix
ControlMaster is working correctly when:
- 1.
ssh -O check user@serverreturns "Master running" - 2.
ls ~/.ssh/sockets/shows socket files with correct permissions - 3.New connections complete almost instantly
- 4.No "Connection refused" or "not a socket" errors
Create a test script:
#!/bin/bash
echo "Testing ControlMaster..."
ssh -O check user@server && echo "Master is running" || echo "No master found"
ssh user@server 'echo "Connection successful"'
ssh -O exit user@server && echo "Master stopped"If you frequently have stale socket issues, add cleanup to your shell profile:
# Add to ~/.bashrc or ~/.zshrc
ssh-cleanup() {
find ~/.ssh/sockets -type s -mtime +1 -delete 2>/dev/null
}
# Run on login
ssh-cleanup