Mailing List Archive

SSH certificate and serverside ForceCommand
Hi,
We're developing an open source project that uses SSH certificates. We
issue short lived certificates (few minutes) to execute commands on behalf
of users. We have a use case where we need to issue certificates with 10
days validity and store them, so we put a command inside them:

ssh-keygen -s ca-key -I certN -n user -O force-command="wget something" -V
+10d user-key.pub

and it works as expected. This way, if the certificate is stolen, it can
only be used to execute that command (also the CA is only trusted from some
hosts, no root login, etc).

We also want to use "ForceCommand" option on the server (inside a "Match"
section) to put a wrapper that checks commands executed for this CA. If a
rogue certificate is issued, at least we can control what is executed.
However, as the command is embedded inside the certificate, the server
passes an empty "SSH_ORIGINAL_COMMAND" to the wrapper. I couldn't find any
additional option or environment variable for this case. We can pass the
command when the connection is established, but it defeats the purpose of
having the certificate's "force-command".

So, is there a way the wrapper could get the command embedded inside a
certificate?

As a side note, more information about the certificate (issue and
expiration time) could be useful for auditing. It would be useful too if
the server could log it (aside from CA, certificate serial, etc), but
couldn't find any option either.

Regards, Ale
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: SSH certificate and serverside ForceCommand [ In reply to ]
On 23/06/2020 16:11, Alejandro Dabin wrote:
> As a side note, more information about the certificate (issue and
> expiration time) could be useful for auditing. It would be useful too if
> the server could log it (aside from CA, certificate serial, etc), but
> couldn't find any option either.

AuthorizedPrincipalsCommand can use a number of tokens which are expanded:

           %%    A literal `%'.
           %F    The fingerprint of the CA key.
           %f    The fingerprint of the key or certificate.
           %h    The home directory of the user.
           %i    The key ID in the certificate.
           %K    The base64-encoded CA key.
           %k    The base64-encoded key or certificate for authentication.
           %s    The serial number of the certificate.
           %T    The type of the CA key.
           %t    The key or certificate type.
           %U    The numeric user ID of the target user.
           %u    The username.

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: SSH certificate and serverside ForceCommand [ In reply to ]
On Tue, 23 Jun 2020, Alejandro Dabin wrote:

> Hi,
> We're developing an open source project that uses SSH certificates. We
> issue short lived certificates (few minutes) to execute commands on behalf
> of users. We have a use case where we need to issue certificates with 10
> days validity and store them, so we put a command inside them:
>
> ssh-keygen -s ca-key -I certN -n user -O force-command="wget something" -V
> +10d user-key.pub
>
> and it works as expected. This way, if the certificate is stolen, it can
> only be used to execute that command (also the CA is only trusted from some
> hosts, no root login, etc).
>
> We also want to use "ForceCommand" option on the server (inside a "Match"
> section) to put a wrapper that checks commands executed for this CA. If a
> rogue certificate is issued, at least we can control what is executed.
> However, as the command is embedded inside the certificate, the server
> passes an empty "SSH_ORIGINAL_COMMAND" to the wrapper. I couldn't find any
> additional option or environment variable for this case. We can pass the
> command when the connection is established, but it defeats the purpose of
> having the certificate's "force-command".
>
> So, is there a way the wrapper could get the command embedded inside a
> certificate?

I think your best avenue would be to set ExposeAuthInfo=yes in
sshd_config (note: requires a relatively recent sshd) and parse it out
of the certificate listed in $SSH_USER_AUTH. E.g.

grep "^publickey .*cert[a-z0-9-]*@openssh.com" $SSH_USER_AUTH \
| awk '{print $2 " " $3}' | ssh-keygen -Lf -

> As a side note, more information about the certificate (issue and
> expiration time) could be useful for auditing. It would be useful too if
> the server could log it (aside from CA, certificate serial, etc), but
> couldn't find any option either.

No, the logging tries to balance between usefulness and brevity.
I'm not sure why expiry information would be useful there - I would
have thought that it's either it's good and accepted or bad and not...

-d
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: SSH certificate and serverside ForceCommand [ In reply to ]
On 23/06/20, Alejandro Dabin (aledabin@gmail.com) wrote:
> As a side note, more information about the certificate (issue and
> expiration time) could be useful for auditing. It would be useful too if
> the server could log it (aside from CA, certificate serial, etc), but
> couldn't find any option either.

The identifier can be overloaded to have arbitrary information shown in
the audit log. I can't recall if you need to set LogLevel to something
above INFO.

Eg:
https://github.com/rorycl/sshagentca/blob/65f726c8480877366cfe13235247a67f0702393d/agentcert.go#L35

Rory

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: SSH certificate and serverside ForceCommand [ In reply to ]
On 23 jun. 2020 a las 23:21, Damien Miller wrote:
> I think your best avenue would be to set ExposeAuthInfo=yes in
> sshd_config (note: requires a relatively recent sshd) and parse it out
> of the certificate listed in $SSH_USER_AUTH. E.g.
>
> grep "^publickey .*cert[a-z0-9-]*@openssh.com" $SSH_USER_AUTH \
> | awk '{print $2 " " $3}' | ssh-keygen -Lf -

"ExposeAuthInfo" solves our use case because it allows to read the
certificate with user privilegies. It requires sshd >= 7.6, I was reading
the manual on my distro which uses 7.4.

Thank you all for your time, and for the great OpenSSH suite!

Regards, Ale
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev