Fail2Ban进阶:自定义规则、多服务监控与邮件告警配置实战
# Fail2Ban的“内功心法”:Filter, Action, Jail三位一体
在咱们开始“传功”之前,得先简单了解一下Fail2Ban这位“高手”的“武功构成”,它主要由这三部分组成:
- **过滤器 (Filters - 存放在 `/etc/fail2ban/filter.d/` 目录):** 这就像是“保安大叔”的“可疑行为识别手册”。每个Filter文件里都定义了一堆正则表达式(`failregex`),用来从特定的日志文件中匹配那些“鬼鬼祟祟”的行为,比如登录失败、访问不存在的页面、或者尝试进行注入攻击的日志条目。它还能识别出“肇事者”的IP地址(通过`<HOST>`标签)。
- **动作 (Actions - 存放在 `/etc/fail2ban/action.d/` 目录):** 这是“保安大叔”抓到坏人后要执行的“处置方案”。比如,最常见的动作就是用`iptables`或`nftables`(Linux防火墙工具)把“肇事IP”给封禁一段时间,不让它再来捣乱。高级点的动作还可以配置成发送邮件通知管理员。
- **监狱 (Jails - 在 `jail.conf` 或 `jail.local` 及 `jail.d/` 目录下定义):** 这就是“具体执行方案”了!一个Jail把一个或多个Filter(识别什么行为)、一个或多个Action(采取什么措施)、以及其他参数(比如尝试多少次算违规`maxretry`、在多长时间内尝试算违规`findtime`、封禁多久`bantime`、监控哪个日志文件`logpath`等)给有机地结合起来,针对特定的服务(如SSH、Nginx的某个认证页面等)进行防护。
**黄金法则:** 永远不要直接修改`jail.conf`!所有的自定义配置和对默认配置的覆盖,都应该写在`jail.local`文件里,或者在`/etc/fail2ban/jail.d/`目录下创建以`.local`或`.conf`结尾的单独配置文件(比如`mycustomjails.local`)。这样,将来Fail2Ban升级时,你的自定义配置才不会被覆盖掉。
## 第一式:打造专属“识别手册”——自定义Filter
Fail2Ban自带了很多常用服务的Filter,但如果你的Web应用有自定义的登录接口,或者你想监控某个特殊应用产生的、具有特定格式的错误日志,那就需要咱们亲自出马,为Fail2Ban量身打造一个新的Filter了。
**场景假设:** 假设你有一个Web应用,它的登录失败日志记录在`/var/log/mywebapp/auth.log`文件中,格式如下:
[2025-05-27 10:20:30] WARN: Login failed for user 'testuser', remote IP: 11.22.33.44
[2025-05-27 10:21:05] WARN: Login failed for user 'admin', remote IP: 55.66.77.88
咱们的目标就是抓住那个`remote IP:`后面的IP地址。
### 步骤1:编写正则表达式 (`failregex`)
正则表达式是这里的核心。你需要写一个能精确匹配到上述日志中“登录失败”那一行,并且能提取出IP地址的表达式。对于我们的例子,一个可行的`failregex`是:
^[.] WARN: Login failed for user '.', remote IP: <HOST>$
- `^`:匹配行首。
- `\[.*\] WARN: Login failed for user '.*', remote IP: `:这部分是固定文本和通配符的组合,`.*`匹配任意字符任意次数。
- **`<HOST>`**:这是Fail2Ban的特殊标签,它会自动匹配并捕获IP地址或主机名。
- `$`:匹配行尾(可选,但通常加上更精确)。
### 步骤2:创建Filter配置文件
在`/etc/fail2ban/filter.d/`目录下创建一个新的Filter文件,比如叫`mywebapp-auth.conf`:
```cobol
vim /etc/fail2ban/filter.d/mywebapp-auth.conf
写入以下内容:
[Definition]
# 正则表达式,用于匹配日志中的失败尝试
failregex = ^\[.*\] WARN: Login failed for user '.*', remote IP: <HOST>$
# 可选:忽略某些正则表达式匹配的行 (比如,你想忽略某个特定测试用户的失败尝试)
# ignoreregex = ^\[.*\] WARN: Login failed for user 'test_ignore_user', remote IP: <HOST>$
步骤3:测试你的新Filter
在把Filter投入实战之前,先用fail2ban-regex工具测试一下它是否能正常工作,就像给新兵器“开刃”试锋:
fail2ban-regex /var/log/mywebapp/auth.log /etc/fail2ban/filter.d/mywebapp-auth.conf
这条命令会用你的Filter去扫描指定的日志文件。观察输出结果,确保:
- “Lines missed” (未匹配的行) 数量合理。
- “Lines matched” (匹配的行) 中,你的
failregex确实抓到了预期的日志条目。 - “Matched view” (匹配详情) 中,被
<HOST>标签捕获到的IP地址是正确的。
如果一切正常,恭喜你,你的专属“识别手册”打造完毕!
第二式:设立新“监狱”——激活自定义Jail
有了Filter,接下来就要在jail.local文件(或者/etc/fail2ban/jail.d/下的自定义文件)里为它设立一个“监狱”(Jail),告诉Fail2Ban具体怎么使用这个Filter来保护你的应用。
打开(或创建)/etc/fail2ban/jail.local文件:
vim /etc/fail2ban/jail.local
在文件末尾(或者任何你觉得合适的地方,但通常我们把自定义的Jail放在一起)添加以下内容:
[mywebapp-auth]
# 是否启用这个Jail
enabled = true
# 应用的端口 (如果你的Web应用跑在标准HTTP/HTTPS端口)
# 如果是其他端口,请相应修改
port = http,https
# 使用哪个Filter (文件名,不带.conf后缀)
filter = mywebapp-auth
# 监控哪个日志文件
logpath = /var/log/mywebapp/auth.log
# 在多长时间内 (findtime,单位秒)
findtime = 600 # 10分钟
# 达到多少次失败尝试 (maxretry)
maxretry = 5 # 5次
# 就封禁多长时间 (bantime,单位秒)
bantime = 3600 # 1小时
# 使用哪个动作 (下面会详细说邮件告警)
# %(action_)s 是一个变量,代表默认的 banning action (比如 iptables-multiport)
# %(action_mwl)s 代表 action_mail-whois-lines,即:封禁 + 发邮件(带whois信息和相关日志行)
action = %(action_mwl)s
这里的参数都很好理解:当Fail2Ban在/var/log/mywebapp/auth.log文件中,通过mywebapp-auth这个Filter,在10分钟(findtime)内发现了同一个IP地址有5次(maxretry)登录失败记录,那么这个IP就会被封禁1小时(bantime),并且会触发邮件通知(因为我们用了action_mwl)。
配置完成后,保存文件,然后重载Fail2Ban使其生效:
fail2ban-client reload
# 或者
systemctl reload fail2ban
检查一下新Jail的状态:
fail2ban-client status mywebapp-auth
如果一切顺利,你应该能看到这个Jail已经成功启动并开始监控了!
第三式:火眼金睛观八方——监控多个日志文件或服务
有时候,同一个服务可能会把日志写到多个文件里(比如按日期轮转的日志),或者你想用同一个Filter和Action策略去监控分布在不同路径下的、行为模式类似的日志。
在Jail配置中,logpath参数其实可以接受多个路径,每行一个:
[my-multi-log-jail]
enabled = true
filter = my-common-filter
logpath = /var/log/app1/error.log
/var/log/app2/error.log
/srv/app3/logs/special_error.log
# ...其他参数如maxretry, bantime, action等
这样,Fail2Ban就会同时监控这三个日志文件,只要任何一个文件中的日志触发了my-common-filter的规则,都会计入这个Jail的maxretry计数。
如果你有多个Web应用跑在不同的虚拟主机上,但它们都可能受到同一种类型的攻击(比如XML-RPC攻击WordPress),你也可以为每个虚拟主机的日志文件分别创建一个Jail,或者用更巧妙的方式(比如让所有虚拟主机的相关错误日志都汇总到一个特定日志,或者用更复杂的Filter)来处理。关键在于灵活运用Filter和Jail的组合。
第四式:“飞鸽传书”报军情——配置邮件告警
IP被封了当然好,但如果管理员能第一时间收到通知,知道“哦,有人在搞事情,已经被Fail2Ban挡回去了”,那岂不是更安心?Fail2Ban的邮件告警功能就能满足你这个需求。
步骤1:配置全局邮件参数
在jail.local文件的[DEFAULT]部分(或者你也可以为特定的Jail单独配置),设置邮件发送相关的参数:
[DEFAULT]
# ...其他默认参数...
# 接收告警邮件的地址 (改成你自己的邮箱)
destemail = admin@example.com
# 发件人名称
sendername = Fail2Ban Alerts on MyServer
# 发件人邮箱地址 (确保这个地址是有效的,或者你的邮件服务器允许以此地址发信)
sender = fail2ban@myserver.example.com
# 使用的邮件发送程序 (Mail Transfer Agent, MTA)
# 可选值通常有 sendmail, mail, postfix 等,取决于你服务器上安装和配置的MTA
# 如果不确定,可以先试试 sendmail 或 mail
mta = mail
重要: 要想让Fail2Ban成功发送邮件,你的服务器上必须已经安装并正确配置了一个MTA(邮件传输代理),比如Postfix, Sendmail, Exim等,并且这台服务器有能力向外发送邮件(比如相关的防火墙端口已打开,没有被ISP阻止等)。这就像你的“保安大叔”得有个能用的“对讲机”或“电话”才能联系到你。
在这里建议使用mail,也就是mailx,新版本是s-nail,使用这个只需要在其配置文件:~/.mailrc里配上有关参数信息即可
步骤2:在Jail中选择包含邮件功能的Action
Fail2Ban的Action是模块化的。很多Action本身就包含了发送邮件的功能。我们在前面自定义Jail的例子中用到的action = %(action_mwl)s 就是一个很好的例子。这里的mwl代表:
m: Mail (发送邮件通知)w: Whois (邮件内容包含对被封IP的Whois查询信息)l: Lines (邮件内容包含触发封禁的相关日志行)
你可以在/etc/fail2ban/action.d/目录下找到各种预定义的action配置文件(比如iptables-mwl.conf),看看它们具体做了些什么。常见的包含邮件功能的action变量有:
%(action_m)s: 只发送邮件,不带Whois和日志。%(action_mw)s: 邮件 + Whois。%(action_ml)s: 邮件 + 日志行。%(action_mwl)s: 邮件 + Whois + 日志行。
选择一个你喜欢的,配置到你的Jail的action参数里就行。
步骤3:测试邮件发送
- 确保你已经正确配置了
destemail,sender,mta。 - 确保你选择的Jail(比如我们前面创建的
[mywebapp-auth])的action参数指向了一个包含邮件功能的动作。 - 为了方便测试,可以临时把这个Jail的
maxretry改得小一点(比如1或2),bantime改得短一点(比如60秒)。 - 重载Fail2Ban配置:
fail2ban-client reload。 - 从一个与服务器不同的IP地址(比如你的手机开热点),故意触发几次你自定义Filter会匹配的失败行为(比如多次尝试用错误密码登录你的Web应用)。
- 观察服务器上的Fail2Ban日志 (
/var/log/fail2ban.log),看看是否有IP被封禁的记录,以及是否有尝试发送邮件的记录。 - 检查你的
destemail邮箱,看看是否收到了来自Fail2Ban的告警邮件。
如果没收到邮件,检查:
- 你的MTA服务是否正常运行?
- 查看MTA的日志(比如Postfix的
/var/log/mail.log或/var/log/maillog),看看是否有发送失败的错误信息(比如发件人地址无效、被目标邮件服务器拒收等)。 - Fail2Ban的日志里是否有关于邮件发送失败的提示。
锦囊妙计:Fail2Ban进阶使用小贴士
- 白名单很重要: 在
jail.local的[DEFAULT]部分,用ignoreip参数把你自己的固定IP地址、办公室IP、或者其他可信的IP地址段加入白名单,防止自己被误封。比如:ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 your.home.static.ip(多个ip中间用空格分开)。 - Ban Action的选择: Fail2Ban默认的ban action通常是
iptables-multiport。如果你的系统使用nftables,或者你是云服务器用户(比如AWS EC2),可以考虑使用更适合你环境的ban action(比如nftables-multiport.conf,或者针对云平台的API进行封禁的action,但这通常需要额外配置)(默认使用fiewalld)。 - 不要期望一劳永逸: Fail2Ban是个很棒的辅助工具,但它不是万能的。它主要防范的是那些“无脑”的、基于日志特征的暴力破解和扫描行为。对于更高级的、更隐蔽的攻击,你还需要其他安全措施(比如强密码策略、SSH密钥登录、定期更新补丁、WAF、IDS/IPS等)。安全是个“木桶原理”。
- 定期“体检”: 偶尔用
fail2ban-client status看看各个Jail的运行情况,以及被封禁的IP列表,了解一下你的服务器都在遭遇哪些类型的“骚扰”。

浙公网安备 33010602011771号