IETF-SSH archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Unix Domain Socket Forwarding



William Ahern wrote:
I'd like to solicit opinions on a protocol for Unix domain socket
forwarding.

As a proof-of-concept I wrote a patch to OpenSSH 4.3p2 and added
the following messages:

forwarded-streamlocal%openssh.com@localhost
direct-streamlocal%openssh.com@localhost
streamlocal-forward%openssh.com@localhost
cancel-streamlocal-forward%openssh.com@localhost

We have also implemented an extension to connect domain local streams for couple of projects. To circumvent (or ignore) the problem arising from umasks and different local stream implementations and access control systems, we only implemented "direct-local%ssh.com@localhost" and left remote forwarding of local streams aside. In my opinion remote forwarding is anyways a feature that is not very often needed but is very often considered harmful by corporate security people.

However a few points:

1) In my opinion, this mechanism should be independent of server system specific implementation of local streams. 2) Stream identifiers should be opaque strings, which could look like pathnames in unix server but in some other system they could look something else. 3) Point 2 makes remote forwarding actually somewhat tricky, since the client should then know what kind of local stream naming policy the server host has. 4) It is not absolutely necessary to make stream identifiers to be full pathnames of unix system sockets. Instead the server could maybe prefix the path somehow and maybe do some access control along the way. 5) Some systems don't enforce the access bits to local domain sockets but if they otherwise implement unix filesystem security, the access control can be implemented by setting the access bits of the parent directory to reflect the access policy wanted.

We basically only defined an extension channel type and only one format:

      byte      SSH_MSG_CHANNEL_OPEN
      string    "direct-local%ssh.com@localhost"
      uint32    sender channel
      uint32    initial window size
      uint32    maximum packet size
      string    opaque local stream endpoint specifier

The confirmation message does not have any channel type specific data.

I can go into details on the format of those messages if anybody wishes, but
to cut to the chase I'm most interested in hearing what people have to say
about umask settings, since some SysV platforms obey file permissions on
Unix domain sockets.

Since they can't be trusted, the only way is to use subdirectories. I still maintain that the client side method should be independent of this. For example in Windows, the logical choice would be to use named pipes for "local streams".

Maybe there could be some kind of access control specifier in the remote forward request that at least could specify whether the socket should be connectable by anybody or only by the user itself. I haven't thought this so much, but to me it seems, that most obvious choice there would be using some kind of mapping between the real socket name and the local stream id. For example local stream /tmp/foo/bar could actually be presented in the server system as unix domain socket /tmp/foo/bar/sock and the permissions of the directory /tmp/foo/bar would be set according to the access control parameters in the request and access bits of the actual socket would be 666 to make everything work identically in systems that enforce the socket node permissions and the ones that do not. Of course all this would be annoying if one wants to listen or connect to local domain sockets not using the naming convention above.

In my implementation I decided to let each end handle the umask
autonomously, partly for simplictity's sake, partly so that the remote side
is solely responsible for local policy, and lastly with the notion that
"streamlocal" might be translatable on Windows (aside from Cygwin's
compatbility layer) and that umask in such a case likely could have no
useful meaning.

Absolutely.

Oh, and another interesting problem is handling unlinking of existing
sockets. Since, unfortunately, Unix domain sockets aren't first class
objects in the Unix namespace model, handling dangling socket paths poses
some headaches.

Very much so. This was also a reason why I decided to forget the remote forwarding for local streams. In our implementations, the local stream identifier (e.g. unix domain socket pathname) is always discovered by the client some other way and then used as a parameter to "direct-local%ssh.com@localhost" request. In this way, client doesn't need to know what kind of semantics (if any) the local stream identifier has. Also the "stream listener" removal is something that is never done by the server but some other component. Of course in remote forwards this would not be the case.

Again, I left this up to each side, independently.

I can't see any other way.

One scenario that I think remote forwarding might be implemented in a local stream abstraction independent and at least somewhat secure way would be as follows:

1) Client requests the forwarding but does not specify the actual listener. Something like:

      byte      SSH_MSG_GLOBAL_REQUEST
      string    "local-forward@whatever.invalid.domain"
      boolean   want reply (always true)
      int32     access policy specifier (to be defined)

2) The server generates the path for socket according to the policy using access bits of the socket parent directory. Of course it also creates the directory and the actual socket. Then it returns the identifier of the listener (= unix domain socket path) in:

      byte      SSH_MSG_REQUEST_SUCCESS
      string    opaque local stream endpoint specifier

3) Now client could use this local stream id to connect to the listener just created (e.g. "direct-local%ssh.com@localhost" above). In practise it would not connect to the listener itself but rather deliver the endpoint identifier to some other component for connecting either through the secsh connection or locally in the server system.

In this scenario the dangling dead sockets would not be a problem, since the server can always generate a path that is free.

Regards,
--
Timo J. Rinne <tri%ssh.com@localhost>        Valimotie 17       +358 20 500 7000 T
Chief Technology Officer           FIN-00380 Helsinki +358 20 500 7397 F
SSH Communications Security Corp.  Finland            http://www.ssh.com



Home | Main Index | Thread Index | Old Index