SSH 是你管理 VPS 的唯一入口。如果 SSH 被攻破,服务器上的一切——你的代理配置、用户数据、密钥文件——都将暴露。好消息是,SSH 加固的步骤非常明确,五步操作就能把安全性提升一个量级。

⚠️ 操作顺序很重要
本文的步骤按推荐顺序排列。每完成一步都建议先测试连接,确认正常后再进行下一步。尤其是禁用密码登录前,务必确认密钥认证已经可用。

一、生成 Ed25519 密钥对

SSH 密钥认证比密码认证安全得多:暴力破解密码需要几秒到几分钟,暴力破解 256 位的 Ed25519 密钥需要的时间超过宇宙年龄。

1.1 为什么选 Ed25519

密钥类型安全性密钥长度性能推荐
Ed25519极高256 位推荐首选
RSA 40964096 位较慢兼容性好时可用
RSA 2048够用2048 位旧系统不得已
ECDSA256/384/521 位不推荐(实现易有随机数问题)
DSA已淘汰1024 位禁止使用

1.2 在本地电脑生成密钥

在你的本地电脑(不是 VPS)上执行:

# 生成 Ed25519 密钥对
ssh-keygen -t ed25519 -C "你的邮箱@example.com"

# 生成过程会提示:
# 1. 保存路径 → 直接回车用默认路径 (~/.ssh/id_ed25519)
# 2. 设置密码短语(passphrase)→ 强烈建议设置
# 3. 确认密码短语
💡 密码短语(Passphrase)要不要设?
建议设置。密码短语是私钥文件的"第二层锁"——即使私钥文件被偷走,没有密码短语也无法使用。如果你觉得每次输入麻烦,可以配合 ssh-agent 缓存密码短语,输入一次后在终端会话期间免重复输入。

1.3 将公钥上传到 VPS

# 方法一:ssh-copy-id(最简单)
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@你的VPS_IP

# 方法二:手动追加
cat ~/.ssh/id_ed25519.pub | ssh root@你的VPS_IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

1.4 验证密钥登录

上传公钥后,开一个新的终端窗口测试密钥登录:

ssh -i ~/.ssh/id_ed25519 root@你的VPS_IP

如果能正常登录(输入密码短语后),说明密钥认证已生效。确认没问题后,再进行下一步。

二、禁用密码登录

密钥认证确认可用后,禁用密码登录。这一步堵死了暴力破解的入口。

# 在 VPS 上编辑 SSH 配置
vi /etc/ssh/sshd_config

修改或添加以下配置项:

# 禁用密码登录
PasswordAuthentication no

# 禁用空密码
PermitEmptyPasswords no

# 禁用 root 密码登录(可选但推荐)
PermitRootLogin prohibit-password

重启 SSH 服务使配置生效:

# Debian / Ubuntu
systemctl restart ssh

# CentOS / RHEL
systemctl restart sshd
⚠️ 千万不要在禁用密码登录前关闭当前终端
修改配置后,先用新终端窗口测试密钥登录是否正常。确认正常后,再关闭旧的密码登录终端。否则一旦密钥有问题,你会被锁在外面。

三、更换 SSH 端口

默认端口 22 是全球扫描器的首要目标。换成非标准端口后,自动化扫描的命中率会大幅下降。

3.1 选择端口号

推荐选择 1024-65535 范围内的端口,避开常见服务端口:

推荐端口说明
2222最常用的 SSH 替代端口
2200简洁好记
443与 HTTPS 混淆(需确认不与代理冲突)
10022足够隐蔽

3.2 修改端口

# 编辑 SSH 配置
vi /etc/ssh/sshd_config

# 找到 Port 22,改为(以 2222 为例)
Port 2222

# 重启 SSH
systemctl restart ssh

3.3 防火墙同步

端口修改后,需要同步更新防火墙规则(以 iptables 为例):

# 放行新端口
iptables -A INPUT -p tcp --dport 2222 -j ACCEPT

# 删除旧端口规则(如果有)
iptables -D INPUT -p tcp --dport 22 -j ACCEPT

# 保存规则
netfilter-persistent save

ufw 用户:

ufw allow 2222/tcp
ufw delete allow 22/tcp
ufw status

3.4 验证新端口

开一个新终端窗口,用新端口连接:

ssh -p 2222 root@你的VPS_IP

确认正常后,再关闭旧终端。

四、安装 fail2ban 防暴力破解

即使禁用了密码登录、更换了端口,SSH 仍然可能受到连接风暴和端口扫描的骚扰。fail2ban 监控登录日志,自动封禁反复失败的 IP。

4.1 安装

# Debian / Ubuntu
apt install fail2ban -y

# CentOS / RHEL
yum install fail2ban -y

# 启动并设置开机自启
systemctl enable --now fail2ban

4.2 配置

fail2ban 不要直接修改 /etc/fail2ban/jail.conf,而是创建 jail.local 覆盖配置:

cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
# 封禁时间(秒)
bantime = 3600
# 检测窗口(秒)
findtime = 600
# 最大失败次数
maxretry = 5
# 使用 iptables 封禁
banaction = iptables-multiport

[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
EOF
💡 配置说明
port — 填你修改后的 SSH 端口
logpath — Debian/Ubuntu 用 /var/log/auth.log,CentOS 用 /var/log/secure
maxretry — 同一 IP 在检测窗口内失败多少次后封禁
bantime — 封禁时长,86400 = 24 小时

4.3 重启并验证

# 重启 fail2ban
systemctl restart fail2ban

# 查看 SSH jail 状态
fail2ban-client status sshd

# 查看被封禁的 IP 列表
fail2ban-client status sshd | grep "Banned IP"

4.4 手动封禁/解封 IP

# 手动封禁一个 IP
fail2ban-client set sshd banip 1.2.3.4

# 手动解封一个 IP
fail2ban-client set sshd unbanip 1.2.3.4

五、登录审计与日志监控

加固完成后,定期检查登录日志可以帮你发现异常行为。

5.1 查看登录日志

# 查看最近的 SSH 登录记录
journalctl -u ssh --since "7 days ago"

# 或直接查看日志文件
grep "sshd" /var/log/auth.log | tail -30

# 查看成功登录记录
grep "Accepted" /var/log/auth.log | tail -20

# 查看失败登录记录
grep "Failed" /var/log/auth.log | tail -20

5.2 检查异常登录

关注以下异常信号:

  • 陌生 IP 登录:除了你的出口 IP,是否有其他 IP 成功登录过?
  • 非工作时间登录:凌晨 2-5 点的登录记录需要关注。
  • root 直接登录:如果你已经创建了普通用户,root 直接登录应该很少出现。
  • 大量失败尝试:来自同一 IP 的多次失败可能意味着针对性攻击。
# 一键查看:按 IP 统计登录次数
grep "Accepted" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn | head -10

# 查看指定时间段的登录记录
grep "sshd" /var/log/auth.log | grep "Jul 14"

5.3 创建普通用户(可选但推荐)

长期使用 root 直接登录有风险。创建一个普通用户,需要管理员权限时用 sudo

# 创建用户
adduser deploy

# 加入 sudo 组
usermod -aG sudo deploy

# 将 SSH 公钥复制到新用户
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@你的VPS_IP

# 测试新用户登录
ssh -p 2222 deploy@你的VPS_IP

# 确认正常后,可选:禁止 root 直接 SSH 登录
# 在 /etc/ssh/sshd_config 中设置:
PermitRootLogin no

六、完整加固脚本

将以上步骤整合为一个一键脚本,在新 VPS 上直接执行:

#!/bin/bash
# SSH 安全加固脚本 — 在 VPS 上执行
# 执行前确认:已通过 ssh-copy-id 上传了公钥

set -e

echo "=== SSH 安全加固开始 ==="

# 1. 安装 fail2ban
apt update && apt install fail2ban -y

# 2. 配置 fail2ban
cat > /etc/fail2ban/jail.local << 'FAIL2BAN'
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
banaction = iptables-multiport

[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
FAIL2BAN

systemctl enable --now fail2ban

# 3. 修改 SSH 配置
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

sed -i 's/^#\?Port .*/Port 2222/' /etc/ssh/sshd_config
sed -i 's/^#\?PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#\?PermitEmptyPasswords .*/PermitEmptyPasswords no/' /etc/ssh/sshd_config
sed -i 's/^#\?PermitRootLogin .*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config

# 4. 重启 SSH
systemctl restart ssh

echo "=== 加固完成 ==="
echo "SSH 端口已改为 2222"
echo "密码登录已禁用"
echo "fail2ban 已安装并配置"
echo ""
echo "请用新终端测试:ssh -p 2222 root@你的VPS_IP"
⚠️ 使用脚本前
脚本会直接修改 SSH 配置并重启。执行前确保:(1) 已上传公钥并验证可用;(2) 有带外访问方式(VPS 控制台)以防万一。

七、常见问题排查

现象可能原因解决方案
禁用密码后无法登录公钥未正确上传通过控制台检查 ~/.ssh/authorized_keys 内容
更换端口后连接超时防火墙未放行新端口通过控制台添加防火墙规则
fail2ban 封禁了自己多次输错密码短语fail2ban-client set sshd unbanip 你的IP
密钥登录提示权限错误.ssh 目录权限不对chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
连接被拒绝(Connection refused)SSH 服务未运行通过控制台执行 systemctl start ssh
公钥认证不生效sshd_config 中禁用了公钥认证确认 PubkeyAuthentication yes(默认是开的)

7.1 检查文件权限

SSH 对文件权限非常严格,权限不对会导致认证失败:

# 正确的权限设置
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/id_ed25519.pub

# 一键修复
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

7.2 紧急恢复

如果被锁在外面,通过 VPS 控制台登录后:

# 恢复 SSH 配置
cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config
systemctl restart ssh

# 或临时启用密码登录
sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
systemctl restart ssh

八、加固检查清单

1

Ed25519 密钥对

在本地生成密钥对并上传公钥到 VPS,验证密钥登录可用。

2

禁用密码登录

设置 PasswordAuthentication no,确认密钥登录正常后重启 SSH。

3

更换端口

将 SSH 端口改为 2222 等非标准端口,同步更新防火墙规则。

4

安装 fail2ban

配置自动封禁规则,3 次失败封禁 24 小时。

5

登录审计

定期检查登录日志,关注异常 IP 和非工作时间登录。