fix(chv): known_hosts 22 端口写裸 host 行,修 provisioned 钉死失效
OpenSSH 默认端口只查裸 host 名、非默认端口只查 '[host]:port':known_hosts_line 对 22 端口也写 '[192.168.10.10]:22',ssh 永远匹配不上,报 Host key verification failed、wake fail-closed 关 VM。keyscan TOFU 输出裸行,lite9 没暴露。非 22 端口仍用括号形式。
This commit is contained in:
1 parent
4f3a176771
commit
ba5df980bf
2 files changed
+25
-4
No files matched your search
+14
-4
@@ -74,13 +74,23 @@ def delete_host_private_key(state_dir: str, vm_name: str) -> str:
|
|||||||
def known_hosts_line(port: int, public_key_text: str, host: str = "127.0.0.1") -> str:
|
def known_hosts_line(port: int, public_key_text: str, host: str = "127.0.0.1") -> str:
|
||||||
"""公钥文件内容转 known_hosts 行:只取前两列(类型+数据)。
|
"""公钥文件内容转 known_hosts 行:只取前两列(类型+数据)。
|
||||||
|
|
||||||
公钥文件形如 'ssh-ed25519 AAAA... [comment]',known_hosts
|
公钥文件形如 'ssh-ed25519 AAAA... [comment]'。22 端口
|
||||||
行形如 '[<host>]:<port> ssh-ed25519 AAAA...'(host 缺省
|
(OpenSSH 默认端口)时行形如 '<host> ssh-ed25519
|
||||||
回环,仅作兼容;客机 IP 方案下 host 应为解析出的客机 IP)。
|
AAAA...'(裸 host 名);非 22 端口时才用
|
||||||
非法内容 ValueError,绝不把陌生行原样写进文件。"""
|
'[<host>]:<port> ssh-ed25519 AAAA...'。OpenSSH 查
|
||||||
|
known_hosts 时,默认端口只查裸 host 名、非默认端口
|
||||||
|
只查括号形式,写错即永远匹配不上(2026-11-07 WSL
|
||||||
|
真机实测:provisioned 模式钉死 key 写成
|
||||||
|
'[192.168.10.10]:22',22 端口 ssh 报 Host key
|
||||||
|
verification failed;keyscan TOFU 输出裸行所以
|
||||||
|
lite9 没暴露)。host 缺省回环,仅作兼容;客机 IP
|
||||||
|
方案下 host 应为解析出的客机 IP。非法内容
|
||||||
|
ValueError,绝不把陌生行原样写进文件。"""
|
||||||
parts = (public_key_text or "").strip().split()
|
parts = (public_key_text or "").strip().split()
|
||||||
if len(parts) < 2 or not parts[0].startswith("ssh-"):
|
if len(parts) < 2 or not parts[0].startswith("ssh-"):
|
||||||
raise ValueError("host 公钥格式非法")
|
raise ValueError("host 公钥格式非法")
|
||||||
|
if int(port) == 22:
|
||||||
|
return "%s %s %s" % (host, parts[0], parts[1])
|
||||||
return "[%s]:%s %s %s" % (host, port, parts[0], parts[1])
|
return "[%s]:%s %s %s" % (host, port, parts[0], parts[1])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -318,6 +318,17 @@ class HostKeyProvisionTest(ChvGapCase):
|
|||||||
self.assertFalse(os.path.exists(r["paths"]["private"]))
|
self.assertFalse(os.path.exists(r["paths"]["private"]))
|
||||||
self.assertTrue(os.path.exists(r["known_hosts"]))
|
self.assertTrue(os.path.exists(r["known_hosts"]))
|
||||||
|
|
||||||
|
def test_known_hosts_line_port_22_is_bare(self):
|
||||||
|
# 22 端口写裸 host 行:OpenSSH 默认端口只查裸名,
|
||||||
|
# '[host]:22' 永远匹配不上(2026-11-07 WSL 真机)。
|
||||||
|
self.assertEqual(
|
||||||
|
known_hosts_line(22, "ssh-ed25519 AAAAx comment",
|
||||||
|
host="192.168.10.10"),
|
||||||
|
"192.168.10.10 ssh-ed25519 AAAAx")
|
||||||
|
self.assertEqual(
|
||||||
|
known_hosts_line(2222, "ssh-ed25519 AAAAx comment"),
|
||||||
|
"[127.0.0.1]:2222 ssh-ed25519 AAAAx")
|
||||||
|
|
||||||
def test_known_hosts_line_rejects_bad_key(self):
|
def test_known_hosts_line_rejects_bad_key(self):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
known_hosts_line(2222, "not-a-key")
|
known_hosts_line(2222, "not-a-key")
|
||||||
|
|||||||
Reference in new issue
Block a user