58

With the following .ssh/config configuration:

ControlMaster auto
ControlPath /tmp/ssh_mux_%h_%p_%r
ControlPersist 4h

How to close the persisting connection before the 4 hours?

I know you can make new connections, but how to close them (all)?

Maybe there is a way to show all the persisted connections and handle them individually but I can not find it.

  • 3
    Not killing it, but you can simply not use the persisting connection via ssh -S none (maybe this helps you already). – sr_ Nov 5 '11 at 9:15
  • No I'm trying to remove a user on a remote server, but the hanging connections prevent me from doing it. – Paolo Nov 5 '11 at 10:17
74

From the manual:

-O ctl_cmd
Control an active connection multiplexing master process. When the -O option is specified, the ctl_cmd argument is interpreted and passed to the master process. Valid commands are: check (check that the master process is running), forward (request forwardings without command execution), cancel (cancel forwardings), exit (request the master to exit), and stop (request the master to stop accepting further multiplexing requests).

Older versions only have check and exit, but that's enough for your purpose.

ssh -O check host.example.com

If you want to delete all connections (not just the connection to a particular host) in one fell swoop, then fuser /tmp/ssh_mux_* or lsof /tmp/ssh_mux_* will list the ssh clients that are controlling each socket. Use fuser -HUP -k tmp/ssh_mux_* to kill them all cleanly (using SIGHUP as the signal is best as it lets the clients properly remove their socket).

  • This is an excellent answer. This is perfect for what I was trying to achieve. check is even more useful than what I was looking for, which is what exit does anyway! :D – ELLIOTTCABLE Dec 6 '11 at 14:19
  • 4
    In OS X fuser can't send signals, but this works just as well: lsof -Fp /tmp/ssh_mux_* | cut -c 2- | xargs kill -HUP – Ori Jan 15 '12 at 21:06
10

I wrote an open source utility, cmc, to manage ControlMaster sessions: ClockworkNet/cmc:

Usage:  cmc [ -c HOST | -o HOST | -x HOST ]
        cmc [ -L | -l | -O | -X ]
        cmc -h

ControlMaster Controller - Eases management of SSH ControlMaster connections

Options:
    -h      show this help message and exit
    -c HOST check HOST ControlMaster connection status (maybe specified more
            than once)
    -L      list ControlMasters defined in SSH_CONFIG
    -l      list ControlMaster connection sockets in ~/.ssh/ and check their
            connection status
    -O      open all ControlMasters defined in SSH_CONFIG
    -o HOST open a ControlMaster session (maybe specified more than once)
    -x HOST close ControlMaster session (maybe specified more than once)
    -X      exit all ControlMaster connections with sockets in ~/.ssh/

Notes:
    * Any unopened sockets in ~/.ssh/ are removed with -l and -X
3

You can run fuser /tmp/ssh_mux_blablabla (possible needing sudo) and kill the PID it returns. fuser shows which processes are using a file. (And more, check out man fuser.)

Update: check out Gilles' answer; it is much more detailed.

1

This works for me using just the socket file for the control master:

$ ssh -o ControlPath=~/.ssh/<controlfile> -O check <bogus arg>

Example

Here's an example where I've already established a connection to a remote server:

$ ssh -o ControlPath=~/.ssh/master-57db26a0499dfd881986e23a2e4dd5c5c63e26c2 -O check blah
Master running (pid=89228)
$

And with it disconnected:

$ ssh -o ControlPath=~/.ssh/master-66496a62823573e4760469df70e57ce4c15afd74 -O check blah
Control socket connect(/Users/user1/.ssh/master-66496a62823573e4760469df70e57ce4c15afd74): No such file or directory
$

If it were still connected, this would force it to exit immediately:

$ ssh -o ControlPath=~/.ssh/master-66496a62823573e4760469df70e57ce4c15afd74 -O exit blah
Exit request sent.
$

It's unclear to me, but it would appear to potentially be a bug in ssh that it requires an additional argument at the end, even though blah is meaningless in the context of the switches I'm using.

Without it gives me this:

$ ssh -o ControlPath=~/.ssh/master-57db26a0499dfd881986e23a2e4dd5c5c63e26c2 -O check
usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
           [-D [bind_address:]port] [-E log_file] [-e escape_char]
           [-F configfile] [-I pkcs11] [-i identity_file]
           [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec]
           [-O ctl_cmd] [-o option] [-p port]
           [-Q cipher | cipher-auth | mac | kex | key]
           [-R [bind_address:]port:host:hostport] [-S ctl_path] [-W host:port]
           [-w local_tun[:remote_tun]] [user@]hostname [command]

Version info

OSX
$ ssh -V
OpenSSH_6.9p1, LibreSSL 2.1.8
CentOS 7.x
$ ssh -V
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017

I confirmed that on both of these versions, the need for the additional bogus argument was required.

References

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.