Mailing List Archive

Feature proposal: ProxyUseFdpass-like behavior for a regular ssh session
Hi,

I have a feature that I'd like to implement if it's acceptable to the
OpenSSH developers.

In short, I'd like to implement a mode for running an ssh session which
functions like ProxyCommand+ProxyUseFdpass: the specified command is
passed a socketpair, and is then expected to pass out a file descriptor;
IO from the client will then be forwarded to and from that file
descriptor.

This is similar to -W, except that instead of forwarding stdin to a
socket connected to a specified host and port, stdin is forwarded to an
arbitrary file descriptor as passed out by the command.

The advantage relative to today is reduced overhead and reduced
complexity. One could achieve similar behavior today by just running a
command which proxies stdio to a user-specified file descriptor; but the
extra command both adds overhead and increases complexity. The argument
is the same as the argument for ProxyUseFdpass: By allowing the user to
specify which file descriptor OpenSSH should forward data to, that
overhead and complexity is elimiated.

I'm not an expert on the SSH protocol, but I believe this would require
a protocol change; a new @openssh.com channel type, perhaps called
fdpass@openssh.com.

Use cases for this:

- -W-style socket forwarding for AF_UNIX and other socket families. This
is useful for, among other things, accessing remote daemons without
extra overhead.

- More customization of AF_INET socket parameters for -W, including
customization of the source address. This could be achieved with an
invocation of "ssh -XXX nc -f -s 1.2.3.4". (I see this was
coincidentally requested on this list a few weeks ago)

- Implementation of other more dynamic forwarding modes, without added
overhead, and without requiring OpenSSH to support them. As a concrete
example, I'd like to use TCP forwarding like -L, but with a listening
socket pre-created by the user and passed in to ssh; this is useful when
using chroot/container/network namespacing features, where ssh might be
running in a separate container from the listening socket. This could be
achieved with minimal overhead by a simple user-written script which
accepts connections on the listening socket and runs "ssh -XXX nc -f
1.2.3.4 1234" for each connection.

- In general, zero-extra-overhead usage of SSH channels. With this
fd-passing behavior, the user is able to determine the file descriptors
used by OpenSSH on both sides, and OpenSSH simply forwards data from the
user-controlled file descriptors on one side to the other side.
Zero-overhead access to SSH channels like this has many uses in
application programming.

I'm happy to implement this with whatever design is preferred by the
OpenSSH developers, as long as it provides the core feature of
user-controlled minimal-overhead access to SSH channels which are
maintained by OpenSSH, without the user having to implement the SSH
protocol.

Thanks for OpenSSH!
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Feature proposal: ProxyUseFdpass-like behavior for a regular ssh session [ In reply to ]
Hi Spencer,

Spencer Baugh wrote:
> In short, I'd like to implement a mode for running an ssh session which
> functions like ProxyCommand+ProxyUseFdpass: the specified command is
> passed a socketpair, and is then expected to pass out a file descriptor;
> IO from the client will then be forwarded to and from that file
> descriptor.
>
> This is similar to -W, except that instead of forwarding stdin to a
> socket connected to a specified host and port, stdin is forwarded to an
> arbitrary file descriptor as passed out by the command.

So you know that ProxyCommand executes on the client before the session
starts while -W opens a "direct-tcpip" channel inside the session making
the peer sshd create a TCP connection to the -W host and port parameters,
right?

To me, these two don't compare at all well.

Since "direct-tcpip" is a standardized channel type it's reasonable
to expect widespread support in servers and -W/-J work widely.


> I'm not an expert on the SSH protocol, but I believe this would require
> a protocol change; a new @openssh.com channel type, perhaps called
> fdpass@openssh.com.

If you want sshd itself to implement this then yes.


But couldn't you achieve what you want with a subsystem configured in
existing sshd_config and invoked through ssh -s on clients?


> - -W-style socket forwarding for AF_UNIX and other socket families.
> This is useful for, among other things, accessing remote daemons
> without extra overhead.

Which software is AF_UNIX client in that use case?

Do you envision the original daemon client utility transparently using
the SSH channel? If so, how?


> - More customization of AF_INET socket parameters for -W, including
> customization of the source address. This could be achieved with an
> invocation of "ssh -XXX nc -f -s 1.2.3.4". (I see this was
> coincidentally requested on this list a few weeks ago)

Right, direct-tcpip doesn't permit the client to dictate what address
the sshd TCP client binds to for the outgoing connection.


> - Implementation of other more dynamic forwarding modes, without added
> overhead, and without requiring OpenSSH to support them. As a concrete
> example, I'd like to use TCP forwarding like -L, but with a listening
> socket pre-created by the user and passed in to ssh; this is useful when
> using chroot/container/network namespacing features, where ssh might be
> running in a separate container from the listening socket. This could be
> achieved with minimal overhead by a simple user-written script which
> accepts connections on the listening socket and runs "ssh -XXX nc -f
> 1.2.3.4 1234" for each connection.

How is the socket passed out of the container/namespace? In a pipe? Which?


> - In general, zero-extra-overhead usage of SSH channels. With this
> fd-passing behavior, the user is able to determine the file descriptors
> used by OpenSSH on both sides, and OpenSSH simply forwards data from the
> user-controlled file descriptors on one side to the other side.
> Zero-overhead access to SSH channels like this has many uses in
> application programming.

Is this also a subsystem candidate?


> user-controlled minimal-overhead access to SSH channels

A subsystem is pretty much that..?


> which are maintained by OpenSSH

What does that actually mean?


> without the user having to implement the SSH protocol.

Hm, why would they have to?


I'm sorry - as you can tell I'm pretty confused. Can you help me out?


Thanks

//Peter
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Feature proposal: ProxyUseFdpass-like behavior for a regular ssh session [ In reply to ]
Peter Stuge <peter@stuge.se> writes:
> Spencer Baugh wrote:
>> In short, I'd like to implement a mode for running an ssh session which
>> functions like ProxyCommand+ProxyUseFdpass: the specified command is
>> passed a socketpair, and is then expected to pass out a file descriptor;
>> IO from the client will then be forwarded to and from that file
>> descriptor.
>>
>> This is similar to -W, except that instead of forwarding stdin to a
>> socket connected to a specified host and port, stdin is forwarded to an
>> arbitrary file descriptor as passed out by the command.
>
> So you know that ProxyCommand executes on the client before the session
> starts while -W opens a "direct-tcpip" channel inside the session making
> the peer sshd create a TCP connection to the -W host and port parameters,
> right?
>
> To me, these two don't compare at all well.
>
> Since "direct-tcpip" is a standardized channel type it's reasonable
> to expect widespread support in servers and -W/-J work widely.

Yes - -W and ProxyCommand are completely different things. I only
mentioned ProxyCommand because the protocol that ProxyUseFdpass is the
same protocol I'm proposing here. Other than that, ProxyCommand is
completely unrelated and irrelevant to what I'm proposing.

>> I'm not an expert on the SSH protocol, but I believe this would require
>> a protocol change; a new @openssh.com channel type, perhaps called
>> fdpass@openssh.com.
>
> If you want sshd itself to implement this then yes.
>
> But couldn't you achieve what you want with a subsystem configured in
> existing sshd_config and invoked through ssh -s on clients?

Maybe I'm totally confused about subsystems, but isn't a subsystem
invoked in the same way as any command? i.e., sshd creates some pipes
and passes them into the subsystem - same as with a user-specified
command.

There's no way to (AFAIK) define a subsystem such that:
1. sshd will run the subsystem with a Unix domain socketpair
2. the subsystem will send a fd over that socketpair
3. sshd will receive a fd from the socketpair (with mm_receive_fd)
4. sshd then forward data on that channel to and from that fd.

That's necessary to avoid the overhead of the subsystem process reading
data from the sshd-created pipes and just copying it over to another fd,
adding extra copies and userspace transitions for no benefit.

For example, if the subsystem or command was to make a network
connection, then the process running for the subsystem would be
pointless extra overhead after the connection is established. That
overhead can be eliminated by passing the fd out with the protocol
described above (which is also the protocol that ProxyUseFdpass uses).

>> - -W-style socket forwarding for AF_UNIX and other socket families.
>> This is useful for, among other things, accessing remote daemons
>> without extra overhead.
>
> Which software is AF_UNIX client in that use case?

nc -F -U
(well, ignoring the fact that BSD nc doesn't actually support -F and -U
being used together)
Or, a simple Python script which does the same thing.

> Do you envision the original daemon client utility transparently using
> the SSH channel? If so, how?

I'm not sure what you mean by this, but no, I don't (think I) envision
that.

>> - More customization of AF_INET socket parameters for -W, including
>> customization of the source address. This could be achieved with an
>> invocation of "ssh -XXX nc -f -s 1.2.3.4". (I see this was
>> coincidentally requested on this list a few weeks ago)
>
> Right, direct-tcpip doesn't permit the client to dictate what address
> the sshd TCP client binds to for the outgoing connection.

Indeed, and my suggestion does permit that.

>> - Implementation of other more dynamic forwarding modes, without added
>> overhead, and without requiring OpenSSH to support them. As a concrete
>> example, I'd like to use TCP forwarding like -L, but with a listening
>> socket pre-created by the user and passed in to ssh; this is useful when
>> using chroot/container/network namespacing features, where ssh might be
>> running in a separate container from the listening socket. This could be
>> achieved with minimal overhead by a simple user-written script which
>> accepts connections on the listening socket and runs "ssh -XXX nc -f
>> 1.2.3.4 1234" for each connection.
>
> How is the socket passed out of the container/namespace? In a pipe? Which?

There are a number of ways to get sockets/file descriptors out of a
container - basic file descriptor passing over Unix domain sockets is
one way (note that this is completely unrelated to my suggestion of
using this in ssh), and another is using setns(2) on Linux.

>> - In general, zero-extra-overhead usage of SSH channels. With this
>> fd-passing behavior, the user is able to determine the file descriptors
>> used by OpenSSH on both sides, and OpenSSH simply forwards data from the
>> user-controlled file descriptors on one side to the other side.
>> Zero-overhead access to SSH channels like this has many uses in
>> application programming.
>
> Is this also a subsystem candidate?
>
>> user-controlled minimal-overhead access to SSH channels
>
> A subsystem is pretty much that..?

A subsystem is run with file descriptors created by sshd; see my
description above ("That's necessary to avoid the overhead...") for why
that's insufficient.

>> which are maintained by OpenSSH
>
> What does that actually mean?

I mean as opposed to writing their own ssh client, which I don't think
should be necessary just to get low-overhead access to SSH channels.

>> without the user having to implement the SSH protocol.
>
> Hm, why would they have to?

Well, this is probably very obscure, but one could avoid a lot of the
work in writing an ssh client by using MUX_C_PROXY with OpenSSH. I
wanted to pre-empt any suggestion of that.

> I'm sorry - as you can tell I'm pretty confused. Can you help me out?

Yes, that's understandable. Hopefully my explanation clarifies a bit?
Again, ProxyCommand has nothing to do with my suggestion, except in that
ProxyUseFdpass has some functionality/speaks a protocol that I want to
also use in another part of OpenSSH.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Feature proposal: ProxyUseFdpass-like behavior for a regular ssh session [ In reply to ]
On Wed, 26 May 2021, Spencer Baugh wrote:

> Hi,
>
> I have a feature that I'd like to implement if it's acceptable to the
> OpenSSH developers.
>
> In short, I'd like to implement a mode for running an ssh session which
> functions like ProxyCommand+ProxyUseFdpass: the specified command is
> passed a socketpair, and is then expected to pass out a file descriptor;
> IO from the client will then be forwarded to and from that file
> descriptor.
>
> This is similar to -W, except that instead of forwarding stdin to a
> socket connected to a specified host and port, stdin is forwarded to an
> arbitrary file descriptor as passed out by the command.

This is basically how the multiplexing protocol works right now.
Take a look at mux.c:mux_client_request_session() - it passes the
stdin, stdout and stderr fds to the primary multiplexing process.

From what you describe, you couple probably use this facility with
a custom client that spoke the simple (but undocumented) multiplexing
protocol to do what you need.

-d
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Feature proposal: ProxyUseFdpass-like behavior for a regular ssh session [ In reply to ]
On Thu, 27 May 2021, Damien Miller wrote:

> This is basically how the multiplexing protocol works right now.
> Take a look at mux.c:mux_client_request_session() - it passes the
> stdin, stdout and stderr fds to the primary multiplexing process.
>
> From what you describe, you couple probably use this facility with
> a custom client that spoke the simple (but undocumented) multiplexing
> protocol to do what you need.

See also the mux proxy mode that Markus added (cf portable commit 8d0578)
Which allows a client to talk to the ssh channels code pretty much
directly - it allows clients for arbitrary extension protocols to be
written without modifying OpenSSH

-d
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Feature proposal: ProxyUseFdpass-like behavior for a regular ssh session [ In reply to ]
Damien Miller <djm@mindrot.org> writes:
> On Wed, 26 May 2021, Spencer Baugh wrote:
>> Hi,
>>
>> I have a feature that I'd like to implement if it's acceptable to the
>> OpenSSH developers.
>>
>> In short, I'd like to implement a mode for running an ssh session which
>> functions like ProxyCommand+ProxyUseFdpass: the specified command is
>> passed a socketpair, and is then expected to pass out a file descriptor;
>> IO from the client will then be forwarded to and from that file
>> descriptor.
>>
>> This is similar to -W, except that instead of forwarding stdin to a
>> socket connected to a specified host and port, stdin is forwarded to an
>> arbitrary file descriptor as passed out by the command.
>
> This is basically how the multiplexing protocol works right now.
> Take a look at mux.c:mux_client_request_session() - it passes the
> stdin, stdout and stderr fds to the primary multiplexing process.
>
> From what you describe, you couple probably use this facility with
> a custom client that spoke the simple (but undocumented) multiplexing
> protocol to do what you need.

I've been looking fairly deeply at the multiplexing protocol (I'd
probably use this feature primarily through the multiplexing protocol)
but I don't think it's exactly what I'm talking about.

You're right that a multiplexing client passes stdin/stdout/stderr to
the primary multiplexing process, on the client side of the connection.
So on the client side, the user can completely control what file
descriptors are used, by passing in whatever stdin/stdout/stderr they
want.

But I'm concerned about the server side; there, it's sshd that creates
the file descriptors. I'd like it to be possible to specify to sshd
which file descriptors the channel should be forwarded to, rather than
sshd just creating its own pipes and passing those to the executed
command. (And my proposal is to do that by having the executed command
return one or more file descriptors)
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev