暴力破解挡不住?fail2ban自动封禁IP实战

暴力破解挡不住?fail2ban自动封禁IP实战

你改了SSH端口,关了root登录,用了密钥。觉得自己服务器固若金汤了。

去翻一下/var/log/auth.log或者/var/log/secure。你可能看到类似这样的内容:

text

Failed password for root from 221.231.xxx.xxx port 12345 ssh2
Failed password for root from 185.191.xxx.xxx port 54321 ssh2
Failed password for invalid user admin from 193.xxx.xxx.xxx

一天几千条。有人在不停地试你服务器的密码。

你心想:反正我不用密码登录,让他们试去。

但每试一次,你的服务器就要处理一次,日志要写一条,CPU要动一下。几千次下来,也是负担。而且他们不只是试SSH,还试你的网站后台、邮箱端口、数据库端口。

能不能让服务器学会“这个人试了三次,直接拉黑”?

能。fail2ban就是干这个的。


先看一个场景

去年一个朋友的服务器,被扫了三个月。他以为没事。有一天他发现服务器特别慢,上去一看,/var/log分区满了。几十GB的日志,全是“Failed password”。

他问我怎么办。我说你早该装fail2ban。装上之后,日志里的失败尝试从每天几千条降到几十条。他说:“原来它可以自己动手,不用我每周末手动封IP。”


fail2ban是什么?

fail2ban是一个日志监控工具。它会扫你的日志文件,找到那些反复失败的登录尝试,然后用防火墙把来源IP封掉一段时间。

它能保护的服务不止SSH。Nginx日志里的404扫描、WordPress登录页面被暴力破解、Postfix的垃圾邮件尝试——都可以用fail2ban来防。

简单说:你配好规则,剩下的事情它帮你做。


安装fail2ban

Ubuntu/Debian:

bash

sudo apt update
sudo apt install fail2ban -y

CentOS/RHEL:

bash

sudo yum install epel-release -y
sudo yum install fail2ban -y

安装完成后,服务会自动启动。查看状态:

bash

sudo systemctl status fail2ban

启用开机自启:

bash

sudo systemctl enable fail2ban

基础配置

fail2ban的配置文件分两部分:

  • /etc/fail2ban/jail.conf:默认配置,不要直接改这个文件,升级会被覆盖
  • /etc/fail2ban/jail.local:自定义配置,优先级更高

创建jail.local

bash

sudo vim /etc/fail2ban/jail.local

写入基础配置:

ini

[DEFAULT]
# 封禁时间(秒)。3600 = 1小时
bantime = 3600

# 在多少秒内进行检查
findtime = 600

# 允许失败的次数
maxretry = 3

# 封禁使用的防火墙工具
banaction = iptables-multiport

# 忽略的IP(白名单)
ignoreip = 127.0.0.1/8 192.168.1.0/24

这段配置的意思是:在600秒(10分钟)内,如果某个IP失败3次,就把它封1小时。你自己的内网IP和本机不会受影响。


配置SSH防护

fail2ban自带了很多服务的规则,在/etc/fail2ban/jail.d/目录下。SSH的规则默认是禁用的。

jail.local里添加:

ini

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

如果你的SSH端口改过(比如改成了2222),需要指定端口:

ini

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

重启fail2ban使配置生效:

bash

sudo systemctl restart fail2ban

测试是否生效

用另一台机器,或者你自己的电脑,连上服务器,输几次错误密码。

三次之后,再尝试连接。应该会卡住或超时,说明你的IP被封了。

查看封禁状态:

bash

sudo fail2ban-client status sshd

输出类似:

text

Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed: 3
|  `- File list: /var/log/auth.log
`- Actions
   |- Currently banned: 1
   |- Total banned: 1
   `- Banned IP list: 192.168.1.100

解封自己的IP:

bash

sudo fail2ban-client set sshd unbanip 192.168.1.100

配置Web应用防护

fail2ban不仅可以保护SSH,还可以保护你的网站。

场景1:Nginx日志里的404扫描

某些扫描器会在你网站上找/admin.php/wp-login.php/phpmyadmin,找不到就404。频繁的404说明有人在探测。

创建/etc/fail2ban/filter.d/nginx-404.conf

ini

[Definition]
failregex = ^<HOST> -.* "(GET|POST).*" 404 .*$
ignoreregex =

jail.local里添加:

ini

[nginx-404]
enabled = true
port = http,https
filter = nginx-404
logpath = /var/log/nginx/access.log
maxretry = 10
bantime = 3600

意思是:10分钟内出现10次404,封1小时。

场景2:WordPress登录防护

WordPress登录页面经常被暴力破解。fail2ban可以配合Nginx日志来防护。

jail.local里添加:

ini

[wordpress]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/nginx/access.log
maxretry = 5

但这个需要先创建filter文件。网上有很多现成的规则,直接搜索就能找到。


常用管理命令

命令说明
fail2ban-client status查看所有启用的jail
fail2ban-client status sshd查看某个jail的详细信息
fail2ban-client set sshd banip 1.2.3.4手动封一个IP
fail2ban-client set sshd unbanip 1.2.3.4解封IP
fail2ban-client reload重新加载配置
tail -f /var/log/fail2ban.log查看fail2ban自己的日志

生产环境建议

1. 别把自己封出去

ignoreip里加上你的办公网络IP、跳板机IP。否则你输错三次密码,自己也被关外面了。

2. 封禁时间不要过长

新手容易把bantime设成一周甚至永久。没必要。大多数扫描器是自动化的,封1小时它们就换IP了,设太久只会影响正常用户。

3. 先测试再上线

改完配置后,sudo fail2ban-client reload,然后用另一台机器测试封禁是否正常。

4. 别只看SSH

如果跑着网站,建议把Nginx的几个常见扫描也加上。攻击者可能不扫SSH,专门扫你的网站漏洞。


一个真实案例

有个做外贸的网站,每天被扫后台登录页面。他装了WordPress,后台地址没改,攻击者拿着常见密码字典一天试几千次。

虽然没有试成功,但服务器CPU一直很高。

我帮他配了fail2ban,监控/wp-login.php的访问日志。同一个IP试3次,封1小时。一周后,日志里的失败尝试减少了95%。

他说:“早知道有这个,我几个月前就装了。”


最后一句

fail2ban是你服务器的自动保安。你不用每天翻日志、手动封IP。它替你盯着,发现可疑行为就动手。

安装10分钟,配置10分钟,之后基本不用管。你的服务器日志会告诉你它每天都干了什么。

去看看/var/log/fail2ban.log,你会看到它替你挡住了多少麻烦。

知识库

一行命令启动所有服务:Docker Compose 实战入门

2026-4-29 15:34:29

知识库

[MySQL排查] "Too many connections" 错误?数据库最大连接数满了怎么办及优化

2025-5-16 11:10:09

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧