【安全基线 01】加固 SSH 与 Fail2ban

新开通的 VPS 几分钟就会被全球机器人爆破扫描。本文手把手教你三步救命加固:改用 SSH 密钥登录并禁用 root 密码、部署 Fail2ban 自动封 IP、用 UFW 防火墙坚持默认拒绝只放行必要端口。

延伸阅读

更多相关攻略推荐:【发行版选型 10】如何选择合适的 Linux 发行版VPS 装什么系统好?Ubuntu、Debian、CentOS 大白刚买的 VPS 怎么连上去?SSH 新手教程(Windows / MVPS 的带宽、流量、端口到底是啥?1Gbps 和 10TB 流量怎【优惠码 01】VPS 优惠码怎么用?哪里找靠谱折扣码、怎么避坑(2

一、新买的 VPS,为什么几分钟就被爆破?

很多新手兴冲冲开了一台 VPS,连上去还没来得及装环境,回头一看日志,满屏都是失败的登录尝试。这不是你被谁盯上了,而是全网自动化的僵尸网络在扫段

原理很简单:攻击者手里有成片的 IPv4 段,用脚本全自动地逐个 IP、逐个端口试探。SSH 默认端口 22 是头号目标,脚本会拿着一堆常见用户名(root、admin、user、test…)和弱密码字典疯狂撞库。只要你的密码够弱,或者还开着 root 密码登录,分分钟就可能被攻破。所以安全加固必须在新机器上线第一时刻做,而不是等业务跑起来再补。

下面三步走,把机器人挡在门外。

亲眼看看被扫的样子

你可以用下面这条命令翻一下登录日志,感受一下攻击的密集程度:

sudo tail -n 50 /var/log/auth.log

你会看到成片这样的记录(IP 和用户名都是机器人乱猜的):

Failed password for root from 185.220.101.35 port 41234 ssh2
Failed password for invalid user admin from 185.220.101.35 port 41236 ssh2
Connection closed by 91.214.124.143 port 55910 [preauth]

这些就是僵尸网络在撞库。它们不在乎你是谁,只管批量试。所以别抱侥幸心理——只要机器暴露公网,几分钟内必被扫,加固不是可选项,是必选项。

二、第一步:SSH 密钥登录 + 禁用 root 密码

密码再复杂也比不过一把密钥。SSH 密钥登录的原理是:在你的电脑上生成一对密钥,公钥放到服务器,私钥留在自己电脑且绝不外传。登录时服务器用公钥验你的私钥,攻击者没有私钥就进不来,暴力猜密码彻底失效。

2.1 先建一个普通管理员用户(别天天用 root)

直接用 root 干活风险极高,一步误操作就能删库。先建个普通用户并给它 sudo 权限:

adduser admin
usermod -aG sudo admin

(CentOS / AlmaLinux / Rocky 等把 sudo 组换成 wheel:usermod -aG wheel admin

2.2 在本机生成密钥对

在你自己的电脑(不是服务器)上执行:

ssh-keygen -t ed25519 -C "you@example.com"

一路回车用默认路径(~/.ssh/id_ed25519),建议设个私钥口令(passphrase)更安全。生成后会得到两个文件:id_ed25519(私钥,绝不可泄露)和 id_ed25519.pub(公钥,上传到服务器)。顺便说一下密钥类型:这里用的 ed25519 是目前推荐的现代算法,密钥短、速度快、安全性高。老教程常让你用 ssh-keygen -t rsa -b 4096,RSA 4096 也安全,但密钥更长、验证稍慢,新手无脑选 ed25519 就行。私钥文件权限必须是 600、公钥 644,权限太开放 SSH 会拒绝使用。

2.3 把公钥塞进服务器

最省事的办法是用 ssh-copy-id:

ssh-copy-id -i ~/.ssh/id_ed25519.pub admin@服务器IP

如果本机没有 ssh-copy-id(比如某些 Windows 环境),就手动来:在服务器上

sudo -u admin mkdir -p /home/admin/.ssh
sudo -u admin chmod 700 /home/admin/.ssh
sudo -u admin nano /home/admin/.ssh/authorized_keys

id_ed25519.pub 的内容粘进去,保存后:

sudo -u admin chmod 600 /home/admin/.ssh/authorized_keys

先开个新终端测试密钥登录能不能成:

ssh admin@服务器IP

能免密进去,说明密钥生效了。这一步务必先验证,再动接下来的配置。

2.4 改 SSH 配置:换端口、禁 root、禁密码

编辑 /etc/ssh/sshd_config

sudo nano /etc/ssh/sshd_config

确保(或改成)以下几行:

# 改个高位端口,避开 22 被扫(先去防火墙放行这个端口再改!)
Port 2222

# 禁止 root 直接登录
PermitRootLogin no

# 禁止密码登录,只用密钥
PasswordAuthentication no

# 允许密钥
PubkeyAuthentication yes

# 关掉交互式键盘认证
KbdInteractiveAuthentication no
ChallengeResponseAuthentication no

# 限制试错次数和登录超时,进一步抗爆破
MaxAuthTries 3
LoginGraceTime 30

改完先校验语法,没问题再重载(重载不会断开你当前的会话,比 restart 安全):

sudo sshd -t
sudo systemctl reload ssh

⚠️ 黄金法则:改 SSH 之前一定保持一个已登录的会话开着,并且先用新端口、新用户、密钥在另一个终端试登录成功,确认没问题再关掉旧会话。否则一旦配错,你可能就被锁在门外,只能靠商家面板的 VNC/救援模式救场。

用新端口登录的命令:

ssh -p 2222 admin@服务器IP

三、第二步:部署 Fail2ban,自动封禁爆破 IP

就算你把密码登录关了,机器人还是会不停来敲门,日志刷得烦人。Fail2ban 的作用是:盯着 SSH 日志,发现某个 IP 短时间内多次登录失败,就自动用防火墙把它 ban 掉一段时间,省心又挡住大部分噪音攻击。

它的工作分三块理解:filter(过滤器)定义「什么样算恶意」(比如 sshd 的失败登录正则)、jail(监狱)把 filter 和动作绑在一起并设触发门槛、action(动作)决定怎么封(这里用 ufw 加一条拒绝规则)。三者配合,日志里一出现超阈值的失败,就自动封 IP。参数含义也很好记:maxretry 是「几次失败开始封」,findtime 是「在这段时间内统计」,bantime 是「封多久」。比如上面设的 10 分钟内失败 5 次就封 1 小时。

3.1 安装

sudo apt update
sudo apt install -y fail2ban

3.2 写 jail.local 配置(别直接改 jail.conf)

Fail2ban 默认配置在 jail.conf,官方建议新建 jail.local 覆盖,方便以后升级不丢配置:

sudo nano /etc/fail2ban/jail.local

填入下面这段:

[DEFAULT]
# 封禁时长:1 小时
bantime = 1h
# 统计窗口:10 分钟内
findtime = 10m
# 允许的最大失败次数
maxretry = 5
# 用 ufw 作为封禁动作(Ubuntu/Debian 配合 UFW 最顺手)
banaction = ufw

[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s

注意:如果你改了 SSH 端口(比如 2222),把 port = ssh 改成 port = 2222,否则 Fail2ban 监听的端口对不上,规则不生效。

3.3 启动并验证

sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd

第二条能看到 sshd 监狱已激活、当前封了哪些 IP。想解封某个 IP:

sudo fail2ban-client set sshd unbanip 1.2.3.4

想看封禁日志:

sudo tail -n 50 /var/log/fail2ban.log

四、第三步:UFW 防火墙,默认拒绝只放行必要端口

防火墙的核心原则只有八个字:默认拒绝,按需放行。也就是「所有进来的流量先一概拒绝,只把我明确需要的端口打开」。

4.1 安装与默认策略

sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing

4.2 放行必要端口(顺序很重要)

如果你改了 SSH 端口,一定要先放行新端口,再去改 sshd_config 和重载,否则会被自己关在门外:

# 放行新的 SSH 端口
sudo ufw allow 2222/tcp

# 如果跑网站,放行 80 和 443
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

如果 SSH 还用默认 22,就放行 sudo ufw allow OpenSSHsudo ufw allow 22/tcp

4.3 启用防火墙

sudo ufw enable
sudo ufw status verbose

status verbose 会列出当前放行的规则。日常管理记住几条就好:加服务用 sudo ufw allow 端口/tcp;想看带编号的规则列表用 sudo ufw status numbered,按编号删规则用 sudo ufw delete 序号;关掉某个端口用 sudo ufw delete allow 端口/tcp。记住一个原则:任何新服务要对外,先想清楚要不要开端口,能不开就不开

启用 UFW 时它会问你「命令可能会断开现有连接」,输入 y 确认即可。万一你忘了先放行 SSH 端口又手滑 enable,当前会话一般还能保住,立刻补一条 sudo ufw allow 2222/tcp 就好;要是真断了,就走商家面板的 VNC / 救援模式进去补救。

RHEL 系(CentOS / Alma / Rocky)默认没有 UFW,用 firewalld:

sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

4.4 验证整条链路(自己动手试一把)

加固完别急着走,亲手验证一遍才安心:

  • 新开终端用 ssh -p 2222 admin@服务器IP 登录,确认密钥能进、密码不被问;
  • ssh root@服务器IP,应当直接被拒(Permission denied);
  • 从另一台机器故意连错几次密码,再跑 sudo fail2ban-client status sshd,看你的 IP 是否出现在 Banned IP list 里;
  • sudo ufw status numbered,确认只放行了 2222 / 80 / 443,没有 22 露在外面。

四步全过,说明三道防线都已就位。

防火墙的速率限制、连接数限制、Docker 容器如何绕过 ufw、以及被 DDoS 时防火墙能做什么——这些网络层进阶玩法我放在本系列第 2 篇《VPS 防火墙加固》里专门讲。本文聚焦登录层这道门,下面的小结帮你自检。

五、额外加固小贴士

  • 先放端口再改 SSH:这是锁死自己的头号原因,顺序永远是新端口放行 → 改 sshd_config → 测试新登录 → 最后才关旧会话。
  • 开自动安全更新:大多数入侵利用的是已公开的补丁漏洞,忘记更新是最常见的翻车原因。Debian/Ubuntu 可装 unattended-upgrades 自动打安全补丁。
  • AllowUsers 白名单:在 sshd_config 加 AllowUsers admin,只有列表里的用户能 SSH,就算机器人猜出别的用户名也进不来。
  • 改端口本身就能降噪:把 22 换成 2222 或 54321,日志里的爆破尝试能少一大半,Fail2ban 压力也小。
  • 定期备份:再硬的堡垒也可能出意外,快照 / 文件备份是你的最后防线。
  • 留好救援通道:确认商家面板有 VNC 或救援模式,真锁门外了还能进去改配置。

六、上线前自检清单

  • ✅ 新建了普通 sudo 用户,不再日常用 root;
  • ✅ 已用 ssh-keygen 生成密钥,并把公钥放进了服务器的 authorized_keys;
  • ✅ 已验证密钥能登录,再设置 PasswordAuthentication no 与 PermitRootLogin no;
  • ✅ SSH 端口已改高位端口,且防火墙已先放行该端口;
  • ✅ Fail2ban 已安装、sshd 监狱已启用,能查到封禁状态;
  • ✅ UFW 默认拒绝入站,只放行了 SSH / 80 / 443 等必要端口;
  • ✅ 商家面板保留 VNC / 救援通道,记下放行了哪些端口、用了哪个用户。

七、总结

VPS 安全不是玄学,就是三道门:SSH 只认密钥不认密码、Fail2ban 自动封爆破 IP、UFW 只开必要端口。这套组合拳成本为零、几分钟搞定,却能把 99% 的自动化攻击挡在门外。无论你在 RackNerdColoCrossingCloudconeVultrDMIT 还是 Bandwagon 买的机器,开箱第一件事请先把这三步做了——别等被黑了才后悔。安全是持续的事,装完环境也记得常更新、常看日志。