SSH 安全登录终极配置:从密钥生成到 fail2ban
VPS 暴露在公网,第一道防线就是 SSH。默认配置(22 端口 + 密码登录)等于把家门钥匙挂在门把手上——你不去看 /var/log/auth.log,永远不知道每天有几千次自动化爆破在尝试你的 root 密码。
这篇把 SSH 安全登录的完整流程从头讲到尾:密钥生成 → 公钥上传 → 服务端配置 → 防火墙 → fail2ban,每一步都说清楚为什么这么做。
一、最终目标
22 → 22000] B -.端口扫描.-> C[ufw 白名单
只允许特定 IP] C -.强行连接.-> D[密码登录已关闭
必须密钥] D -.密钥爆破.-> E[fail2ban
3 次失败封 1 小时] E -.放弃.-> F[安全]
四道关卡叠加,攻击成本指数级上升。
二、第一步:本地生成密钥对
在你自己的电脑上(不是 VPS):
2.1 PowerShell / Bash / Zsh 都一样
ssh-keygen -t ed25519 -C "my-vps-key" -f ~/.ssh/my-vps-key| 参数 | 含义 |
|---|---|
-t ed25519 | 算法(ed25519 比 RSA 更短更安全) |
-C "..." | 注释,方便区分多个密钥 |
-f path | 私钥文件名 |
提示输入 passphrase(密钥保护密码):
- 本地开发机:可设可不设,设了每次用都要输
- 服务器中转 / 自动化场景:直接回车不设
2.2 生成结果
会得到两个文件:
| 文件 | 用途 |
|---|---|
~/.ssh/my-vps-key | 私钥,绝不能泄露,绝不上传 |
~/.ssh/my-vps-key.pub | 公钥,传到所有要登录的服务器 |
2.3 查看公钥内容
cat ~/.ssh/my-vps-key.pub输出类似:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...........xxxxxxxx my-vps-key整行复制下来。
三、第二步:把公钥放到 VPS
3.1 方式一:ssh-copy-id(最简单)
ssh-copy-id -i ~/.ssh/my-vps-key.pub root@<VPS_IP># 输入一次密码,自动放到 ~/.ssh/authorized_keys3.2 方式二:手动 echo(万能)
如果商家不支持 ssh-copy-id 或 Windows 没装:
# 先用密码 SSH 进去ssh root@<VPS_IP>
# 在 VPS 上跑mkdir -p ~/.sshchmod 700 ~/.ssh
# 把整行公钥追加到 authorized_keysecho "ssh-ed25519 AAAAC3...... my-vps-key" >> ~/.ssh/authorized_keyschmod 600 ~/.ssh/authorized_keys
# 验证权限ls -la ~/.ssh/权限必须是:
drwx------ 2 root root . (.ssh 700)-rw------- 1 root root authorized_keys (600)🪤 90% 的”密钥登录失败”都是权限错。权限太宽 sshd 会拒绝读密钥,就一直要密码。
3.3 验证密钥登录可用
开一个新终端(旧的别关,万一密钥配错可以救):
ssh -i ~/.ssh/my-vps-key root@<VPS_IP>不让你输密码、直接进去——成功。
四、第三步:配置 sshd
4.1 备份原配置
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak4.2 修改 /etc/ssh/sshd_config
sudo vim /etc/ssh/sshd_config找到以下行(如果前面有 # 要去掉):
# 改端口(建议 1024-65535 之间随机选一个)Port 22000
# 开启密钥登录PubkeyAuthentication yes
# 指定授权文件位置AuthorizedKeysFile .ssh/authorized_keys
# 关闭密码登录PasswordAuthentication no
# 关闭空密码PermitEmptyPasswords no
# 关闭挑战应答(PAM 那套)ChallengeResponseAuthentication no
# root 只能密钥登录(保留 root 但禁密码)PermitRootLogin prohibit-password
# 限制登录尝试次数MaxAuthTries 3| 配置项 | 改前 | 改后 | 作用 |
|---|---|---|---|
Port | 22 | 22000 | 避开自动化扫描 |
PubkeyAuthentication | yes/no | yes | 启用密钥 |
PasswordAuthentication | yes | no | 关闭密码登录 |
PermitEmptyPasswords | no/yes | no | 禁止空密码 |
PermitRootLogin | yes | prohibit-password | root 只允许密钥 |
MaxAuthTries | 6 | 3 | 限制单次连接的尝试次数 |
4.3 检查配置语法(关键!)
sudo sshd -t没有输出 = 配置正确。如果有 Bad configuration option 之类的错误,绝对不要重启 sshd——重启会导致 sshd 起不来,你就被锁外面了。
4.4 防火墙先开新端口
sudo ufw allow 22000/tcpsudo ufw status4.5 重启 sshd
sudo systemctl restart sshdsudo systemctl status sshd确认状态 active (running)。
4.6 确认监听端口
sudo ss -tlnp | grep ssh# 应该显示# LISTEN 0 128 0.0.0.0:22000 0.0.0.0:* users:(("sshd",pid=xxx,fd=3))4.7 新终端验证新端口
别关旧终端,新开:
ssh -p 22000 -i ~/.ssh/my-vps-key root@<VPS_IP>进得去——再删 22 端口的防火墙规则:
sudo ufw delete allow 22五、第四步:fail2ban 兜底
即使密钥登录、改了端口,攻击者还是可能扫到你的端口疯狂尝试。fail2ban 会监控日志,N 次失败自动封 IP M 分钟。
5.1 装 + 配置
sudo apt install -y fail2bansudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.localsudo vim /etc/fail2ban/jail.local把 [sshd] 段改成:
[sshd]enabled = trueport = 22000filter = sshdlogpath = /var/log/auth.logmaxretry = 3bantime = 3600findtime = 600backend = auto
# 自己的家庭/办公 IP 加白名单,避免自封ignoreip = 127.0.0.1/8 ::1 <你的家庭 IP>5.2 启动
sudo systemctl enable --now fail2bansudo systemctl status fail2ban5.3 常用命令
# 总览sudo fail2ban-client status
# 看 sshd jail(含被封 IP 列表)sudo fail2ban-client status sshd
# 手动封 / 解封sudo fail2ban-client set sshd banip 1.2.3.4sudo fail2ban-client set sshd unbanip 1.2.3.4六、本地 SSH config(开发体验飞升)
每次 ssh -p 22000 -i ~/.ssh/my-vps-key root@<IP> 太累。
编辑 ~/.ssh/config:
Host myvps HostName 1.2.3.4 Port 22000 User root IdentityFile ~/.ssh/my-vps-key ServerAliveInterval 60 ServerAliveCountMax 3之后只用:
ssh myvps| 配置项 | 含义 |
|---|---|
Host | 别名 |
HostName | 真实 IP/域名 |
Port | 端口 |
User | 默认用户 |
IdentityFile | 私钥路径 |
ServerAliveInterval | 多少秒发一次心跳(防止 NAT 断开) |
ServerAliveCountMax | 心跳几次没回应才认定断了 |
七、Termius / Tabby / 其它 GUI 客户端
这类工具的”添加密钥”功能:
- 生成密钥:在客户端里
Keys → Generate Key - 导入私钥:把本地生成的私钥整个文件内容粘贴进去(不要只贴公钥)
- 绑定到主机:在主机配置里选这个 key
不同客户端 UI 不一样,原理都是一样:私钥放在客户端 / 本地,公钥放在 VPS 的 ~/.ssh/authorized_keys。
八、所有关键文件位置
| 文件 | 作用 | 权限 |
|---|---|---|
本地 ~/.ssh/private_key | 私钥 | 600 |
本地 ~/.ssh/public_key.pub | 公钥 | 644 |
本地 ~/.ssh/config | 客户端配置 | 600 |
VPS /etc/ssh/sshd_config | 服务端配置 | 644 |
VPS ~/.ssh/authorized_keys | 已授权公钥列表 | 600 |
VPS /var/log/auth.log | SSH 登录日志 | - |
VPS /etc/fail2ban/jail.local | fail2ban 配置 | - |
九、踩坑清单
| 现象 | 原因 | 解决 |
|---|---|---|
| 密钥配了还是要密码 | ~/.ssh 或 authorized_keys 权限不对 | chmod 700 ~/.ssh; chmod 600 authorized_keys |
| 改端口连不上 | 防火墙没放新端口 | VNC 进去 ufw allow 新端口 |
| sshd restart 后服务起不来 | 配置语法错 | 用 sshd -t 提前检查 |
| 改了配置没生效 | 没 restart sshd | systemctl restart sshd |
| 改端口没生效(仍 22) | 云厂商平台代理 SSH | ss -lntp grep :22 看监听的是 sshd 还是 init |
| fail2ban 把自己封了 | 没加 ignoreip | VNC 进去 fail2ban-client set sshd unbanip 你的IP |
| 部分商家轻量服务器没法改端口 | 平台层硬编码 22 | 去厂商控制台改 |
十、几条实用经验
- 不要用 RSA,用 ed25519。短、快、安全。
- 公钥可以放多份,
authorized_keys一行一个,多设备共用同一 VPS 很方便。 - 私钥分机器:每台开发机生成自己的密钥,VPS 上
authorized_keys加多行,任何一台机器丢失只需要删那行。 - 改完 sshd 一定先
sshd -t再 restart——这一条能救命。 - fail2ban 不是万能:它防 SSH 爆破有用,对零日漏洞无能为力。保持系统更新才是根本。
- 永远不要图省事用密码登录——爆破一旦被打穿,整台机器没了。
完成这一套,你的 SSH 已经能扛住绝大多数自动化攻击。剩下的就是养成”系统勤更新、关注 CVE”的习惯。