Bug 3271 - Interface to send commands to the server side ssh
Summary: Interface to send commands to the server side ssh
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 8.5p1
Hardware: All All
: P5 enhancement
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-03-05 19:03 AEDT by Marcos Dione
Modified: 2021-04-23 15:10 AEST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marcos Dione 2021-03-05 19:03:42 AEDT
With ~.C it's possible to open a command line to send commands/options to the server side of an ssh session. This is recommended for f.i. adding redirections after the session has been open. See https://unix.stackexchange.com/questions/576947/add-forward-during-ssh-session-dynamically

My suggestion is to create an interface to send those commands from the command line or scripts. One option would be a unix socket laying around and an envvar pointing to it.

I understand this could be a security hazard, so maybe this can be disabled by default and only be enabled on the client's command line, and maybe it could accept only a subset of all the commands/options ssh supports.
Comment 1 Darren Tucker 2021-03-05 19:34:12 AEDT
You can do that via the ControlMaster's command option "-O".  It uses the unix socket laying around wherever ControlPath points to.  It's a security hazard so it's disabled by default, and it can only do a subset of the things that ssh command line options support.

 -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).
Comment 2 Marcos Dione 2021-03-08 02:02:35 AEDT
Well, that works only from the client side and for a very restrict set of commands. Maybe there's a separate tool that can do this? Any suggestions where to even ask?
Comment 3 Darren Tucker 2021-03-08 13:42:38 AEDT
(In reply to Marcos Dione from comment #2)
> Well, that works only from the client side

~C escapes only work from the client side.

> and for a very restrict set of commands.

It can add and remove port forwardings, which is the use case you described.  What else would you like to be able to do via this mechanism?

> Maybe there's a separate tool that can do this? Any
> suggestions where to even ask?

Perhaps you could give more of a description of what you're trying to achieve?
Comment 4 Marcos Dione 2021-03-08 18:10:35 AEDT
Let me put some names to things:

* server: machine running sshd
* client: machine running ssh

I want to run commands (as in shell commands, that I can then execute from any program) on the server that modifies the ports forwarded by the session established from the client to the server.

You say ~.C and -O work on the client, I want something that works on the server. In fact, ~.C only works on the _terminal_, and I can't find ways to simulate those keystrokes on the server (I tried writing to /dev/tty and other open fds by the answering ssh process).
Comment 5 Darren Tucker 2021-03-08 19:58:00 AEDT
(In reply to Marcos Dione from comment #4)
[...]
> I want to run commands (as in shell commands, that I can then
> execute from any program) on the server that modifies the ports
> forwarded by the session established from the client to the server.

The port forward listen requests 

You could do that by combining ControlMaster and a remote forward of a Unix domain socket:

client$ ssh -v -oControlMaster=yes -R/tmp/sock:/tmp/sock server
[...]

server$ $ ssh -oControlPath=/tmp/sock -O forward -L 1234:127.0.0.1:22 localhost
debug1: client_input_channel_open: ctype forwarded-streamlocal@openssh.com rchan 5 win 2097152 max 32768
debug1: client_request_forwarded_streamlocal: request: /tmp/sock
debug1: connect_next: host /tmp/sock ([unix]:/tmp/sock) in progress, fd=8
debug1: channel 2: new [forwarded-streamlocal]
debug1: confirm forwarded-streamlocal@openssh.com
debug1: multiplexing control connection
debug1: channel 3: new [mux-control]
debug1: channel 2: connected to /tmp/sock port -2
debug1: Local forwarding listening on ::1 port 1234.
debug1: channel 4: new [port listener]
debug1: Local forwarding listening on 127.0.0.1 port 1234.
debug1: channel 5: new [port listener]
debug1: channel 3: free: mux-control, nchannels 6
debug1: channel 2: free: forwarded-streamlocal, nchannels 5

server$ $ telnet localhost 1234
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused

client$ telnet localhost 1234
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SSH-2.0-OpenSSH_8.5

The caveat is that the mux protocol is effectively internal to ssh, so it'll only work with an OpenSSH client of of a compatible version being run on both ends.  (There's been 4 revisions of the mux protocol in the 12 years since multiplexing was introduced, so while it doesn't change often it does change.)
Comment 6 Darren Tucker 2021-03-08 19:59:28 AEDT
(In reply to Darren Tucker from comment #5)
> The port forward listen requests 

submitted a bit early.  I was going to say "The port forward listen requests are normally only sent by the client, so the spec says a client should ignore them if it receives one".
Comment 7 Marcos Dione 2021-03-08 23:57:17 AEDT
13:50 $ ssh -v -oControlMaster=yes -R/tmp/sock:/tmp/sock uk-janderson
OpenSSH_8.3p1 Ubuntu-1, OpenSSL 1.1.1f  31 Mar 2020
[...]
debug1: Remote connections from /tmp/sock:-2 forwarded to local address /tmp/sock:-2
[...]
debug1: remote forward success for: listen /tmp/sock:-2, connect /tmp/sock:-2


mdione@uk-janderson:~$ ssh -oControlPath=/tmp/sock -O forward -L 1234:127.0.0.1:22 localhost
debug1: client_input_channel_open: ctype forwarded-streamlocal@openssh.com rchan 2 win 2097152 max 32768
debug1: client_request_forwarded_streamlocal: request: /tmp/sock
debug1: connect_next: host /tmp/sock ([unix]:/tmp/sock): No such file or directory
connect to /tmp/sock port -2 failed: No such file or directory
debug1: failure forwarded-streamlocal@openssh.com
muxclient: master hello exchange failed

So I guess my cliente/server mix do not interoperate? Where can i read about the mux protocol changes? I can't find anything on Debian's changelog or News files, and there doesn't seems to be a changelog on your side?
Comment 8 Darren Tucker 2021-03-09 08:43:30 AEDT
(In reply to Marcos Dione from comment #7)
> 13:50 $ ssh -v -oControlMaster=yes -R/tmp/sock:/tmp/sock uk-janderson
> OpenSSH_8.3p1 Ubuntu-1, OpenSSL 1.1.1f  31 Mar 2020
> [...]
> debug1: Remote connections from /tmp/sock:-2 forwarded to local
> address /tmp/sock:-2
> [...]
> debug1: remote forward success for: listen /tmp/sock:-2, connect
> /tmp/sock:-2
> 
> 
> mdione@uk-janderson:~$ ssh -oControlPath=/tmp/sock -O forward -L
> 1234:127.0.0.1:22 localhost
> debug1: client_input_channel_open: ctype
> forwarded-streamlocal@openssh.com rchan 2 win 2097152 max 32768
> debug1: client_request_forwarded_streamlocal: request: /tmp/sock
> debug1: connect_next: host /tmp/sock ([unix]:/tmp/sock): No such
> file or directory
> connect to /tmp/sock port -2 failed: No such file or directory
> debug1: failure forwarded-streamlocal@openssh.com
> muxclient: master hello exchange failed
> 
> So I guess my cliente/server mix do not interoperate?

No, that looks like listening socket on the server is either gone or the forward was not established.  If the problem is the mux version it'll give an error along the lines of "Unsupported multiplexing protocol version"

> Where can i read about the mux protocol changes?

https://github.com/openssh/openssh-portable/blob/master/clientloop.h, any commit that changes SSHMUX_VER.

A shell one-liner tells me version 1 shipped in V_4_2_P1 through V_5_0_P1, version 2 shipped in V_5_1_P1 through V_5_3_P1 and version 4 shipped in V_5_4_P1 and up.  It looks like version 3 was never in a release.

> I can't find anything on
> Debian's changelog or News files, and there doesn't seems to be a
> changelog on your side?

Well like I said it's intended to be internal to ssh, not used in this way.
Comment 9 Damien Miller 2021-04-23 15:10:24 AEST
closing resolved bugs as of 8.6p1 release