SSH RemoteForward fails with shared Control Socket

port-forwardingssh

My ~/.ssh/config contains:

ControlMaster auto
ControlPath ~/.ssh/socket-%r@%h:%p

Host hostname.example
    # TextMate rmate port
    RemoteForward :52698 localhost:52698

When I make an initial connection to the host, it successfully creates the master socket file at ~/.ssh-lachlanhunt@hostname.example:22.

But when I open a new terminal and attempt to make a second connection, I get this error:

$ ssh hostname.example
mux_client_forward: forwarding request failed: remote port forwarding failed for listen port 52698
muxclient: master forward request failed
ControlSocket /Users/lachlanhunt/.ssh/socket-lachlanhunt@hostname.example:22 already exists, disabling multiplexing
Warning: remote port forwarding failed for listen port 52698

But if I comment out the RemoteForward line in the config, it's able to successfully reuse the connection, making it connect faster. Is there any way I can configure ssh to support both multiplexed connections and enable the remote port forwarding, such that it only attempts to forward the port if it's the master connection?

My system:

  • macOS Sierra 10.12.6
  • OpenSSH_7.4p1, LibreSSL 2.5.0

Best Answer

I figured out a solution. I use the Match section with the host and negated exec keywords to test for the hostname and the existence of the control socket file. If the file doesn't exist, then this is the master connection, so setup the port forwarding. Otherwise, this is a slave connection and the forwarding is skipped.

ControlMaster auto
ControlPath ~/.ssh/socket-%r@%h:%p

Match host hostname1.example.com,hostname2.example.com !exec "[ -e ~/.ssh/socket-%r@%h:%p ]"
    # TextMate rmate port
    RemoteForward :52698 localhost:52698