我正在为主机池使用 OpenSSH 证书。也就是说,在 中~/.ssh/known_hosts
有一个如下所示的条目:
@cert-authority service.redacted.com ssh-rsa ...
...并且service.redacted.com
是一个循环 DNS 条目,其中涉及的每个系统都有一个主机证书(参见HostCertificate
中的条目man sshd_config
),该证书被签名为对 有效service.redacted.com
。
当想要从池中连接到随机选择的系统时,这可以完美地工作 - 但是如果有人想要从池中连接到单个特定的系统,并使用给定的证书颁发机构验证其主机密钥是否合法,该怎么办?
我尝试过的一件事是:
service_name=service.redacted.com
specific_host=1.2.3.4
ssh -v -oHostKeyAlias="$service_name" "$specific_host"
...结果如下:
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
相当肯定是证书中列出的主体;1.2.3.4
不是。
答案1
从当前上游 OpenSSH-portable master 开始 (https://github.com/openssh/openssh-portable/commits/773dda25e828c4c9a52f7bdce6e1e5924157beab), 这不可能。
相关逻辑在于check_host_key() 函数,它只调用check_host_cert()
一次——最初传入的主机名ssh_login()
仅通过将所有字符标准化为小写进行修改。传递的相同主机名resolve_host()
以获取addrinfo *
用于实际连接的结构;resolve_host()
尊重一些选项(选择要使用的地址系列),但不提供覆盖机制。
也就是说,所需的更改很短(目前已提交给上游邮件列表并等待审核):
From 367fd8323d864daaf486047850f93c2167c66f37 Mon Sep 17 00:00:00 2001
From: Charles Duffy <[email protected]>
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