Ssh – Removing port forwardings programmatically on a ControlMaster SSH session

multiplexingport-forwardingSecurityssh

Quite a while ago I got an answer telling me how to add a port-forwarding on a running SSH ControlMaster process. To know that helps a lot, but I'm still missing a way to remove such a port forwarding after I don't need that anymore.

As far as I know, you can do that through the internal command key sequence on normal connections, this seems to be disabled for ControlMaster clients. Even if that would be possible I would need a solution which I can automatize with scripts, which is surely not so easy this way.

Is there a way to do it? And is it easily automatizable?

Best Answer

As my previous answer notes, the ssh man page explains the -O ctl_cmd in detail, where ctl_cmd is one of check, forward, cancel, or exit.

-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), “exit” (request the master to
        exit), and “stop” (request the master to stop accepting further multiplexing
        requests).

You can use the ctl_cmd's to accomplish the automation you want for your scripts. You'll need to first create a ControlMaster socket with the -S like and ssh to the remotehost like this:

ssh -v -M -S/tmp/controlmaster-remotehost remotehost

and then from your local machine you can forward and cancel ports as you like. You can forward multiple ports with one command:

ssh -O forward -S/tmp/controlmaster-remotehost -L5555:localhost:22 -L3333:localhost:22 remotehost

and/or handle them one at a time:

ssh -O cancel  -S/tmp/controlmaster-remotehost -L5555:localhost:22 remotehost
ssh -O cancel  -S/tmp/controlmaster-remotehost -L3333:localhost:22 remotehost

I created a gist with a side-by-side session showing the ssh -O ctl_cmd in action; with port forward/cancel from localhost on the left side, and the output of ssh connected to remotehost on the right side:

https://gist.github.com/raw/4265549/999d90b8f85190a41eed00e4d60d5d22da6c67b9/ssh-controlmaster-side-by-side.log

These commands are only available as of OpenSSH 6.0:

 * ssh(1): support for cancelling local and remote port forwards via the
   multiplex socket. Use ssh -O cancel -L xx:xx:xx -R yy:yy:yy user@host"
   to request the cancellation of the specified forwardings
 * support cancellation of local/dynamic forwardings from ~C commandline

If you have an earlier version you'll need to upgrade. If you're on Mac OS X you can install macports and then upgrade using: sudo port install openssh which will install it into /opt/local/bin.