Ssh – Adding port forwardings programmatically on a ControlMaster SSH session

multiplexingport-forwardingSecuritysshvnc

I just found out about the ControlMaster/ControlPath feature of OpenSSH, which allows you to use a single SSH connection to run multiple terminals.

As I often use SSH to use port forwarding to get encrypted and authenticated VNC sessions I instantly recognized that you can't add port forwardings to a remote server to which you already have an established connection. This sucks.

Sometimes later I found out that you can circumvent this limitation by typing ~C in a running SSH terminal session. This opens up a command-line which allows you to add or remove port forwardings.

My quesion now is: How can I add port forwardings on an existing SSH session which is using the ControlMaster/ControlPath feature, without the need to have access to a terminal session inside that SSH session. I need this to enable my script which starts a secure tunneled VNC connection for me to add and later remove its port forwardings.

(I know I could use a terminal multiplexer such as GNU Screen or tmux, actually I'm doing this already. But I like the idea of using just one SSH session for serveral reasons.)

Best Answer

That's quite simple, actually. Simply add the ctl_cmd -O forward to your existing command, thus:

ssh -M -L5555:localhost:22 remotehost

becomes:

ssh -O forward -M -L5555:localhost:22 remotehost

The ssh man page discusses the -O ctl_cmd option:

-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).

This, of course, assumes you've either enabled ControlMaster yes in your ~/ssh/config file or -M on the command line.