OFFSET偏移
← 文章目录OFFSET / FIELD NOTESNO. 045

SSH 认证体系:目录、密钥与 TOFU

区分用户身份、服务器身份及首次信任的边界。

所在专题SSH 认证、agent 与命令行工作流 ↗
约 7 分钟阅读开始阅读

目录:SSH 是两套独立系统#

OpenSSH 同时扮演客户端(ssh)和服务器(sshd),同一套软件中的不同程序读取各自配置:

方向 程序 目录 归属
出站(你连别人) ssh 客户端 ~/.ssh/ + /etc/ssh/ssh_config 你(用户级)
入站(别人连你) sshd 服务器 /etc/ssh/ + 每用户 authorized_keys 系统 + 用户
SSH 出站(你是客户端):
  你 ──ssh──▶ GitHub
    ~/.ssh/          ← 你的通行证、偏好、信任名单

SSH 入站(你是服务器):
  Windows ──ssh──▶ 你
    /etc/ssh/        ← 服务器运行配置 + 系统户口本
    ~/.ssh/authorized_keys  ← 你放行的客人名单

四类认证材料各管一块#

在常见的公钥认证连接中,可以区分四类材料;authorized_keys 与 known_hosts 是列表文件,并非各自一把密钥:

Key 位置 回答的问题 谁验证谁
id_ed25519(你的私钥) ~/.ssh/ 你是谁 对端验证你
authorized_keys(别人的公钥) ~/.ssh/ 谁被授权进来 你验证对端
host key(系统私钥 + .pub) /etc/ssh/ 我是哪台机器 对端验证你
known_hosts(对端主机公钥或 CA 等信任记录) ~/.ssh/ 我信任哪些服务器 你验证对端

authorized_keys 的例外归属 authorized_keys 在 ~/.ssh/ 里,但它是入站用的——它是「服务器允许谁进来」的名单,按用户存放。本质是 sshd 读的配置,只是放在各用户家目录方便自管。

公钥不会自动登记 客户端验证服务端 host key;使用公钥认证时,服务端验证用户私钥的签名。管理员需预先把用户公钥加入目标账户的 authorized_keys(或使用证书/其他授权机制);连接不会自动把来访用户公钥加入授权名单。客户端接受或预置信任后才记录服务器公钥。用户也可通过密码等方式认证,不是每种连接都使用用户公钥。

双向认证:为什么需要 host key#

SSH 连接不只是验证「你是谁」,而是双向验证:

desktop ──────SSH 连接──────▶ 你的机器

方向1(验证对端身份):
  对端出示自己的私钥签名
  你的机器用 ~/.ssh/authorized_keys 里的公钥验证

方向2(验证你的机器 = host key 的活):
  你的机器出示 host key 私钥签名
  对端用 known_hosts 中已信任的主机公钥验证

host key 干的是方向 2——它是你的机器反向证明「我是我」的身份证。 这也是上面那个 A/B 机器例子说的「双方互相确认对方身份」。

为什么需要反向验证(防中间人):

desktop ──▶ [攻击者假装是你] ──▶ 真的你
                ↑
            desktop 以为连的是你,其实连的是骗子

攻击者先连到你,再伪装成你接受 desktop 的连接。desktop 输入的凭据交给了攻击者。host key 防的就是这个:desktop 第一次连接时记下你的指纹,之后每次校验「指纹还对不对」。

TOFU 模型的本质与局限#

TOFU(Trust On First Use,首次使用即信任):

  • 第一次连接:核对并接受对端 host key,把主机公钥记录到 known_hosts
  • 之后每次:校验「还是不是那个指纹」

它解决什么(连续性):

场景A(TOFU 能防):你在 A 网吧连真 GitHub,记下真指纹;
  之后在 B 网吧,攻击者冒充 GitHub → 指纹对不上 → 警觉 ✓

它解决不了什么(首次真实性):

场景B(TOFU 防不了):你第一次就连上假 GitHub → 记下假指纹 → 永远被骗 ✗

TOFU 的盲区 TOFU 只能保证「之后连的还是不是第一次连的那个」,不能保证「第一次连的那个是不是真的」。如果第一次就连上骗子,指纹验证等于摆设。

首次信任怎么补强:带外验证#

  • 查官方公布的指纹:GitHub、云厂商官网公开自己的 host key 指纹,连接后 ssh-keygen -lf 对比
  • SSH 证书(SSH CA):大公司给每台服务器签发证书,客户端预置 CA 公钥,首次连接也可验证
  • 私有网络/直连:可减少暴露面,但同一局域网也不能单独证明身份;最好仍从服务器控制台或可信渠道取得指纹核对

TOFU 适合能够接受首次信任风险的场景;公开指纹、可信控制台或预置信任材料可加强首次验证。不要为消除提示全局关闭 host key 校验。

GitHub 的 git 入口与账户识别#

连 GitHub 时 User git 是统一入口名,不代表你的 GitHub 账户名。GitHub 靠公钥识别账号,不看用户名。多账号靠「同一个 git + 不同 IdentityFile」区分:

Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_work    # 工作账号的 key

通用目录示例#

~/.ssh/
  ├── id_ed25519          # 用户私钥,应设置 passphrase
  ├── id_ed25519.pub      # 用户公钥,注释可写 user@workstation
  ├── authorized_keys    # 允许登录此账户的用户公钥
  ├── known_hosts        # 已信任的服务器主机公钥
  └── config             # 用户客户端配置

/etc/ssh/
  ├── ssh_config         # 系统级客户端配置
  ├── sshd_config        # 服务器配置
  └── ssh_host_ed25519_key # 服务器主机私钥

关键洞察#

目录归属的本质是「谁拥有这份配置」——/etc/ssh/ 是系统所有(机器身份,root 管),~/.ssh/ 是用户所有(你的身份,你管)。authorized_keys 卡在中间:既是服务器的授权逻辑,又按用户的客人名单分,所以它在 ~/.ssh/ 但归入站用。

相关#


参考与延伸

  1. OpenSSH ssh 手册 ↗
  2. OpenSSH ssh_config 手册 ↗
  3. OpenSSH ssh-keygen 手册 ↗

根据技术笔记重新整理,示例使用通用名称。

沿专题继续阅读

SSH 认证、agent 与命令行工作流

  1. 01SSH 认证体系:目录、密钥与 TOFU
  2. 02ssh-agent、passphrase 与 keyring
  3. 03SSH 使用指南:命令行操作
CONTINUE READING / 下一篇ssh-agent、passphrase 与 keyring

理解私钥文件保护、agent 签名接口与桌面密码保管箱的分工。