1

I'm using OpenSSH certificates for a pool of hosts. That is to say, in ~/.ssh/known_hosts, there's an entry that looks thus:

@cert-authority service.redacted.com ssh-rsa ...

...and service.redacted.com is a round-robin DNS entry for which each system involved has a host certificate (see the HostCertificate entry in man sshd_config) signed as valid for service.redacted.com.

This works perfectly when wanting to connect to a randomly-selected system from the pool -- but what if someone wants to connect to a single, specific system from the pool, validating its host key as legitimate using the certificate authority given?


One thing I tried was thus:

service_name=service.redacted.com
specific_host=1.2.3.4
ssh -v -oHostKeyAlias="$service_name" "$specific_host"

...which results in the following:

debug1: Host 'service.redacted.com' is known and matches the RSA-CERT host certificate
Certificate invalid: name is not a listed principal
The authenticity of host 'service.redacted.com (1.2.3.4)' can't be established.

service.redacted.com quite certainly is a listed principal in the certificate; 1.2.3.4 is not.

1 Answer 1

2

As of current upstream OpenSSH-portable master (https://github.com/openssh/openssh-portable/commits/773dda25e828c4c9a52f7bdce6e1e5924157beab), this is not possible.

The relevant logic is in the check_host_key() function, which calls check_host_cert() only once -- with the hostname which was originally passed into ssh_login() modified only by normalizing all characters to lowercase. That same hostname in passed through resolve_host() to get the addrinfo * struct used for the actual connection; resolve_host() respects a few options (selecting the address family to use), but otherwise does not provide an override mechanism.


That said, the change needed is a short one (presently submitted to the upstream mailing list and pending review):

From 367fd8323d864daaf486047850f93c2167c66f37 Mon Sep 17 00:00:00 2001
From: Charles Duffy <charles@threatgrid.com>
Date: Tue, 17 Feb 2015 09:49:32 -0600
Subject: [PATCH] Allow HostKeyAlias to match a host certificate principal if
 HostName does not

---
 sshconnect.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sshconnect.c b/sshconnect.c
index df921be..666c3ff 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -902,7 +902,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
                debug("Found %s in %s:%lu", want_cert ? "CA key" : "key",
                    host_found->file, host_found->line);
                if (want_cert && !check_host_cert(hostname, host_key))
-                       goto fail;
+                       if (options.host_key_alias == NULL || !check_host_cert(options.host_key_alias, host_key))
+                               goto fail;
                if (options.check_host_ip && ip_status == HOST_NEW) {
                        if (readonly || want_cert)
                                logit("%s host key for IP address "
--
2.0.0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.