SSH 密钥登录配置详解:从 ssh-keygen 到禁用密码

SSH 密钥登录配置详解:从 ssh-keygen 到禁用密码

SSH安全加固服务器运维Linux
📶 入门 🧩 OpenSSH

一台新上线的云服务器只要分配了公网 IP 并暴露 22 端口,几分钟内就会迎来全网不断的自动化密码爆破扫描。哪怕是 38 元/年的阿里云 2核2G 入门机型(价格查询于 2026-10-03),也会被僵尸网络无差别盯上。我们在 服务器安全加固指南 一文中曾提过「用密钥别用密码」。密码登录在公网上被全自动爆破只是时间问题,配置 SSH 密钥登录是唯一的根治方案。本篇将用 5 个关键步骤,切断服务器被密码爆破的攻击面。

选用 ed25519 生成本地密钥对

威胁:老旧的 RSA 算法需要 3072 位甚至 4096 位的长度才能保证安全。它不仅生成速度慢,密钥文件也过长。如果还在使用默认参数生成较短的 RSA 密钥,很容易被现代算力破解。

命令: 在本地终端执行,指定使用 ed25519 算法。它是目前安全性与签名速度兼顾的最优解。

ssh-keygen -t ed25519 -C "admin@local"

执行后,系统会提示保存路径。直接按回车使用默认的 ~/.ssh/id_ed25519。遇到 Enter passphrase 提示时,输入一个短密码来保护私钥文件本身。一旦物理设备丢失,这个短密码能为你换来吊销公钥的缓冲时间。

验证: 执行以下命令。确认公钥(.pub 后缀)和私钥文件已经生成。

ls -l ~/.ssh/id_ed25519*

私钥必须保留在本地客户端,公钥则需要上传给目标服务器。

使用 ssh-copy-id 自动化下发公钥

威胁:手工复制 id_ed25519.pub 内容并写入服务器文件时容易出错。多加空格、遗漏字符或截断换行,会直接导致密钥格式损坏而无法解析。

命令: 利用 Ubuntu 和大多数 Linux 发行版自带的 ssh-copy-id 自动化下发公钥。这一步需要你当前仍有目标服务器的密码访问权限。

ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]

按照提示输入一次服务器账号密码。工具会自动将公钥追加到服务器对应用户的 ~/.ssh/authorized_keys 文件末尾。

验证: 执行 ssh [email protected]。如果能跳过远端密码验证直接登入环境,说明公钥部署完成。

避开 authorized_keys 的权限陷阱

威胁:OpenSSH 守护进程默认开启了 StrictModes 严格权限检查。如果存放公钥的 .ssh 目录对组或其他用户开放了写入权限,系统会认为该环境已被污染。此时 SSH 会无视你的公钥文件,强行退回密码登录。

目录/文件正确权限数字对应说明
~/.ssh 目录drwx------700仅所有者拥有读、写、执行权限,屏蔽其他用户。
authorized_keys-rw-------600仅所有者拥有读、写权限,不可执行。
私钥文件 (id_ed25519)-rw-------600仅所有者可读写。若权限过宽,本地客户端直接报错。

命令: 在服务器端执行以下命令,收拢读写权限。

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

验证: 检查权限位配置,确保严格符合上述标准。

ls -ld ~/.ssh
ls -l ~/.ssh/authorized_keys

配置 SSH 别名与免密代理

威胁:每次连接都需要手敲长串 IP 和用户名。在给私钥设置了 passphrase 后,每次登录依然要求输入密码。这在面对多台服务器时会严重拖累运维效率。

命令:

  1. 启动 ssh-agent 并在内存中托管私钥解密状态。这样只需在每次本地开机时验证一次 passphrase。
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
  1. 编辑本地的 ~/.ssh/config,录入服务器别名。
Host myserver
    HostName 203.0.113.1
    User username
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

验证: 在本地终端敲击 ssh myserver。一步登入说明代理与别名已正确工作。

禁用密码登录并切断回退通道

威胁:只要 sshd_config 还允许密码认证,爆破字典就依然能不断重试。这不仅长期消耗服务器网络连接,更让先前配置好的密钥形同虚设。必须切断这条危险的回退路径。

命令: 在动手前,你必须确保当前已经用密钥成功登录了服务器,并且使用的账号拥有 sudo 权限。这是禁用密码前的回滚保险,避免配置失误把自己锁在系统外面。在 Ubuntu 24.04 LTS 的终端内,编辑 SSH 配置文件:

sudo nano /etc/ssh/sshd_config

找到 PasswordAuthentication 字段,将其修改为 no。为防止 PAM 模块通过键盘交互继续请求密码,将 KbdInteractiveAuthentication 也设为 no。

PasswordAuthentication no
KbdInteractiveAuthentication no

保存后重启 SSH 服务。

sudo systemctl restart ssh

验证: 另开一个终端窗口,强制不带密钥进行测试。

ssh -o PubkeyAuthentication=no myserver

如果服务器直接返回 Permission denied (publickey) 报错,且不出现输入密码的交互框,说明爆破通道已被封死。

常见问题(FAQ)

1. 为什么执行 ssh-copy-id 之后登录还要输密码? 多半是权限被篡改了。如果服务器端 ~/.ssh 目录不是 700,或者 authorized_keys 文件不是 600,OpenSSH 会拒接读取公钥内容。请再次检查云服务器对应目录的权限,或者查阅 /var/log/auth.log 寻找 Authentication refused: bad ownership or modes 报错。

2. SSH 客户端提示 WARNING: UNPROTECTED PRIVATE KEY FILE 怎么处理? 这是因为本地私钥文件权限过宽。私钥文件必须是 600 权限(仅当前所有者可读写)。在本地终端执行 chmod 600 ~/.ssh/id_ed25519 即可消除警告并恢复使用。

3. 禁用密码后,本地私钥弄丢了怎么办? 云厂商都会在控制台提供基于 VNC 或串口的网页登录入口。你可以通过网页控制台绕过 SSH 直接登录系统本地终端,重新将 PasswordAuthentication 改为 yes 恢复密码访问,或者将生成好的新公钥手动写入 ~/.ssh/authorized_keys。

落实上述加固策略后,服务器的防线就从脆弱的密码校验,转移到了物理介质与加密算法上。如果当下只能做 3 件事,请立刻生成 ed25519 密钥、用 ssh-copy-id 下发,然后果断将 PasswordAuthentication 设为 no。