密钥登录到底解决了什么
口令登录有两个硬伤:可被暴力尝试与每次都要输入。密钥登录用非对称密钥证明身份——私钥留在本地,公钥放到服务器。只要私钥不泄露,攻击者无法凭口令猜测进入。
生成与部署
# 推荐 ed25519:短、快、安全性好
ssh-keygen -t ed25519 -C "you@example.com"
# 把公钥复制到服务器(或手动追加到 ~/.ssh/authorized_keys)
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@host
# 私钥设了口令时,用 agent 缓存,避免反复输入
eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519
~/.ssh/config 让多主机变得好管
Host prod
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 30
Host *.internal
User ops
ProxyJump bastion
IdentityFile ~/.ssh/id_ed25519
写好之后,ssh prod 一行即可登录;* 与 ProxyJump 还能批量表达对内网主机经由跳板机访问。
服务器端该做的加固
- 关闭口令登录(确认密钥可用之后):
PasswordAuthentication no; - 禁止 root 直接登录:
PermitRootLogin no; - 改用非默认端口并不能替代密钥,只能减少噪音日志;
- 用
AllowUsers限定可登录账号。
四个常见坑
- 私钥权限过宽:必须是 600,SSH 会直接拒绝;
- known_hosts 冲突:主机重装或 IP 复用后指纹变化,应核对指纹后再删除旧记录,不要无脑清理;
- agent 转发滥用:
ForwardAgent会让跳板机上的 root 借你的密钥横向移动,非必要不开; - 一份私钥到处用:应按用途分开密钥对,丢失时影响范围更小。
常见问题
为什么要给私钥设口令?设备丢失时多一道防线,配合 agent 并不影响日常使用。密钥也能被暴力破解吗?ed25519 与足够长的 RSA 在当前算力下不可行,风险主要来自私钥泄露本身。连接经常断开怎么办?配置 ServerAliveInterval,并让服务端有合理的 ClientAliveInterval。
密钥选择与生成
新密钥一律用 Ed25519;若必须兼容老旧设备再退回 RSA 4096。生成时加上注释便于日后清理:
ssh-keygen -t ed25519 -C "you@example.com",私钥务必设置口令短语;- 私钥权限必须是
600、目录700,否则 OpenSSH 会直接拒绝加载; - 一台设备一对密钥,方便按设备吊销,不要多台机器共用一个私钥。
~/.ssh/config 的实用写法
把跳板、端口、用户名与密钥路径都写进 config,能省掉大量重复参数:
Host *段里设ServerAliveInterval 30,避免长时间空闲被断开;- 内网机器用
ProxyJump bastion直连,无需先手动登录跳板; - 显式写
IdentityFile与IdentitiesOnly yes,避免尝试登录时把过多公钥推给服务器而被拒。
常见误区
- 开启 Agent forwarding:跳到不可信主机后,对方可借用你的 agent 登录其它机器,除非必要应关闭,改用
ProxyJump; - 把私钥拷来拷去:应生成新密钥并把公钥分发到服务器,而不是搬运私钥;
- 禁用密码登录后忘了免密:改
PasswordAuthentication no前先确认密钥登录可用,否则可能把自己锁在外面; - 忽略 known_hosts 变更:主机密钥变化可能是重装,也可能是中间人,务必核实后再清理记录。
服务端加固清单
关闭 root 直连、禁用密码认证、限制可登录用户、开启失败次数限制,并把 sshd 日志接入集中采集,便于识别爆破行为。
密钥轮换与吊销
- 按设备发放:一台设备一对密钥,离职或设备丢失时只需从
authorized_keys删除对应行,不影响其它人; - 注释即台账:
-C里写清使用者与设备,否则半年后没人敢删任何一行; - 定期轮换:私钥长期不换会持续累积风险,建议按年轮换并保留一段双密钥并行期;
- 证书优于裸公钥:规模稍大时改用 SSH 证书(CA 签发)可设置有效期,天然支持到期自动失效。
常见的连接失败原因
Permissions 0644 ... are too open:私钥权限过宽,改为600;Too many authentication failures:本地密钥过多被逐个尝试,加IdentitiesOnly yes与显式IdentityFile;Host key verification failed:对方主机密钥变更,先确认原因再更新known_hosts。
多环境配置的组织
把 ~/.ssh/config 按环境拆成若干文件,再用 Include 引入,避免一个文件越写越长。生产环境的别名建议带明确前缀(如 prod-),并开启 StrictHostKeyChecking 的默认严格模式,用命名习惯降低“连错机器”的概率。