Lucian Boca
Lucian Boca

Reputation: 467

retrieve SSH unique session ID

I wonder if there is any way to retrieve, for both a server and a client connected through ssh (OpenSSH), some unique session identifier (let this be USID).

This would be used to restrict the execution of a specific (custom) software (let it be a.exe), so it can only be executed through a specific ssh session, even if other users (potentially root) have access to that executable:

The communication channels between X and C, X and S are secure, so the only issue here is retrieving that USID without having to write my own ssh client and/or server.

Any ideas?

Upvotes: 2

Views: 4125

Answers (2)

Ivan Vučica
Ivan Vučica

Reputation: 9679

I'm responding 14 years later, which has seen quite a bit of development in the public space in the area. Even though you probably do not require an update anymore, I'll respond anyway, for readers who run into this via public search like I did.

You are really phrasing two problems:

  1. How do I identify a particular connection (a session ID)?
  2. How do I make sure that a particular connection is coming from a machine that is considered safe?

You are really asking a solution for the second bit, but I'll cover both.


Specifying a session ID

Assuming you really require a session ID to be passed from a client to a server, one way to do it without hacking the client or the server is to build a wrapper around the client.

A small wrapper can generate a UUID, export it into the environment, then pass it via SendEnv YOUR_VARIABLE_NAME.

#!/bin/bash

export SSH_SESSION_ID=$(uuidgen)  # this is your USID
ssh -O SendEnv SSH_SESSION_ID "$1"  # or set it in ~/.ssh/config, or /etc/ssh/ssh_config

Aside from having the client SendEnv, your server needs to accept it. Adjust /etc/ssh/sshd_config to AcceptEnv SSH_SESSION_ID.

See an answer on passing environment variables.

Identifying the connection could be interesting for another reason; tracing job execution across machines and joining the spans together with OpenTelemetry, or pairing the access with a user for legal reasons, or for analysis reasons. I would not really do it for security / ACL reasons.

You can likely do a hack with tcpwrappers (/etc/hosts.allow) and the aclexec stanza in there. sshd : ALL : aclexec /opt/sshd-hosts_options.sh %a would pass in the address as the first argument to your custom script, but you can pass in multiple arguments. %p would give you the PID that's trying to do ACLing, so you can inspect procfs (/proc/PID/...) for the connections incoming to that server. If the wrapper around the client uses ProxyCommand to specify an intermediary for the connection, you can inspect what the source TCP port is, and register that with your ACLing service (assumption: ACLing service trusts the client to register the source port), allowing the server's aclexec script to validate the connection is really coming from a trusted party.

Caveat: around 2017, there was chatter about tcpwrappers being deprecated and possibly removed from OpenSSH. I'm on Debian, and use of tcpwrappers on incoming connections works fine; Fedora's docs say it's removed by default on Fedora 28.

Yet another caveat: If a user uses a bouncer or uses a non-local relay via ProxyCommand, you might also have a different address/port visible via tcpwrappers.


Validating just the machine safety as connection time: Use of SSH certs is likely enough

It is possible to instead just focus on the actual goal: ensure that the trusted machine is "safe enough".

Instead of the complication with the connection itself, let's focus on just giving the authentication token which is valid for 'long enough', as long as the machine is trusted.

SSH comes with a new type of keys which are not really keys: they're certificates. They're not in the formats of usual TLS certificates (though they can be converted), but the main benefit for us is that they have expiration time, and can be revoked.

  1. The server can be configured to trust a particular certificate authority.
  2. The certificate authority can refuse to issue certs to machines that are not trusted.
  3. The certificates can have a short timespan, requiring the user to re-validate the machine and reissue a cert; the client-side wrapper can perform this transparently for the user.

Manpages for ssh-keygen, sshd_config etc contain enough information: see mainly TrustedUserCAKeys, but also CASignatureAlgorithms, HostCertificate, RevokedKeys.

Eventually the cert expires, and if the client became untrusted in the meantime, the service you write to issue certs rejects the request.

Downside: User can, of course, still copy the cert from a trusted machine to an untrusted machine.


Depending on your setup, if you have a functioning Kerberos install, you might instead choose to reject connections to Kerberos from untrusted machines. This would also prevent the user from SSHing from an untrusted machine.

Downside: Ticket could still be copied from a trusted machine to an untrusted one.


All in all:

I would rather build the SSH CA / Kerberos infrastructure and care about "is the server able to present a trustworthy ssh cert / Kerberos ticket", and have a short max age of a cert, than actually identify the connection with a session ID.


I wrote a bit more, but I felt like I went into too many details. If the shortened text is lacking in detail too much, please ask for clarification; in particular, I removed some tcpwrappers samples, some random ideas about identifying connections and some ramblings about SSH CA.

Upvotes: 1

phatmanace
phatmanace

Reputation: 5031

seems to me in a round about way, you are trying to re-implement kerberos. Seems to me that you want to GSSAPI secure the transport between client and server; so your client needs to authenticate to the server.

Typical way of doing this would be to 'kinit' to a prinicpal using a keytab, and then passing this credential to the server. Kerberos ensures that it's reasonably hard to fake.

that's probably going to be a little less brittle than the method that you describe above.

-Ace

Upvotes: 1

Related Questions