SSH ControlMaster and ControlPath
One of my favorite SSH tricks is using the ControlMaster
and
ControlPath
options for speeding up connections. The idea is simple:
if you're already logged into a server and you need to log in again,
just reuse the connection you already have instead of redoing the entire
connection handshake. In addition to making connections much faster, if
you're logging in with a password, you don't have to re-type your
password for each connection. This can be really handy if you're doing a
lot of copies with scp
, checking out files with Subversion's
svn+ssh://
, etc., and don't want (SSH keys can also solve this problem
in many cases, but requires you to set up keys on the server, whereas
this just requires client-side configuration.)
Setting this up is easy. We'll designate one ssh
process as a master, and
then when another ssh
process wants to connect to the same host, it will
connect to the master process instead and request a shared connection. In order
to make this work, we first have to set up a place for this master process to
listen for requests.
To do this, add the line
ControlPath ~/.ssh/control-%h-%p-%r
to your ~/.ssh/config
file. You can read more about the syntax in the
ssh_config
man page; this particular setting puts the shared sockets in
your ~/.ssh directory, which is usually a good place for it, and makes
sure that the path is unique for each hostname, port, and remote
username, as recommended by the man page.
Then create the master ssh
process by running it with the -M
option.
You'll get a normal login, which you can use or just keep around in a
minimized window. You have to keep this connection around until you're
done with all your other connections. If for some reason you want to
avoid opening a shell — for instance, you're using this with
GitHub, which doesn't let you open a shell — you'll also want the
-N
option.
Once you've done this, every new ssh
process that's connecting to the
same host (with the same username and port) will reuse the master
connection instead of making its own. You don't need to do anything
special; as long as ControlPath
is set, each new ssh
process will
check for a master connection at that path.
As mentioned, this can make SSH significantly faster for repeated
operations. For instance, git fetch
against GitHub becomes over twice
as fast for me, compared to re-doing SSH key authentication:
geofft@cactuar:~/src/vireo$ time git fetch
real 0m0.305s
user 0m0.005s
sys 0m0.011s
geofft@cactuar:~/src/vireo$ ssh -M -N -f git@github.com
geofft@cactuar:~/src/vireo$ time git fetch
real 0m0.140s
user 0m0.000s
sys 0m0.010s
This example also used the -f
option, which puts the connection into
the background as soon as authentication is complete. To close the
connection, you can use the -O exit
option to ssh
, which, instead of
opening a new connection, signals the ControlMaster process to exit.
geofft@cactuar:~/src/vireo$ ssh -O exit git@github.com
Exit request sent.
geofft@cactuar:~/src/vireo$ time git fetch
real 0m0.303s
user 0m0.010s
sys 0m0.007s
There's a good article on Wikibooks about connection multiplexing that covers more advanced use of this feature.