You can reuse the connection to the remote server using controlmaster directive. To enables the sharing of multiple sessions over a single network connection to add controlmaster after host directive. When set to yes ssh client will listen for connections on a control socket specified using the ControlPath argument. These sessions will try to reuse the master instance’s network connection rather than initiating new ones, but will fall back to connecting normally if the control socket does not exist, or is not listening. Multiplexing is nothing but the ability to send more than one signal over a single line or connection. OpenSSH can re-use an existing TCP connection using multiplexing.
WARNING! These examples requires OpenSSH version 4.0 or higher.
Setting up ssh multiplexing
Open ~/.ssh/config file (ssh client configuration file). If you need system wide settings add to the /etc/ssh/ssh_config file:
$ vi ~/.ssh/config
Append following code to reuse ssh connection for all hosts:
host * controlmaster auto controlpath /tmp/ssh-%r@%h:%p
Where,
- controlmaster auto: Set controlmaster to auto
- controlpath /tmp/ssh-%r@%h:%p: Specify the path to the control socket used for connection sharing. In the path, %h will be substituted by the target host name, %p the port, and %r by the remote login username. It is recommended that any ControlPath used for opportunistic connection sharing include at least %h, %p, and %r. This ensures that shared connections are uniquely identified.
You can also match any host in the 192.168.0.[0-9] network range with following pattern:
Host 192.168.0.? controlmaster auto controlpath ~/.ssh/ssh-%r@%h:%p
For any host in the “.co.in” set of domains, reuse the connection:
Host *.co.in controlmaster auto controlpath ~/.ssh/private/master-%r@%h:%p
Save and close the file. Now connect as usual,
$ ssh vivek@vpn.nixcraft.co.in
Next, time you connect again it will use connection socket /tmp/ssh-vivek@vpn.nixcraft.in:22 to speed up things. You don’t have to input password or anything else. You need one connection to be active for the second to be accelerated. This also works with scp / sftp etc:
$ scp /path/to/file.txt vivek@vpn.nixcraft.co.in:/tmp
Compare ssh command with and without multiplexing
You can compare the time it takes to run command on a slow remote server, using time. First, run time command without multiplexing (remove entries from ~/.ssh/config file):
$ time ssh vivek@vpn.nixcraft.co.in /path/to/command
$ time ssh -o 'ControlMaster=no' vivek@vpn.nixcraft.co.in /bin/true
Sample outputs:
real 0m3.546s user 0m0.016s sys 0m0.008s
Now, run same command with multiplexing (add entries to ~/.ssh/config):
$ time ssh vivek@vpn.nixcraft.co.in /path/to/command
$ time ssh vivek@vpn.nixcraft.co.in /bin/ture
Sample outputs:
real 0m0.621s user 0m0.006s sys 0m0.004s
How to disable multiplexing for a single ssh command session?
Run command as follows with ControlMaster set to no:
$ ssh -o 'ControlMaster=no' vivek@vpn.nixcraft.co.in
How to find out or check the status of multiplexing
$ ssh -O check vivek@vpn.nixcraft.co.in
Sample outputs:
Master running (pid=64134)
How to stop multiplexed connections
To gracefully shutdown multiplexing pass the -O stop option to the ssh command:
$ ssh -O stop vivek@ vivek@vpn.nixcraft.co.in
Sample outputs:
Stop listening request sent.
Pass the -O exit option to remove the control socket and immediately terminates all existing connections, run:
$ ssh -O exit vivek@vivek@vpn.nixcraft.co.in
Sample outputs:
Exit request sent.
And all of your ssh session will terminated with the following message:
Shared connection to vpn.nixcraft.co.in closed.
A sample session output
Fig.01: A sample session
Using ssh multiplexing with ProxyCommand
You can go through one host to reach another server. In this example, you reach to internal host called 10.70.203.66 via vpn.nixcraft.co.in:
Host internal HostName 10.70.203.66 User vivek ProxyCommand ssh vivek@vpn.nixcraft.co.in -W %h:%p ControlPath ~/.ssh/controlmasters/%r@%h:%p ControlMaster auto
Just type the following command to go through ‘vpn.nixcraft.co.in’ to reach another server called ‘internal’:
$ ssh internal
Say hello ControlPersist option
When ControlPersist used in conjunction with ControlMaster, specifies that the master connection should remain open in the background (waiting for future client connections) after the initial client connection has been closed. You can set it as follows:
- ControlPersist no : The master connection will not be placed into the background, and will close as soon as the initial client connection is closed.
- ControlPersist yes : The master connection will remain in the background indefinitely (until killed or closed via a mechanism such as the ssh -O exit user@host option. Further, if set to yes then, if set to a time in seconds, or a time in any of the formats documented in sshd_config(5), then the backgrounded master connection will automatically terminate after it has remained idle (with no client connections) for the specified time. For example, ControlPersist 10m.
Here is an updated config file:
Host internal HostName 10.70.203.66 User vivek ProxyCommand ssh vivek@vpn.nixcraft.co.in -W %h:%p ControlPath ~/.ssh/controlmasters/%r@%h:%p ControlMaster auto ControlPersist yes
A note about X11, ssh-agent and port forwarding
Please note that X11 and ssh-agent forwarding is supported over these multiplexed connections, however the display and agent forwarded will be the one belonging to the master connection i.e. it is not possible to forward multiple displays or agents. However, you can create new session as follows for port forwarding:
$ ssh -M -S /tmp/3001.port.forwording -L 3001:localhost:3001 -N -f vivek@vpn.nixcraft.co.in
Further readings:
- man pages ssh_config(5)
🐧 10 comments so far... add one ↓
Category | List of Unix and Linux commands |
---|---|
File Management | cat |
Firewall | Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04 |
Network Utilities | dig • host • ip • nmap |
OpenVPN | CentOS 7 • CentOS 8 • Debian 10 • Debian 8/9 • Ubuntu 18.04 • Ubuntu 20.04 |
Package Manager | apk • apt |
Processes Management | bg • chroot • cron • disown • fg • jobs • killall • kill • pidof • pstree • pwdx • time |
Searching | grep • whereis • which |
User Information | groups • id • lastcomm • last • lid/libuser-lid • logname • members • users • whoami • who • w |
WireGuard VPN | Alpine • CentOS 8 • Debian 10 • Firewall • Ubuntu 20.04 |
Wow, that is indeed a good trick! Never heard of these configuration variables.
Works on Mac OS X 10.5.4, the only remark;
– I have the options set for no host, so your ~/.ssh/config could just be like this:
ControlMaster auto
ControlPath /tmp/ssh-%r@%h:%p
– The manpage suggests to use the variables with different capitalization. See example above.
Regards and thanks for the great trick, indeed fast!
Robert de Bock.
I’m concerned about security. Is there any security issue using re-using ssh connections?
thanks
The ONLY draw back I’ve found to this is that because all subsequent SSH requests to the same host share the TCP connection, doing a bulk SCP will slow down the responsiveness of the interactive sessions. It’s not a problem most of the time.
why doesn’t it works in my cygwin?
The error is:
$ ssh sunjingwei@relay01
ssh_msg_recv: read: header
muxclient: msg_recv
thank u very much.
$ ssh -fNM eta
$ ssh eta ls
mm_receive_fd: no message header
muxserver_accept_control: failed to receive fd 0 from slave
ssh_msg_recv: read: header
muxclient: msg_recv
FYI, ssh manpages recommend storing the socket in a private location to prevent other users from using the same socket.
As for the cygwin error, my research so far indicates that this is due to passing around a file descriptor… https://bugzilla.mindrot.org/show_bug.cgi?id=1278
You’re the grteesat! JMHO
Hi,
does it works on windows?
My config file looks like:
But i have to enter password every time, when connecting to host :(
This is unreal!
Connections to EC2 instances took ~6 seconds to negotiate a connection.
I’m using Chef-Solo and the multiple stages involved in deploying code such as rsync, scp, remote ssh commands, were being dragged down by this connection.
You have made my day!
I wrote an open source utility to managed background ControlMaster sessions: https://github.com/ClockworkNet/cmc