找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2433

积分

0

好友

341

主题
发表于 11 小时前 | 查看: 0| 回复: 0

一、开场白:集群很乖,也有脾气

实验室里新装了两台 Proxmox VE(后面简称 PVE),取名 proxmox-a (192.168.2.7) 和 proxmox-b (192.168.2.8)。

把它们肩并肩加入同一个集群后,本以为可以左手右手一个慢动作——在任何一台的 8006 Web 面板里都能随意启停对方的容器。结果现实给我上了一课:

  • 在 B 的 8006 里点 A 的容器 → 秒开秒关,乖巧听话。
  • 在 A 的 8006 里点 B 的容器 → “嘭”弹红框,死活不给面子。

于是,一条诡异的“管理单行道”横空出世。

二、事故现场高清回放

1. Web 端症状

打开浏览器 F12 开发者工具抓取网络请求,能看到失败的 API 调用:

POST https://192.168.2.7:8006/api2/json/nodes/proxmox-b/lxc/101/status/start

服务器返回了 500 内部服务器错误,而响应的正文里嵌着熟悉的 SSH 报错字样。

2. 后台日志佐证

在 A 节点上查阅 /var/log/syslog,找到了关键线索:

pvedaemon[1234]: problem connecting to 'proxmox-b' - ssh: handshake failure

这说明 PVE 的后台守护进程 (pvedaemon 或其代理) 试图通过 SSH 连接到节点 B,但握手过程直接失败了。

3. 控制台手动复现

为了进一步确认,切换到 A 节点的命令行,手动执行 SSH 连接:

ssh root@192.168.2.8

屏幕瞬间被醒目的“大横幅”警告占满:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
SHA256:P4UMJmTShfmaJoxDCraoHRwIngNtjA5JIlL/hnsmr1Y.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending RSA key in /etc/ssh/ssh_known_hosts:12
  remove with:
  ssh-keygen -f “/etc/ssh/ssh_known_hosts” -R “192.168.2.7”
Host key for 192.168.2.7 has changed and you have requested strict checking.
Host key verification failed.

翻译成更直白的话就是:“对方(节点B)出示的 SSH 主机密钥指纹,和我(节点A)本地记录里保存的对不上号。出于安全考虑(担心是中间人攻击),我拒绝连接!”

三、架构速览:8006 面板背后的“暗线”通信

理解故障原因,需要先明白 PVE Web 管理面板 (https://IP:8006) 操作远程节点的底层逻辑。它并非浏览器直接与目标节点对话,而是遵循以下链条:

  1. 你的浏览器 → 向当前登录的节点(例如节点A)的 8006 端口发送请求。
  2. 节点A上的 pve-proxy 服务接收到请求 → 通过 SSH 协议连接到目标节点(例如节点B)的 22 端口。
  3. 节点B的 sshd (SSH服务) 将接收到的指令转交给本地的 pvedaemon 守护进程。
  4. 节点B的 pvedaemon 最终执行具体的虚拟机/容器启停、迁移等操作。

因此,SSH 连接一旦在第二步握手失败,整条管理链路就中断了,Web 前端自然只能收到一个笼统的 500 错误。

四、根因定位:谁的“身份证”被换了?

经过梳理,问题根源水落石出:

  1. 密钥变更:之前我曾对 proxmox-a 进行过系统重装。重装后,我执行了 dpkg-reconfigure openssh-server,这导致节点A的整套 SSH 主机密钥(RSA/ECDSA/ED25519)被重新生成。
  2. 记录未更新:集群中的其他节点(本例中的节点B)的系统级 SSH 已知主机文件 /etc/ssh/ssh_known_hosts 里,仍然记录着节点A旧的密钥指纹。
  3. 严格的安全策略:SSH 客户端默认启用 StrictHostKeyChecking=yes。当它发现对方提供的密钥指纹与本地记录不符时,会出于安全考虑直接拒绝连接。
  4. 单向故障现象:这就导致了有趣的“单向通车”现象:
    • B 访问 A:B 的 known_hosts 里存的是 A 的新指纹(因为重装后B可能重新连接过A并更新了记录),所以连接成功。
    • A 访问 B:A 的 known_hosts 里存的还是 B 的指纹,但实际上B的密钥并未改变。此时A作为客户端去连接B,B出示了正确的(未变的)密钥,但A用旧的记录去核对,对不上,于是握手失败。

五、修复全流程(手把手版)

修复需要在“拒绝连接”的节点上进行,本例中就是在节点A上操作。

步骤 1:确认冲突记录的行号

错误信息已经明确给出了线索:

Offending RSA key in /etc/ssh/ssh_known_hosts:12

这表明在 /etc/ssh/ssh_known_hosts 文件的第 12 行,存在一条与目标主机(192.168.2.8)相关的无效 RSA 密钥记录。

步骤 2:一键删除过时的指纹记录

使用 ssh-keygen 命令清理旧记录。-R 参数会自动移除文件中所有关联到指定主机(IP或主机名)的密钥条目,涵盖各种算法,非常省心。

ssh-keygen -f /etc/ssh/ssh_known_hosts -R 192.168.2.8

步骤 3:重新建立连接并信任新指纹

现在,让节点A重新连接节点B,并在首次连接时自动接受并保存正确的主机密钥。使用 -o StrictHostKeyChecking=accept-new 选项可以安全地实现这一点。

ssh -o StrictHostKeyChecking=accept-new root@192.168.2.8 “echo SSH host key updated”

看到终端输出 “SSH host key updated” 字样,即表示新的主机密钥指纹已成功写入节点A的 known_hosts 文件。

步骤 4:最终验证

回到节点A的 8006 Web 管理界面。

  1. 进入“数据中心”视图下的集群概览。
  2. 点击节点 proxmox-b
  3. 找到之前无法操作的容器(例如ID 101),点击“启动”。

此时,操作应该能够成功执行,容器顺利启动。同时,检查 /var/log/syslog,之前频繁出现的 ssh: handshake failure 错误日志也会消失。集群管理自此恢复“双向通车”。

六、可选加固与批量处理场景

1. 关闭严格主机密钥检查(不推荐用于生产环境)

在测试或频繁重建节点的环境中,可以临时放宽检查。在 /etc/ssh/ssh_config 中为特定网段添加配置:

Host 192.168.2.*
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

警告:这将完全禁用对该IP段的主机密钥验证,会丧失对中间人攻击的检测能力,仅适用于可信任的封闭测试环境。

2. 提前备份与恢复主机密钥(推荐做法)

在进行系统重装或迁移前,这是一个一劳永逸的优雅方案。

  • 备份:重装前,将源节点的 /etc/ssh/ssh_host_* 密钥文件(通常包括 ssh_host_ecdsa_keyssh_host_ed25519_keyssh_host_rsa_key 等)打包备份。
  • 恢复:新系统安装完成后,将备份的密钥文件原样放回 /etc/ssh/ 目录。
  • 生效:执行 systemctl restart sshd 重启 SSH 服务。这样,集群中其他节点保存的该主机指纹将始终保持有效,完全无感知。

3. 使用自动化工具进行批量管理

如果你的集群节点数量众多,使用 Ansible 等自动化工具来批量更新密钥记录是高效的选择。以下是一个示例 playbook 片段:

- name: remove stale host key
  known_hosts:
    name: “{{ item }}”
    state: absent
  loop: “{{ groups[‘pve’] }}”

- name: scan and add new key
  shell: ssh-keyscan -H {{ item }} >> /etc/ssh/ssh_known_hosts
  loop: “{{ groups[‘pve’] }}”

这个 playbook 会先移除所有已知集群节点旧的记录,然后通过 ssh-keyscan 重新获取并添加所有节点当前正确的主机密钥。

七、小结

总结一下核心要点:PVE 集群的跨节点 Web 管理,底层完全依赖于 SSH 通信。一旦节点间记录的 SSH 主机密钥指纹不匹配,就会导致 Web 面板出现“集群已连接,但操作单向不通”的诡异状况。

解决之道就是“删除旧指纹,获取新指纹”这两步。对于因主机密钥变更引发的问题,通常几分钟内就能让集群恢复双向正常管理。

希望这篇从故障现象到根因分析,再到解决方案的完整记录,能帮助你快速定位并解决类似问题。欢迎在云栈社区分享你的运维经验和遇到的挑战,祝各位的 Proxmox VE 之旅一路绿灯!




上一篇:从技术产品到链上项目:如何判断一件事的“重要性”?
下一篇:SQL基础查询入门:21个常用查询语法与场景实例详解
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-26 16:10 , Processed in 0.252703 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表