ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

SSH 密钥认证详解:原理、实操、参数、排错与加固(开发者版)

SSH 密钥认证详解:原理、实操、参数、排错与加固(开发者版)

SSH 密钥认证详解:原理、实操、参数、排错

Windows OpenSSH 客户端 + Linux 服务端完整实操案例(Windows10 1809+/Win11 自带 OpenSSH,不依赖 Xshell/PuTTY)

前言

SSH 是 Linux、服务器、容器、跳板机最常用远程协议。很多开发者只会简单ssh user@ip和密钥复制,但是对ssh-keygen参数、~/.ssh/config、ssh-agent、签名机制、sshd 细粒度配置、排错参数-v/-vv/-vvv、密钥轮换、证书、密钥隔离缺乏了解。

本文聚焦OpenSSH 原生体系,所有命令可直接复制到生产环境,兼顾原理、工程实践和踩坑点。

核心铁律:密钥对由客户端生成,公钥部署到服务端,私钥本地保管;私钥永远不上传服务器,网络中永不传输私钥。

一、两种认证模式对比

认证方式校验逻辑安全短板适用场景
PasswordAuthentication 密码认证客户端发送密码,服务端比对 shadow 哈希密码可被爆破、弱口令风险、公网暴露高危本地虚拟机临时调试,公网生产禁止开启
PubkeyAuthentication 公钥密钥认证挑战 + 签名机制,服务端用公钥验签私钥泄露则账号失守,依赖本地私钥安全跳板机、云服务器、CI/CD、自动化脚本、生产环境

补充:OpenSSH 还有 HostbasedAuthentication(基于主机认证,企业域环境,极少用)、Kerberos 认证,本文不展开。

二、非对称加密 & 密钥对基础

SSH 公钥认证使用签名,不是 “公钥加密消息”,这点非常容易混淆:

  • 私钥:用于签名;
  • 公钥:用于验签;
  • 数学特性:签名可公开验签,但是无法从公钥反推私钥。

支持算法(OpenSSH 8.0+)

  1. ed25519:首选,椭圆曲线,密钥短、速度快、安全强度高,推荐所有新密钥
  2. rsa:兼容性最好,老旧设备兼容;至少 4096 bit,不建议 2048
  3. ecdsa:不推荐,有实现争议

命令指定算法:-t ed25519/-t rsa

三、ssh-keygen 完整参数详解(重点)

基础生成:

ssh-keygen -t ed25519 -C "work-laptop@zhangsan"

完整常用参数合集:

# 生成 ed25519,指定备注、输出路径、强制覆盖、设置密钥密码 ssh-keygen -t ed25519 \ -C "dev-machine | dev@company.com" \ -f ~/.ssh/id_ed25519-work \ -N "MyPassphrase123" \ -q

参数说明:

  • -t:密钥类型ed25519/rsa
  • -C:comment 备注,仅文本标记,不参与校验,方便区分多套密钥
  • -f:输出文件路径,不写则默认~/.ssh/id_xxx
  • -N:非交互设置私钥密码(passphrase),脚本自动化生成密钥使用;交互式直接回车留空 = 私钥无密码(风险高)
  • -q:静默模式,不输出交互提示
  • -b:密钥长度,仅 RSA 需要:-b 4096
  • -o:使用新 OpenSSH 私钥格式(默认新版已开启,老版本需要加)
  • -a:KDF 迭代次数,增加暴力破解私钥难度,-a 100

⚠️ 区分两个密码:

  1. 服务器账号密码:密码登录用,存在/etc/shadow
  2. 私钥 passphrase:加密本地私钥文件;私钥本身是加密文件,拿到私钥文件没有这个密码依然无法签名。这是保护私钥的最后一道防线。

私钥密码管理命令

# 修改已有私钥的密码 ssh-keygen -p -f ~/.ssh/id_ed25519-work # 查看密钥指纹(用于核对公钥,防止中间人) ssh-keygen -lf ~/.ssh/id_ed25519-work.pub # 导出公钥(有时候.pub丢了,可以从私钥恢复公钥) ssh-keygen -y -f ~/.ssh/id_ed25519-work > ~/.ssh/id_ed25519-work.pub

四、Windows (OpenSSH 客户端) + Linux 服务器 完整实操案例

环境说明

  • 客户端:Windows 11 / Windows10 1809+,系统自带 OpenSSH 客户端,使用 PowerShell(推荐)或者 Windows Terminal

  • 服务端:CentOS7 / Rocky8 / Ubuntu(Linux),sshd 服务正常运行,IP:

    10.0.0.20

    登录用户:

    dev

    SSH 端口:

    22

    ⚠️ 先确认 Windows 已经安装 OpenSSH 客户端:

    设置 → 应用 → 可选功能 → 添加功能,搜索

    OpenSSH 客户端

    安装。

    验证(PowerShell):

    ssh -V

步骤 1:Windows 本地生成密钥对(PowerShell 执行)

Windows 下~对应目录:C:\Users\你的用户名\.ssh\

# 生成 ed25519 密钥,备注 windows-dev-pc ssh-keygen -t ed25519 -C "windows-dev-pc"

交互提示:

  1. Enter file in which to save the key (C:\Users\xxx\.ssh\id_ed25519): 回车默认
  2. Enter passphrase:推荐设置私钥密码(保护私钥,每次使用私钥需要输入;直接回车为空密码,方便自动化但是不安全)
  3. Enter same passphrase again:确认

生成文件:

C:\Users\你的用户名\.ssh\id_ed25519 # 私钥(保密!) C:\Users\你的用户名\.ssh\id_ed25519.pub # 公钥,上传Linux

指定自定义路径、非交互(脚本场景)

ssh-keygen -t ed25519 -C "windows-dev-pc" -f C:\Users\xxx\.ssh\id_ed25519-linux -N "Pass@1234" -q

步骤 2:把 Windows 公钥推送到 Linux 服务器

两种方案:优先方案 A(ssh-copy-id,新版 OpenSSH 支持)

方案 A:PowerShell 直接 ssh-copy-id(推荐)
# 默认端口22 ssh-copy-id dev@10.0.0.20 # 如果服务器修改了端口,例如2222 ssh-copy-id -p 2222 dev@10.0.0.20 # 指定私钥文件推送对应公钥 ssh-copy-id -i C:\Users\xxx\.ssh\id_ed25519-linux.pub dev@10.0.0.20

执行时输入一次 Linux 服务器 dev 账号密码,命令自动追加公钥、自动修复 Linux 端.ssh目录与 authorized_keys 权限。

方案 B:手动复制公钥(ssh-copy-id 不可用时,老旧 OpenSSH 版本)
  1. PowerShell 查看公钥内容,完整复制
cat C:\Users\xxx\.ssh\id_ed25519.pub
  1. 先用密码登录 Linux 服务器
ssh dev@10.0.0.20
  1. Linux 内执行,写入公钥
mkdir -p ~/.ssh # 【重点】>> 追加,不要用 > 覆盖原有公钥 echo "粘贴你复制的全部公钥字符串" >> ~/.ssh/authorized_keys # 权限加固(Linux sshd强制校验) chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chown -R dev:dev ~/.ssh

步骤 3:Windows PowerShell 使用密钥登录 Linu

# 默认私钥路径,端口22 ssh dev@10.0.0.20 # 自定义SSH端口 ssh -p 2222 dev@10.0.0.20 # 指定私钥文件(多密钥场景高频使用) ssh -i C:\Users\xxx\.ssh\id_ed25519-linux dev@10.0.0.20

步骤 4:Windows 配置~/.ssh/config 简化连接

新建 / 编辑文件:C:\Users\xxx\.ssh\config

注意:config 文件没有后缀名

Host linux-dev HostName 10.0.0.20 User dev Port 22 IdentityFile C:\Users\xxx\.ssh\id_ed25519-linux IdentitiesOnly yes

保存后,以后一行命令直接登录:

ssh linux-dev

参数说明:

  • IdentitiesOnly yes:只使用指定私钥,避免客户端尝试一堆密钥导致服务器拒绝(Too many authentication failures)

步骤 5:Windows ssh-agent 托管私钥(不用反复输入 passphrase)

PowerShell(管理员权限)

# 启动ssh-agent服务 Start-Service ssh-agent # 设置开机自动启动 Set-Service -Name ssh-agent -StartupType Automatic # 添加私钥到代理 ssh-add C:\Users\xxx\.ssh\id_ed25519-linux

添加之后,本次会话不用重复输入私钥密码。

Windows 专属坑点

  1. Windows 私钥文件权限:Windows NT 权限宽松,OpenSSH 会告警。右键私钥文件 → 属性 → 安全,删除其他用户,只保留当前用户拥有读取权限;
  2. 不要用记事本编辑 config,容易引入 BOM、换行符问题,推荐 VS Code;
  3. PuTTY 是另外一套体系:需要把 OpenSSH 私钥转成 ppk,本文优先原生 OpenSSH,不推荐混合使用。

五、部署公钥到服务端:ssh-copy-id 与手动方案(Linux 客户端版本)

# 默认端口 ssh-copy-id -i ~/.ssh/id_ed25519-work user@10.0.0.10 # 自定义端口 ssh-copy-id -p 2222 -i ~/.ssh/id_ed25519-work user@10.0.0.10 # 只输出,不写入(调试看将要推送的公钥内容) ssh-copy-id -n -i ~/.ssh/id_ed25519-work user@10.0.0.10

参数:

  • -i:指定要推送的公钥文件
  • -p:ssh 端口
  • -n:dry-run 试运行

手动写入 authorized_keys(跳板机、无 ssh-copy-id 环境)

# 本地查看公钥 cat ~/.ssh/id_ed25519-work.pub # 服务端执行 mkdir -p ~/.ssh # 追加公钥,不要覆盖! echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIxxx comment" >> ~/.ssh/authorized_keys

✅服务端权限硬性要求(sshd 内置校验,权限宽松直接拒绝)

chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys # 属主必须是登录用户,不能是root或其他账号 chown -R user:user ~/.ssh

常见坑:windows 复制粘贴公钥带入换行、空格;authorized_keys一行一条公钥。

六、ssh 连接命令参数大全

# 指定私钥、端口、用户 ssh -i ~/.ssh/id_ed25519-work -p 2222 dev@10.0.0.10 # 调试模式,逐级增加日志 ssh -v dev@10.0.0.10 # 简要调试 ssh -vv dev@10.0.0.10 # 中等日志,日常排错首选 ssh -vvv dev@10.0.0.10 # 完整底层交互日志,定位握手、算法协商问题 # 端口转发(本地端口转发,开发经常用到) ssh -L 8080:127.0.0.1:8080 dev@10.0.0.20 # 远程端口转发 ssh -R 9000:127.0.0.1:9000 dev@10.0.0.20 # 静默执行远程命令(CI脚本) ssh dev@10.0.0.20 "df -h && free -h"

七、sshd 服务端配置(Linux /etc/ssh/sshd_config)生产加固

# 启用公钥认证(必须开启) PubkeyAuthentication yes # 公钥文件路径,默认 AuthorizedKeysFile .ssh/authorized_keys # 关闭密码认证,密钥调试成功之后再打开! PasswordAuthentication no # 禁止空密码账号登录 PermitEmptyPasswords no # 限制最大尝试次数,防探测 MaxAuthTries 3 # 禁用老旧不安全算法 KexAlgorithms curve25519-sha256@libssh.org

修改后重启 sshd

# RHEL / CentOS / Rocky systemctl restart sshd # Ubuntu / Debian systemctl restart ssh # 查看状态 systemctl status sshd

八、排错清单(高频)

  1. Permissions 0644 for 'id_ed25519' are too open:私钥权限太松,Windows 收紧安全权限,Linux 执行chmod 400 私钥文件
  2. 密钥不生效,一直弹出密码输入:检查authorized_keys权限、公钥是否换行空格、sshd_configPubkeyAuthentication yes
  3. Too many authentication failures:客户端自动尝试一堆密钥,配置IdentitiesOnly yes
  4. 指纹校验:首次连接提示 host key,是主机指纹校验(中间人防护,和用户密钥不是一回事)

九、ssh-agent 补充说明

ssh-agent 是密钥代理进程,把解密后的私钥放在内存,避免反复输入 passphrase。

  • Windows:系统自带 ssh-agent 服务
  • Linux:eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519
  • Mac:ssh-add --apple-use-keychain存入钥匙串

十、全文总结

  1. 规范流程:客户端(Windows/Linux)生成密钥对,公钥下发 Linux 服务器,私钥本地保管
  2. 优先 ed25519,RSA 仅兼容老旧环境,长度≥4096
  3. Windows 原生 OpenSSH 无需 Xshell/PuTTY,PowerShell 原生全套命令,支持 config、ssh-agent、ssh-copy-id
  4. 权限是密钥登录失败第一诱因:Linux.ssh 700、authorized_keys 600;Windows 收紧私钥 NTFS 权限
  5. 公网服务器务必关闭 PasswordAuthentication,只保留公钥认证
  6. 私钥设置 passphrase + ssh-agent 托管,兼顾安全和开发效率
返回列表