How to verify that ssh certificate was signed by specified ssh CA private key?

11,721

Solution 1

To remotely obtain ssh host certificate(s), you can use ssh-keyscan -c <hostname> (without the -c option, you will only get the host key(s)). To limit to a specific certificate type, you can include -t type, using ssh-rsa not [email protected], if necessary.

Then, you can extract the certificate details, including the Signing CA's public key, with ssh-keygen -L -f <certfile>. If you use (lowercase) -l instead, then ssh-keygen only outputs the information about the underlying (public) host key embedded in the certificate, rather than all of the certificate elements.

Solution 2

I have not gone so far as setup a signed for my internal ssh. But when I was doing that for imap I learned a simple way to check things.

See https://www.feistyduck.com/library/openssl-cookbook/online/ch-testing-with-openssl.html for details.

Basically, using "openssl s_client ..." you can get a lot us useful data.

e.g., my unsigned (CA unsigned) ssh (note - No client CA names sent, and compare to the "self-signed" report obtained from my imaps test)

openssl s_client -connect x072:22
CONNECTED(00000003)
804401144:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:825:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 305 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1526335517
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

Whereas when connecting to my imaps services - I see a (depth:0 self-signed) certificate chain.

root@x071:[/root]openssl s_client -connect x063:993
CONNECTED(00000003)
depth=0 C = NL, ST = N. Holland, L = Amsterdam, O = ROOTVG, OU = aixtools
verify error:num=18:self signed certificate
verify return:1
depth=0 C = NL, ST = N. Holland, L = Amsterdam, O = ROOTVG, OU = aixtools
verify error:num=26:unsupported certificate purpose
verify return:1
depth=0 C = NL, ST = N. Holland, L = Amsterdam, O = ROOTVG, OU = aixtools
verify return:1
---
Certificate chain
 0 s:/C=NL/ST=N. Holland/L=Amsterdam/O=ROOTVG/OU=aixtools
   i:/C=NL/ST=N. Holland/L=Amsterdam/O=ROOTVG/OU=aixtools
---
Server certificate
-----BEGIN CERTIFICATE-----
snip...

These differ from using ssh-keygen, which I must research more myself. But I think I shall stay with openssl s_client due to it's divisity.

Share:
11,721

Related videos on Youtube

Drew
Author by

Drew

Updated on September 18, 2022

Comments

  • Drew
    Drew over 1 year

    I am trying to harden my ssh setup using this material. It works fine, but I've got a question which I'm struggling to find the answer to.

    Does anyone know if there is a way to check the ssh host/user certificate signature against the SSH CA? I know that I can just try to ssh into host, that hold that host certificate, and if it connects than the signature is obviously ok... But I am writing an automation task and I need a programmatic way to make sure that the certificate file is signed by CA. Say some ssh-keygen command or anything else.

    UPDATE:

    As @PKapp proposed:

    I could compare two outputs: the Fingerprint of Signing CA from Server side certificate and the Fingerprint of the CA itself

    sudo ssh-keygen -L -f /etc/ssh/ssh_host_ed25519_key-cert.pub | fgrep "Signing CA" | sed 's/^[ \t]*//' | cut -d ' ' -f 4
    SHA256:LkdPQLdx4tuZp7pG0g6nAJqilFd6ZzjGdgVEV9elrdA
    
    sudo ssh-keygen -l -f /etc/ssh/id_ed25519-HostCA.pub | cut -d ' ' -f 2
    SHA256:LkdPQLdx4tuZp7pG0g6nAJqilFd6ZzjGdgVEV9elrdA
    

    If the filtered outputs are identical, then the certificates match...

  • Drew
    Drew almost 6 years
    Thank you. I will post the elaborate answer based on your suggestion. Wait till anyone suggest another solution. If there is no better option, I will mark your answer as a correct one.
  • Drew
    Drew almost 6 years
    One question, can I get remotely the host certificate's "Signing CA" fingerprint? Seems like ssh-keyscan -c <hostname> doesn't provide this info (only the cert content itself)
  • PKapp
    PKapp almost 6 years
    The remote server typically does not have the need to keep or use the Signing CA public key. It is the client side responsibility to obtain the Signing CA public key from a trusted source other than the server it is going to verify, and presumably add a known_hosts entry using @cert-authority to assert trust of the Signing CA, rather than trust of a single host key. So, ssh-keyscan does aid in getting the certificate from the remote host, but the content to compare to the "known" trusted Signing CA should already be present on the client side.
  • Nabheet
    Nabheet about 5 years
    Looks like the question was about signed SSH keys and not SSL. The philosophy is the same but different libraries. When you sign SSH keys, you can set up a trust chain so that you don't get prompted to add the server key to your known_hosts file while connecting over SSH.