Linux 服务器 SSH 安全加固实战:从密码登录到纯密钥认证
面向 Linux 服务器新手的 SSH 安全加固指南,完整介绍如何从 Root 密码登录过渡到 SSH 密钥认证,并关闭密码登录以降低暴力破解风险。
前言
SSH 是管理 Linux 服务器最常用的远程连接方式。很多新服务器初始化时会先使用 root 用户和密码登录,但公网服务器长期暴露在互联网中,经常会遭遇自动化扫描和密码暴力破解。
更稳妥的做法是:先用密码完成初始化,再配置 SSH 密钥登录,确认密钥可用后关闭密码登录,只保留密钥认证。
本文按几个大方向整理完整流程:
- Root 密码登录
- SSH 密钥登录
- 关闭密码登录
- 验证与排错
- 推荐配置模板
重点关注几个容易踩坑的地方:
- 公钥应该放在哪里
.ssh和authorized_keys权限应该怎么设- 私钥是否需要 passphrase 保护
- 关闭密码登录前如何避免把自己锁在服务器外
- 如何确认密码登录确实已经被禁用
一、Root 密码登录
Root 密码登录适合服务器初始化阶段使用。例如刚购买云服务器时,你可能需要先通过密码连接上去,创建用户、更新系统、安装基础软件或配置 SSH 密钥。
需要注意:Root 密码登录不建议长期开放。它方便管理,也方便攻击者进行暴力破解。因此,Root 密码登录应该只是过渡方案。
开启 Root 密码登录
使用 root 用户或具有 sudo 权限的用户登录服务器,编辑 SSH 服务端配置文件:
sudo nano /etc/ssh/sshd_config找到或新增以下配置:
PermitRootLogin yesPasswordAuthentication yes含义如下:
| 配置项 | 作用 |
|---|---|
PermitRootLogin yes | 允许 root 用户直接通过 SSH 登录 |
PasswordAuthentication yes | 允许使用密码进行 SSH 认证 |
如果原文件中看到类似内容:
#PermitRootLogin prohibit-password#PasswordAuthentication yes不要简单理解为“前面有 # 就是关闭”。在 OpenSSH 中,注释通常表示使用默认值。为了避免误解,建议直接写出明确配置。
修改完成后,先检查配置语法:
sudo sshd -t如果没有任何输出,说明语法正常。
然后重启 SSH 服务:
sudo systemctl restart sshd部分系统服务名可能是 ssh:
sudo systemctl restart ssh此时可以使用 root 用户和密码连接服务器。
二、SSH 密钥登录
密码登录只能作为临时过渡。完成基础连接后,应尽快配置 SSH 密钥认证。
SSH 密钥认证的核心逻辑是:
- 私钥保存在本地电脑
- 公钥写入服务器
- 登录时,本地私钥与服务器公钥匹配,认证通过
生成 SSH 密钥对
密钥对应该在本地电脑生成,不要在服务器上生成。
Windows 用户可以使用 PowerShell,macOS 和 Linux 用户可以使用 Terminal。
执行:
ssh-keygen -t ed25519 -C "my_server_key"默认会生成两个文件:
~/.ssh/id_ed25519~/.ssh/id_ed25519.pub| 文件 | 类型 | 是否可以公开 | 说明 |
|---|---|---|---|
id_ed25519 | 私钥 | 不可以 | 只能保存在本地电脑,不能发送给任何人 |
id_ed25519.pub | 公钥 | 可以 | 需要写入服务器的 authorized_keys 文件 |
为私钥设置 passphrase
生成密钥时,终端会提示:
Enter passphrase (empty for no passphrase):Enter same passphrase again:建议为重要服务器使用的私钥设置 passphrase。
passphrase 可以理解为“私钥的本地解锁密码”。它不会发送到服务器,也不是服务器 root 密码。它只用于在本地解锁私钥文件。
| 项目 | 作用位置 | 用途 |
|---|---|---|
| 服务器密码 | 服务器端 | 用于密码登录服务器 |
| SSH 私钥 | 本地电脑 | 用于密钥认证 |
| 私钥 passphrase | 本地电脑 | 用于解锁私钥文件 |
如果私钥文件被他人复制,而私钥没有 passphrase,攻击者可能直接尝试使用该私钥登录服务器。设置 passphrase 后,即使私钥文件泄露,也仍然需要额外的解锁密码。
如果之前生成私钥时没有设置 passphrase,可以后续补上:
ssh-keygen -p -f ~/.ssh/id_ed25519Windows PowerShell:
ssh-keygen -p -f $env:USERPROFILE\.ssh\id_ed25519设置 passphrase 后,如果不想每次连接都重复输入,可以使用 ssh-agent 缓存已解锁的私钥。
macOS / Linux:
eval "$(ssh-agent -s)"ssh-add ~/.ssh/id_ed25519Windows PowerShell:
Start-Service ssh-agentssh-add $env:USERPROFILE\.ssh\id_ed25519手动配置公钥到服务器
很多教程会使用 ssh-copy-id 上传公钥,但不少 Windows 环境默认没有这个命令。手动复制粘贴法更通用,也能让你清楚知道公钥到底被放到了服务器哪里。
先在本地查看公钥。
macOS / Linux:
cat ~/.ssh/id_ed25519.pubWindows PowerShell:
Get-Content ~/.ssh/id_ed25519.pub也可以直接用记事本打开:
C:\Users\你的用户名\.ssh\id_ed25519.pub复制完整公钥内容。它通常以 ssh-ed25519 开头,末尾可能带有注释,例如:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx my_server_key复制时必须复制整行,不能只复制中间一部分。
然后回到服务器 SSH 窗口,创建 .ssh 目录并设置权限:
mkdir -p ~/.sshchmod 700 ~/.ssh将公钥写入 authorized_keys:
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx my_server_key" >> ~/.ssh/authorized_keyschmod 600 ~/.ssh/authorized_keys这里的权限非常关键:
| 路径 | 推荐权限 | 说明 |
|---|---|---|
~/.ssh | 700 | 只有当前用户可以读、写、进入 |
~/.ssh/authorized_keys | 600 | 只有当前用户可以读写 |
如果权限过于开放,例如 777,OpenSSH 可能会认为环境不安全,从而拒绝密钥认证。
测试密钥登录
在关闭密码登录之前,必须先确认密钥登录已经可用。
不要关闭当前已经连接的 SSH 窗口。保留这个窗口作为回退通道。
在本地电脑新开一个终端,执行:
ssh root@你的服务器IP如果配置成功,会出现以下情况之一:
- 直接登录服务器
- 提示输入私钥 passphrase
只要没有要求输入服务器 root 密码,就说明密钥登录已经生效。
如果仍然提示输入服务器密码,说明密钥认证没有成功。此时不要继续关闭密码登录,应该先排查公钥内容、文件权限和登录用户是否正确。
三、关闭密码登录
确认密钥登录成功后,就可以关闭密码认证。
这是整套 SSH 加固中最关键的一步。关闭前请记住一个原则:不要关闭当前已经连上的 SSH 窗口。
这个旧窗口是回退通道。如果新窗口因为配置错误连不上,你仍然可以用旧窗口把配置改回来。
修改 SSH 配置
编辑配置文件:
sudo nano /etc/ssh/sshd_config设置:
PasswordAuthentication noPubkeyAuthentication yes如果仍然希望允许 root 使用密钥登录,可以保留:
PermitRootLogin yes如果后续希望进一步加固,可以创建普通用户,使用普通用户登录后再通过 su 或 sudo 提权。
检查并重载 SSH 服务
保存后先检查语法:
sudo sshd -t如果没有输出,说明配置语法正确。
然后平滑重载 SSH 服务:
sudo systemctl reload sshd如果服务名是 ssh:
sudo systemctl reload ssh这里建议使用 reload,不要直接 restart。reload 会重新加载配置,通常不会中断当前已连接会话,更适合远程修改 SSH 配置时使用。
四、验证与排错
配置完成后,需要验证两件事:
- 密钥登录仍然可用
- 密码登录已经被禁用
验证密钥登录
在本地新开终端:
ssh root@你的服务器IP预期结果:可以正常登录服务器,并且不会提示输入服务器 root 密码。
验证密码登录已禁用
强制 SSH 客户端只使用密码认证,并禁用公钥认证:
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no root@你的服务器IP预期结果:服务器拒绝登录,通常会看到类似提示:
Permission denied (publickey).如果仍然出现 password: 提示,说明密码认证没有被正确关闭,需要重新检查 sshd_config。
常见问题
如果仍然提示输入服务器密码,常见原因包括:
- 公钥没有正确写入
~/.ssh/authorized_keys - 公钥只复制了一部分,不是完整一行
.ssh或authorized_keys权限不正确- 服务器登录用户不是你写入公钥的用户
- SSH 服务没有重载配置
建议检查:
cat ~/.ssh/authorized_keyschmod 700 ~/.sshchmod 600 ~/.ssh/authorized_keyssudo sshd -tsudo systemctl reload sshd如果修改配置后没有生效,可能是其他配置文件覆盖了主配置。检查目录:
ls -la /etc/ssh/sshd_config.d/查看最终生效值:
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|pubkeyauthentication'如果新窗口无法登录,不要关闭旧窗口。在旧窗口中临时恢复:
PasswordAuthentication yes然后检查并重载:
sudo sshd -tsudo systemctl reload sshd恢复连接后,再重新排查密钥配置问题。
五、推荐配置模板
完成加固后,/etc/ssh/sshd_config 中与认证相关的核心配置可以参考如下模板。
# 允许 root 登录。后续也可以改为普通用户登录后再提权。PermitRootLogin yes
# 禁用密码登录,降低暴力破解风险。PasswordAuthentication no
# 启用公钥认证。该项默认通常就是 yes,显式写出更清晰。PubkeyAuthentication yes
# 关闭不需要的认证方式。KerberosAuthentication noGSSAPIAuthentication no需要注意:不同发行版、不同 OpenSSH 版本、不同云厂商镜像可能存在额外配置文件,例如:
/etc/ssh/sshd_config.d/*.conf如果主配置文件修改后没有生效,需要检查这些附加配置文件中是否存在覆盖项。
总结
SSH 安全加固的核心思路并不复杂:先保证自己能够通过密钥登录,再关闭密码登录。
推荐的最小安全流程是:
- 临时使用 root 密码登录完成初始化
- 本地生成 SSH 密钥对
- 为重要私钥设置 passphrase
- 将公钥写入服务器
~/.ssh/authorized_keys - 设置正确权限:
.ssh为700,authorized_keys为600 - 新开终端确认密钥登录成功
- 修改
PasswordAuthentication no - 使用
sudo sshd -t检查配置 - 使用
sudo systemctl reload sshd平滑重载 - 强制密码认证测试,确认密码登录已被禁用
完成这些步骤后,服务器将不再接受密码认证,可以有效降低公网暴力破解风险。
对于个人服务器和小型项目来说,这是非常值得优先完成的一项基础安全配置。
觉得这篇文章怎么样?
点个赞,让更多人看到!
相关文章
OpenClaw 安装、卸载与更新:一篇带你学会
一篇讲清 OpenClaw 的安装、卸载与更新流程,适合新手快速上手,并附常见问题与排查思路。
SSH 连不上服务器时,几种中转方案的实战总结
总结灰云直连、Cloudflare Tunnel、SSH 跳板机与 Tailscale/WireGuard 几种常见 SSH 中转方案,结合一次本地网络受限的真实排障过程,帮助快速判断该选哪条路径。
OpenClaw 怎么安装和更新?curl脚本、npm、Docker 全对比
一文讲清 OpenClaw 的 4 种安装方式:官方脚本、npm 全局、源码、容器;并给出对应更新、回滚与排障策略。
Vaultwarden(Docker)怎么查看版本并升级?一套可复制的更新流程
以 Docker Compose 部署为例,讲清 Vaultwarden 如何查看当前版本、pull 最新镜像、重建容器完成升级,并处理 compose version 过时与 ADMIN_TOKEN 明文告警。

评论区