ssh control socket: almost great

ssh is an essential tool on a unix network. I use it to log in to machines remotely, control VNC desktops, act as a VPN (SOCKS proxy), synchronize source code (with git and svn), serve music and movies across a wireless network (with sshfs), and transfer hundreds of gigabytes of pulsar data (with rsync). So the ControlMaster feature seemed like a great idea: automatically reuse one ssh connection for as many logins and file transfers as necessary. But it won't quite do what I want.

I see two major failings:

First of all, the connection dies when the initial ssh process dies. So if you log in, creating a master socket, and do something, then log in in a subsidiary socket, you get your second connection through the ControlMaster magic. But if you then log out of the first connection, the ssh process keeps running. If you kill it (say by closing the window it's in), all the subsidiary connections die. What this means is that if you try to use opportunistic connection reuse, and you have several terminal windows open on the same host, for the most part you can just close the one window. But there's one window that, if you close it, will take down all the others with it. Yuck.

You can kind of work around this by, instead of using opportunistic connection sharing, explicitly starting a master connection with "ssh -MfN host", which drops the ssh process into the background as soon as it's connected. Unfortunately, this means you have a quasi-zombie ssh process hanging around indefinitely. So I'm not sold on it either. (But if you're going to do it, using autossh might help.)

The second, more serious, problem I have with ControlMaster is that it doesn't let subsidiary ssh connections open new port forwardings. I use port forwardings a lot, for example to forward VNC connections to machines I can't see from the outside world. If opportunistic connection sharing causes those to fail, or worse, fail sometimes, it's going to be a problem. A shame really, it's such a sensible idea.

Edit as of 2013 August 29: OpenSSH now has the ControlPersist option, which, in combination with ControlMaster and ControlPath, can be used to make the controlling SSH process background itself. You still can't (as far as I can tell) add new forwardings later on, but at least the problem of having the first connection be magical has gone away. I use this combination for one particular machine that accepts only password authentication (don't get me started) but that I use only as a gateway machine. Now the first time I try to connect through it I get prompted for a password but later connections just reuse the link. And because all it's doing is forward connections using the -W option, I don't care that I can't add port forwardings. 


Popup said...

It sounds interesting, and I was tempted to do a small test.

It does indeed connect faster. I ran a series of
time ssh _other_host_ > echo "test"

and the difference is impressive. Without ControlMaster I get an median of 0.934 seconds, and with it I get 0.202.

Now the problem is to regain that half-hour lost in experimenting. If I gain 700milliseconds per connection, and I normally make on average 10 connections per day, I ought to be ahead in about a year! And then I can start gaining time!

Anne M. Archibald said...

Oh yes, the speed is convenient. And it can be handy authentication-wise too: if you use password authentication, then you only have to authenticate the master connection, all the others work unattended. But I think your regaining-lost-time arithmetic is off. In terms of total hours spent, of course, you're right; it's unlikely to pay off. But those extra 700 milliseconds can mean the difference between losing your train of thought while you wait for the connection, and being able to seamlessly keep working.

tzeentch said...

Yes, I agree with you re limitations, there really should be a better way to control the running master.

There is a workaround for the second limitation (inability of multiplexed connections to modify port forwardings, etc.) however it is only possible if not using the first (running master with -fMN). Basically on the connection which *is* the master, you can use the ~C escape and type additional -L, -R, etc. options to add forwardings and -KR to remove them. man ssh(1) section about escape characters will tell you all about it.

Again, however, ~C is not possible from multiplexed connections, so it won't help if your master is running in the background.

If anyone finds a way to control a backgrounded master process I'd be very happy to hear about it :)

Anonymous said...

I think you can make new forwardings by just doing a new ssh with the -L and -R options, and -O forward.