44

I do not mean simply putting the public RSA key of a x.509 certificate into ~/.ssh/authorized_keys - I'm looking for a way to set up a ssh such that x.509 certificates signed by a pre-defined CA will automatically be granted access to the linked user account. RFC 6187 seems to suggest such a functionality, but I can't find any documentation on this, or whether it is implemented in OpenSSH at all.

Here's a more elaborate description of what I want to do:

  • A CA ("SSH-CA") is set up
  • This CA is used to sign user certificates with keyUsage=digitalSignature (and maybe the id-kp-secureShellClient extendedKeyUsage field)
  • This certificate can now be used to log in on a server. The server does not require the public key being present in the authorized_keys. Instead, it is set up to trust the SSH-CA to verify the public key and signature of the certificate (or certificate chain) and the username/UID (probably directly in the subjectAltName field, or maybe using some server-side mapping) before the usual RSA authentication takes place

So, (how) can this be achieved with OpenSSH, and if it requires a patch how can client-side modifications be kept minimal?


As an alternative I guess one could also use any S/MIME certificate plus a username to email-address mapping, without requiring an own CA. The client could also still use only the private RSA key and a certificate server is used obtain a certificate from a public key, additionally offering the possibility to use PGP certificates as well (e.g. via monkeysphere) without the user requiring any knowledge about all this as long as they simply provide a public key.

If it's not natively possible, I guess I could come up with a semi-automatic "implementation" of this by letting a script on the server automatically check a somehow else submitted certificate via openssl (or gnupg) and have the public key be put to the respective user's authorized_keys file - although at that point I am probably more or less re-doing the monkeyshere project...

0

5 Answers 5

32

OpenSSH does not officially support x.509 certificate based authentication:

The developers have maintained a stance that the complexity of X.509 certificates introduces an unacceptable attack surface for sshd. Instead, they have [recently] implemented an alternative certificate format which is much simpler to parse and thus introduces less risk.

...

OpenSSH just uses the low-level cryptographic algorithms from OpenSSL.

However Roumen Petrov publishes OpenSSH builds that do include X.509 support, and you could try with those.

X.509 certificates can [be] used as "user identity" and/or "host key" in SSH "Public Key" and "Host-Based" authentications.

Roumen Petrov's builds can be downloaded via this page.

Here's a Debian how-to for SSH with authentication key instead of password that might also prove useful in setting up your OpenSSH to accept x509 PKI for user authentication.

2
  • 3
    The Debian link is just about the usual key setup, but Roumen Petrov's build sounds like the solution Commented Feb 19, 2013 at 7:29
  • 2
    Please be careful with Roumen Petrov's build and do not reuse the same x509 certificate for ssl/https. Bugs like 3-Shake show that it is hard to use crypto securely within just the SSL protocol. Security of SSH implementations is never tested in this SSH-SSL key-reuse scenario!
    – user185953
    Commented Mar 14, 2019 at 16:37
31

Native certificate-based authentication is available in unmodified upstream OpenSSH. It is not, however, based on x.509.

First, generate your CA:

ssh-keygen -f ssh-ca

Next, install your CA key in .authorized_keys with a cert-authority prefix:

echo "cert-authority $(<ssh-ca.pub)" >>.ssh/authorized_keys

From that point, whenever a key is generated by a user:

ssh-keygen -f real-key

...the public portion can be signed by your SSH CA, whereafter it will be trusted by the server without that key itself being added to authorized_keys:

ssh-keygen -s ssh-ca -I identifier_for_your_real_key_goes_here real-key.pub
6
  • 2
    Thanks, I never read about this despite it being available since apparently 5.4 from 2011... github.com/cloudtools/ssh-ca might be of interest then. I'll try and check this sometime, in which case you'd deserve the checkmark Commented Oct 9, 2014 at 4:37
  • 1
    Absolutely incredible! I'm surprised I've never seen this done before!
    – user97193
    Commented Mar 22, 2019 at 16:56
  • It works for known_hosts too; one can put a CA in /etc/ssh/ssh_known_hosts for one's own domain, sign the host keys on the various servers with that CA, and then never again have a prompt asking a user to manually verify (or, more realistically, punt on manually verifying and assume) that a given host key for a server in that domain is valid. Commented Mar 22, 2019 at 21:11
  • (Of course, one needs to be able to distribute updates to that ssh_known_hosts with revocations for compromised host keys, but... them's the breaks). Commented Mar 22, 2019 at 21:12
  • 3
    I believe this answer provides OpenSSH certificate format, and not X.509 certificate format. X.509 certificate format is detailed in RFC 6187. Also see ssh-keygen and writing user certificate in X.509 format? on SuperUser.
    – user29925
    Commented Jul 15, 2019 at 15:58
3

With OpenSSH it's not possible. As said by @TildalWave you need to use the fork from Roumen Petrov PKIXSSH.

Once you have your X509 certificate you don't need to add the public key on the authorized_keys file.

You need to configure two things in the server side:

  • Add the certificate for the CA in the directory set by CACertificatePath directive in sshd_config file (normally /etc/ssh/ca/crt, I think) with a link for the hash of the certificate.

    For creating the link use openssl. Supposing the CA certificate has been copied under /ect/ssh/ca/crt/ca.crt the commands will be:

cd /etc/ssh/ca/crt/
ln -s ca.crt `openssl x509 -in ca.crt -noout -hash`.0
  • Add the "subject" information of x509 certificate to the authorized_keys file of the user (in destination server)

    Suppose the private key and the X509 certificate of the user is in ssh/id_rsa to get the subject run in the client:

openssl x509 -noout -subject -in .ssh/id_rsa

And them on the server, add this line with the prefix x509v3-sign-rsa subject= to the authorized_keys.

This line will have a content similar to this one:

x509v3-sign-rsa subject= /C=ES/ST=Pontevedra/L=Vigo/CN=testssh/[email protected]

As we can see, the authentication is really made trusting the CA for any valid x509 certificate from the user. We could generate a new certificate and it will be accepted with no intervention on server side.


After struggling for a few days I have written a post explaining the full process on a blog I have just deployed. You can read it at "OpenSSH with X509 certificates HOW TO".

0
1

CA Signed SSH keys

When you want to manage user's access out-of-bound, then you don't want to install their public key in authorized_keys files on the servers they need to access. Neither do you want to manage personal accounts, but instead use a principal (functional account i.e. admin) and grant a lease on it.

You can create a Certificate Signing Authority for Secure Shell (different from X509 TLS/SSL) simply by creating an ssh keypair. The CA's public key is installed on all servers, and that is the only file that needs to be there. (You can have 2 CA keys in the file or more if you need.)

$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/ca_ssh
cat ~/.ssh/ca_ssh.pub

Copy this file to the servers and add it to /etc/ssh/sshd_config:

TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pub

Granting Access

To sign Fred's public key (fred.pub) to grant one week access to the server as admin and log as staff in /var/log/secure, run this command and send the fred.pub-cert file back to Fred.

ssh-keygen -s ~/.ssh/ca_ssh -I staff -n admin -V +1w fred.pub

Revoking keys

Add public keys of people that should no longer login during their lease to playbook_dir/files/ssh/revoked_keys

0

Yes, not possible. And there is strong reasons for that. But if you want to achieve you can use tool which I developed on top of socat. It is almost full featured terminal access over pty and use x509. I do plan to extend it and make much more sophisticated.

https://github.com/aze2201/shell_sock

5
  • Could you please kindly elaborate how the software helps out/solves the problem of OP? Commented Dec 25, 2023 at 12:51
  • OP means OpenSSH ? This is using invoke /bin/bash ,pty parameter to remote socat, with forward to raw TCP. but connection esablishes with OpenSSL connection via x509.
    – aze2201
    Commented Dec 25, 2023 at 14:49
  • in nutshel.. client uses socat openssl connection with key, crt, ca-cert to server socat which listens openssl own key,crt and same ca-key. Once connection establishes client send port request to server and server redirect to local port in proxy via socat.
    – aze2201
    Commented Dec 25, 2023 at 18:36
  • admin can connect to proxy and listen nc over ssh in proxy. all connections are secure
    – aze2201
    Commented Dec 25, 2023 at 18:37
  • please edit your answer accordingly, thank you Commented Dec 26, 2023 at 9:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .