彻底搞懂SSH认证:主机认证与用户认证

admin 2026-01-17 01:16:45 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细解析了SSH认证的双重机制,即主机认证与用户认证。主机认证通过known_hosts文件验证服务器公钥指纹以防止中间人攻击,优先于用户认证发生;用户认证则通过密码或公钥确认访问权限。文章结合实验说明了known_hosts的生成与作用,并利用时序图清晰展示了完整的认证流程。 综合评分: 85 文章分类: 网络安全


cover_image

彻底搞懂SSH认证:主机认证与用户认证

0xNvyao 0xNvyao

安全随笔

2026年1月16日 18:01 上海

| | | — | | 声明:请勿利用本公众号文章内的相关技术、工具从事非法测试,如因此造成一切不良后果与文章作者及本公众号无关! |

大家对SSH密钥登录过程应该都很熟悉:

  • 在客户端通过ssh-keygen生成公私钥对
  • 将公钥上传到服务器的/root/.ssh/authorized_keys文件
  • 使用ssh [email protected] -i 私钥文件,完成登录

但今天我们要深入探讨另一个关键文件/root/.ssh/known_hosts,以及SSH认证中常被混淆的两个核心概念:主机认证与用户认证。

一、从实验现象说起

实验环境

  • 机器1:10.10.10.101(客户端)
  • 机器2:10.10.10.102(服务器)

实验步骤

第一步:检查known_hosts文件

[root@server01 ~]# cat /root/.ssh/known_hosts# 空文件,无内容

第二步:首次连接目标服务器

[root@server01 ~]# ssh [email protected] authenticity of host '10.10.10.102 (10.10.10.102)' can't be established.ED25519 key fingerprint is SHA256:n7D8Nq5sTv2+L5ghdhgDHv0fPIDvg/SW0Cd4s1qQzMpY.This key is not known by any other namesAre you sure you want to continue connecting (yes/no/[fingerprint])? yes

输入yes后,通过密码完成登录。

第三步:查看known_hosts变化

连接成功后,known_hosts文件增加了三条记录,都是关于10.10.10.102的:

10.10.10.102 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJK8pL+3t1dOq+fZXm2QWEZn21y/mzlWD/fLEH9qQrCC10.10.10.102 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDaXpV7T6Uk96UhACfTeKJc8tL9zYCisWizeit7VyoVPVg1pCaL+rstNFdJse9J0wYo7U2CJeV+Fj8cJSTpub0LuK+2a9TLHNQZ4JPmWl/9CHZIgOuYCVo8NobfaMIkMJYYv7HSiBEXJX6GG7ma5KwmcbUQ5p9xwczLMPlakXVsxwgl1ytdDE5VyzLD8hBFE2Ih9WX7t1kEw+ILg8KTJGU8hJbySB1jQNRONHt9yNyybBSXGdp5+LQ/R0nN8whDZ5v3t/NZdPB41mkPvO4C7p/WDescWRKEpWVnfRDAQy0wrdMnyYriTjfjywJuQ+j6j2cQfdtKpdfU6eZpO9gcGOH0DB1jW7eerZnTPJZJXV1EVTRfRnahISSNqZu1aeaMphxjYpxgK6asoM7WLIEUC99tKUKW7j2066PDw7OqZlzavwCbYf84AqahD8T2Tmav6Qb4D+43Va+4ee2jZ8Y8X4boIuqBxZJX2glC3RHtcUdTAainPt54n7uR24VjMHA86Y0=10.10.10.102 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJ8eRqGWaetbiqRLuJQK0BQ6e5Ge0Zq4mz1i3enVJecmHSGiA62XLeIQjb62bZ4nK+EDlUORd944AvtgH7Mh5k9=

二、known_hosts的核心作用

  1. 防止中间人攻击(MITM)

这是known_hosts最核心的安全功能:

  • 首次连接:SSH客户端会询问你是否信任该主机。输入yes后,服务器公钥存入known_hosts
  • 后续连接:SSH会自动比对服务器发来的公钥与known_hosts中记录的是否一致

安全逻辑:

  • 公钥一致 → 连接的是同一台服务器(安全)
  • 公钥不一致 → 服务器可能被替换,或存在中间人攻击(危险)
  1. 文件格式

每行记录包含三个部分:

[主机标识] [算法类型] [公钥字符串]

例如:

10.10.10.102 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJK8pL+3t1dOq+fZXm2QWEZn21y/mzlWD/fLEH9qQrCC

3、对比机器1的known_hosts和机器2的/etc/ssh/公钥内容

机器1的known_hosts:

AAAAB3NzaC1yc2EAAAADAQABAAABgQDaXpV7T6Uk96UhACfTeKJc8tL9zYCisWizeit7VyoVPVg1pCaL+rstNFdJse9J0wYo7U2CJeV+Fj8cJSTpub0LuK+2a9TLHNQZ4JPmWl/9CHZIgOuYCVo8NobfaMIkMJYYv7HSiBEXJX6GG7ma5KwmcbUQ5p9xwczLMPlakXVsxwgl1ytdDE5VyzLD8hBFE2Ih9WX7t1kEw+ILg8KTJGU8hJbySB1jQNRONHt9yNyybBSXGdp5+LQ/R0nN8whDZ5v3t/NZdPB41mkPvO4C7p/WDescWRKEpWVnfRDAQy0wrdMnyYriTjfjywJuQ+j6j2cQfdtKpdfU6eZpO9gcGOH0DB1jW7eerZnTPJZJXV1EVTRfRnahISSNqZu1aeaMphxjYpxgK6asoM7WLIEUC99tKUKW7j2066PDw7OqZlzavwCbYf84AqahD8T2Tmav6Qb4D+43Va+4ee2jZ8Y8X4boIuqBxZJX2glC3RHtcUdTAainPt54n7uR24VjMHA86Y0=

机器2的/etc/ssh/公钥内容(以rsa算法公钥为例):

AAAAB3NzaC1yc2EAAAADAQABAAABgQCyJIV7T6Uk96UhACfTeMJc8tL9zYCisWizeit7VyoVPVg1pCaL+rstNFdJse9J0wYo7U2CJeV+Fj8cJSTpub0LuK+2a9TLHNQZ4JPmWl/9CHZIgOuYCVo8NobfaMIkMJYYv7HSiBEXJX6GG7ma5KwmcbUQ5p9xwczLMPlakXVsxwgl1ytdDE5VyzLD8hBFE2Ih9WX7t1kEw+ILg8KTJGU8hJbySB1jQNRONHt9yNyybBSXGdp5+LQ/R0nN8whDZ5v3t/NZdPB41mkPvO4C7p/WDescWRKEpWVnfRDAQy0wrdMnyYriTjfjywJuQ+j6j2cQfdtKpdfU6eZpO9gcGOH0DB1jW7eerZnTPJZJXV1EVTRfRnahISSNqZu1aeaMphxjYpxgK6asoM7WLIEUC99tKUKW7j2066PDw7OqZlzavwCbYf84AqahD8T2Tmav6Qb4D+43Va+4ee2jZ8Y8X4boIuqBxZJX2glC3RHtcUdTAainPt54n7uR24VjMHA86Y0=

经对比完全一致,这就是机器1第一次ssh登陆机器2时,输入yes后,known_hosts内容写入的内容。

三、主机认证 vs. 用户认证关系

这两个独立的认证阶段是最容易混淆的概念!即使使用密码登录,SSH依然需要进行主机认证。

第一阶段:主机身份认证(Host Authentication)

  • 目的:确保你连接的服务器是真实的,而非假冒的
  • 对应文件:known_hosts
  • 发生时机:在任何用户认证之前
  • 逻辑:服务器发送它的”数字身份证”(公钥)给客户端验证

第二阶段:用户身份认证(User Authentication)

  • 目的:证明你有权限访问该服务器

  • 方式:

  • 密码认证

  • 密钥认证(使用authorized_keys)

这就是为什么即使使用密码登录,known_hosts依然会被更新的原因!

known_hosts存在三条记录的原因是服务器在/etc/ssh/目录下同时配置了三种主机密钥,上机器2(10.10.10.102)/etc/ssh/目录看一下:

root@server02:~# ll /etc/ssh/-rw-------   1 root root    513 Jan  5 01:11 ssh_host_ecdsa_key-rw-r--r--   1 root root    182 Jan  5 01:11 ssh_host_ecdsa_key.pub-rw-------   1 root root    411 Jan  5 01:11 ssh_host_ed25519_key-rw-r--r--   1 root root    102 Jan  5 01:11 ssh_host_ed25519_key.pub-rw-------   1 root root   2610 Jan  5 01:11 ssh_host_rsa_key-rw-r--r--   1 root root    574 Jan  5 01:11 ssh_host_rsa_key.pub

客户端在首次连接时,会获取并记录所有可用算法对应的公钥指纹,确保未来连接的最佳兼容性。

最后让大模型帮忙画了一个ssh认证过程的时序图,方便大家的理解:

附上完整的 Mermaid 代码:

sequenceDiagram    autonumber    participant C as 客户端 (10.10.10.101)    participant S as 服务端 (10.10.10.102)    Note over C, S: 第一阶段:主机验证与密钥交换    C->>S: TCP 连接请求 (端口 22)    S->>C: 版本协商与算法协商 (KEXINIT)    S->>C: 发送服务器公钥 (来自 /etc/ssh/ssh_host_*_key.pub)
&nbsp; &nbsp; Note&nbsp;left&nbsp;of&nbsp;C:&nbsp;1.&nbsp;检查&nbsp;~/.ssh/known_hosts<br>2.&nbsp;未找到该服务器记录&nbsp; &nbsp; C-->>User: 警告: "The authenticity of host...继续连接吗?"&nbsp; &nbsp;&nbsp;User-->>C: 输入 "yes"&nbsp; &nbsp; C->>C: 将服务器公钥指纹存入&nbsp;~/.ssh/known_hosts
&nbsp; &nbsp; Note&nbsp;over&nbsp;C, S: Diffie-Hellman 密钥交换<br>双方生成相同的【会话密钥】与【Session ID】
&nbsp; &nbsp; Note&nbsp;over&nbsp;C, S: 第二阶段:用户验证 (已在加密通道中进行)&nbsp; &nbsp; C->>S: SSH_MSG_USERAUTH_REQUEST (Service: ssh-userauth,&nbsp;User: test02)
&nbsp; &nbsp; alt 公钥认证 (优先尝试)&nbsp; &nbsp; &nbsp; &nbsp; C->>S: SSH_MSG_USERAUTH_REQUEST (类型: "publickey", 仅发送公钥指纹)&nbsp; &nbsp; &nbsp; &nbsp; Note&nbsp;right&nbsp;of&nbsp;S: 检查&nbsp;~/.ssh/authorized_keys 是否存在匹配公钥&nbsp; &nbsp; &nbsp; &nbsp; S->>C: SSH_MSG_USERAUTH_PK_OK (确认公钥可用,要求提供签名)
&nbsp; &nbsp; &nbsp; &nbsp; C->>C: 使用【私钥】对【Session ID&nbsp;+&nbsp;认证请求数据】进行签名&nbsp; &nbsp; &nbsp; &nbsp; C->>S: SSH_MSG_USERAUTH_REQUEST (包含完整公钥和数字签名)
&nbsp; &nbsp; &nbsp; &nbsp; Note&nbsp;right&nbsp;of&nbsp;S: 使用服务器端公钥验证签名有效性&nbsp; &nbsp; &nbsp; &nbsp; alt 验证成功&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; S->>C: SSH_MSG_USERAUTH_SUCCESS&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else&nbsp;验证失败&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; S->>C: SSH_MSG_USERAUTH_FAILURE (返回可用认证方式)&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;end
&nbsp; &nbsp;&nbsp;else&nbsp;密码认证 (若公钥不可用或验证失败)&nbsp; &nbsp; &nbsp; &nbsp; S->>C: SSH_MSG_USERAUTH_FAILURE (提示可使用 password 认证)&nbsp; &nbsp; &nbsp; &nbsp; C->>S: SSH_MSG_USERAUTH_REQUEST (类型: "password", 包含加密密码)&nbsp; &nbsp; &nbsp; &nbsp; Note&nbsp;right&nbsp;of&nbsp;S: 验证密码 (检查&nbsp;/etc/shadow 或 PAM)&nbsp; &nbsp; &nbsp; &nbsp; alt 密码正确&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; S->>C: SSH_MSG_USERAUTH_SUCCESS&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else&nbsp;密码错误&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; S->>C: SSH_MSG_USERAUTH_FAILURE&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;end&nbsp; &nbsp;&nbsp;end&nbsp; &nbsp; Note&nbsp;over&nbsp;C, S: 第三阶段:会话建立 (Channel)&nbsp; &nbsp; C->>S: SSH_MSG_CHANNEL_OPEN (session)&nbsp; &nbsp; S->>C: SSH_MSG_CHANNEL_OPEN_CONFIRMATION&nbsp; &nbsp; C->>S: SSH_MSG_CHANNEL_REQUEST (pty-req, 请求伪终端)&nbsp; &nbsp; S->>C: SSH_MSG_CHANNEL_SUCCESS&nbsp; &nbsp; C->>S: SSH_MSG_CHANNEL_REQUEST (shell, 开启 Shell)&nbsp; &nbsp; S->>C: SSH_MSG_CHANNEL_SUCCESS
&nbsp; &nbsp; S-->>C: 发送 Shell 欢迎语与提示符&nbsp; &nbsp; Note&nbsp;over&nbsp;C: 显示: test02@hostname:~$

四、结语

理解SSH的双重认证机制是保障服务器安全的基础。记住:

  • 主机认证确保你连接的是正确的服务器
  • 用户认证确保只有授权用户能访问
  • 两者缺一不可,且主机认证永远在前

下次看到known_hosts更新时,你会明白:这不是简单的”记录”,而是SSH在默默为你筑起第一道安全防线。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:安全随笔 0xNvyao 0xNvyao《彻底搞懂SSH认证:主机认证与用户认证》

评论:0   参与:  0