Discussion:
User id for the forwarder ports
(too old to reply)
Esben Nielsen
2016-01-03 00:03:27 UTC
Permalink
Hi,

Question:

Can a TCP server (running on the same host as the OpenSSH server) know
the user id/name of a user forwarding an TCP port ?

I.e. if someone on some client machine does
ssh -L9999:localhost:9999 ***@somehost
nc localhost 9999
and a service accepts the connection on port localhost:9999 on
somehost, can it somehow safely read out the user name "someuser"?

Long explanation:

We consider using SSH port forwarding as a way to enforce
authentication and authorization in an old application (running on
Linux) exposing a quite a few TCP connections.

On the client side the clients can use OpenSSH client or Putty to make
a Socks proxy. If their application framework already supports Socks
they do not have to change much to connect. Or something like libssh
can be used to include the ssh client side into the application.

On the server side the sshd_config can be used to set up allowed ports
per user or group. This is, however, not good enough, because the
application will not know the original user id, so it can niether log
actions, nor allow or block actions not allowed for that particular
user.

So my question is:
Is there any way to let the TCP application server know the user id of
the SSH forwarded TCP connection?
If no, would it be possible to set up the OpenSSH server to do
something special per destination port basis, such as connecting to a
UNIX socket instead of a TCP socket or sending the user ID as the
first thing on the connection ?
(We could use UNIX socket forwarding, but the the client side can't
use a Socks, and most other clients such as libssh does not support it
either...)

Regards,
Esben
gsslist+ (Gregory Seidman)
2016-01-03 01:13:09 UTC
Permalink
I think what you are looking for is ident
<https://en.wikipedia.org/wiki/Ident_protocol>, but while I could see using
it for auditing purposes I would be uncomfortable recommending it as an
authentication mechanism. You would need to be running some identd
(available in any Linux distro, usually gidentd), often through
inetd/xinetd.

--Greg
Post by Esben Nielsen
Hi,
Can a TCP server (running on the same host as the OpenSSH server) know
the user id/name of a user forwarding an TCP port ?
I.e. if someone on some client machine does
nc localhost 9999
and a service accepts the connection on port localhost:9999 on
somehost, can it somehow safely read out the user name "someuser"?
We consider using SSH port forwarding as a way to enforce
authentication and authorization in an old application (running on
Linux) exposing a quite a few TCP connections.
On the client side the clients can use OpenSSH client or Putty to make
a Socks proxy. If their application framework already supports Socks
they do not have to change much to connect. Or something like libssh
can be used to include the ssh client side into the application.
On the server side the sshd_config can be used to set up allowed ports
per user or group. This is, however, not good enough, because the
application will not know the original user id, so it can niether log
actions, nor allow or block actions not allowed for that particular
user.
Is there any way to let the TCP application server know the user id of
the SSH forwarded TCP connection?
If no, would it be possible to set up the OpenSSH server to do
something special per destination port basis, such as connecting to a
UNIX socket instead of a TCP socket or sending the user ID as the
first thing on the connection ?
(We could use UNIX socket forwarding, but the the client side can't
use a Socks, and most other clients such as libssh does not support it
either...)
Regards,
Esben
_______________________________________________
openssh-unix-dev mailing list
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Darren Tucker
2016-01-03 02:18:43 UTC
Permalink
Post by Esben Nielsen
Can a TCP server (running on the same host as the OpenSSH server) know
the user id/name of a user forwarding an TCP port ?
I.e. if someone on some client machine does
nc localhost 9999
and a service accepts the connection on port localhost:9999 on
somehost, can it somehow safely read out the user name "someuser"?
If sshd is running with PrivilegeSeparation (which it does by default)
then the sshd for that connection will be running as "someuser". On
Linux, your application can figure out what that user is by calling
getsockopt with SO_PEERCRED on the socket (there's example code in
https://anongit.mindrot.org/openssh.git/tree/openbsd-compat/bsd-getpeereid.c)
--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Esben Nielsen
2016-01-04 06:15:26 UTC
Permalink
Post by Darren Tucker
Post by Esben Nielsen
Can a TCP server (running on the same host as the OpenSSH server) know
the user id/name of a user forwarding an TCP port ?
I.e. if someone on some client machine does
nc localhost 9999
and a service accepts the connection on port localhost:9999 on
somehost, can it somehow safely read out the user name "someuser"?
If sshd is running with PrivilegeSeparation (which it does by default)
then the sshd for that connection will be running as "someuser". On
Linux, your application can figure out what that user is by calling
getsockopt with SO_PEERCRED on the socket (there's example code in
https://anongit.mindrot.org/openssh.git/tree/openbsd-compat/bsd-getpeereid.c
)
--
Darren Tucker (dtucker at zip.com.au)
Post by Darren Tucker
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
--
Sendt fra Gmail Mobil
Esben Nielsen
2016-01-04 06:26:22 UTC
Permalink
Unfortunately, SO_PEERCRED only works of UNIX domain sockets. For local tcp
connections the UID is returened as -1.

A solution could be to make a mapping option in sshd_config along with
OpenPermit, such forwarding to say localhost:4000 can be remapped to UNIX
socket /var/forwards/4000.

Esben
Post by Darren Tucker
Post by Esben Nielsen
Can a TCP server (running on the same host as the OpenSSH server) know
the user id/name of a user forwarding an TCP port ?
I.e. if someone on some client machine does
nc localhost 9999
and a service accepts the connection on port localhost:9999 on
somehost, can it somehow safely read out the user name "someuser"?
If sshd is running with PrivilegeSeparation (which it does by default)
then the sshd for that connection will be running as "someuser". On
Linux, your application can figure out what that user is by calling
getsockopt with SO_PEERCRED on the socket (there's example code in
https://anongit.mindrot.org/openssh.git/tree/openbsd-compat/bsd-getpeereid.c
)
--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
--
Sendt fra Gmail Mobil
Damien Miller
2016-01-04 07:36:43 UTC
Permalink
Post by Esben Nielsen
Hi,
Can a TCP server (running on the same host as the OpenSSH server) know
the user id/name of a user forwarding an TCP port ?
No; there are a number of impediments to implementing it.

The SSH protocol doesn't support sending this information. It could
conceivably be added as an extension though. We'd need to be careful
in designing this - many users would be surprised if ssh started "leaking"
user identifiers across forwarding channels.

If the lack of protocol support was solved, another problem would be
how the information is relayed to the next application. I'm not aware of
a kernel mechanism to allow an application to fake a user identity
across a local socket.

Next problem: if one existed, it would almost certainly require root
privileges and sshd takes great care to get rid off root privileges
wherever possible. They certainly aren't used for port forwarding.

TLDR: doing this is hard (I haven't even gone into user/uid mapping
problems) and not likely to happen soon, sorry.

-d
Esben Nielsen
2016-01-04 08:50:33 UTC
Permalink
I propose making options in sshd_config to set up a mapping for each port:
if the user tries to forward localhost:4000 you can specify in sshd_config
that it is a UNIX socket connect to say /var/sshforward/4000.sock.

Now the service can listen on /var/sshforward/4000.sock and use SO_PEERCRED
(which is not working on local top sockets on my system at least).

Esben
Post by Damien Miller
Post by Esben Nielsen
Hi,
Can a TCP server (running on the same host as the OpenSSH server) know
the user id/name of a user forwarding an TCP port ?
No; there are a number of impediments to implementing it.
The SSH protocol doesn't support sending this information. It could
conceivably be added as an extension though. We'd need to be careful
in designing this - many users would be surprised if ssh started "leaking"
user identifiers across forwarding channels.
If the lack of protocol support was solved, another problem would be
how the information is relayed to the next application. I'm not aware of
a kernel mechanism to allow an application to fake a user identity
across a local socket.
Next problem: if one existed, it would almost certainly require root
privileges and sshd takes great care to get rid off root privileges
wherever possible. They certainly aren't used for port forwarding.
TLDR: doing this is hard (I haven't even gone into user/uid mapping
problems) and not likely to happen soon, sorry.
-d
--
Sendt fra Gmail Mobil
Peter Stuge
2016-01-04 15:06:25 UTC
Permalink
Post by Damien Miller
Post by Esben Nielsen
Can a TCP server (running on the same host as the OpenSSH server) know
the user id/name of a user forwarding an TCP port ?
No; there are a number of impediments to implementing it.
The SSH protocol doesn't support sending this information.
The original question was about the server-side username. I guess the
solution is platform-specific.


//Peter
Gert Doering
2016-01-04 17:24:21 UTC
Permalink
Hi,
Post by Peter Stuge
The original question was about the server-side username. I guess the
solution is platform-specific.
"ident", if the server can be extended to query the ident server.

(it has been mentioned before, and if the root account on the server can
be trusted, ident is good enough here)

gert
--
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany ***@greenie.muc.de
fax: +49-89-35655025 ***@net.informatik.tu-muenchen.de
Ángel González
2016-01-20 00:34:50 UTC
Permalink
Post by Esben Nielsen
Hi,
Can a TCP server (running on the same host as the OpenSSH server) know
the user id/name of a user forwarding an TCP port ?
(...)
Is there any way to let the TCP application server know the user id of
the SSH forwarded TCP connection?
Yes.
For instance a naive implementation could run a root netstat -e -tp
looking for the other side of its connection.

Even with an optimized search of the connection, I think you would need
to end up with a root process
scanning all fds per check, though.


Additionally, I should note that you seem to be attempting the wrong
solution ("tacklinh openssh in the middle") for your problem of
authorizing users, making it needlessly complex.
For instance, given that you seem to be developing the server side of
the application, why don't you require socks authentication? (yes, socks
protocol supports authentication, and even if the client implementation
doesn't, it'd be easier to fix it than your solution)

Regards

Continue reading on narkive:
Loading...