什么是 Fail2ban?
Fail2ban 是一个入侵防御软件框架,用于保护服务器免受暴力破解和其他自动化攻击。它通过监控系统日志(如 /var/log/auth.log, /var/log/nginx/error.log 等)来检测恶意行为,例如多次失败的登录尝试。一旦检测到异常,它会自动调用防火墙规则(如 iptables, nftables, firewalld 等)来封锁可疑的IP地址一段时间。
核心概念
Jail(监禁): 核心概念。一个“Jail”定义了一个应用场景,它指定了:
要监控什么日志 (logpath)
用什么规则来检测恶意行为 (filter)
检测到后执行什么动作 (action)
封禁多长时间 (bantime)
触发封禁的阈值 (maxretry, findtime)
Filter(过滤器): 包含一组正则表达式规则的文件(位于 /etc/fail2ban/filter.d/),用于解析日志文件并识别失败的尝试。例如 sshd, nginx-http-auth。
Action(动作): 定义当达到封禁条件时要执行的命令的文件(位于 /etc/fail2ban/action.d/)。通常是添加一条防火墙规则来封禁IP。动作也包括解封时的命令。
Jail.conf / Jail.local: 主配置文件。绝对不要直接修改 jail.conf,因为软件更新时会覆盖它。应该使用 jail.local 文件来覆盖默认设置。配置是分层级的:[DEFAULT] 段设置全局默认值,后面的 [jail-name] 段为特定服务设置。
第一部分:安装与基本使用
1. 安装 Fail2ban
在大多数 Linux 发行版上,安装都非常简单。
Ubuntu / Debian:
sudo apt update<br /> sudo apt install fail2banCentOS / RHEL / Fedora:
# CentOS/RHEL (需要EPEL仓库)<br /> sudo yum install epel-release<br /> sudo yum install fail2ban</p> <p># Fedora<br /> sudo dnf install fail2ban安装后,Fail2ban 会自动启动并启用开机自启。 您可以通过以下命令检查状态:
sudo systemctl status fail2ban2. 基本配置:创建 jail.local
复制默认的配置文件并进行自定义:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local用您喜欢的文本编辑器(如
nano,vim)打开jail.local:sudo nano /etc/fail2ban/jail.local3. 配置全局默认值 ([DEFAULT] 段)
在
[DEFAULT]部分,您可以设置所有Jail的默认值。以下是一些关键参数:[DEFAULT]<br /> # 忽略的IP地址范围(白名单),多个IP用空格分隔<br /> ignoreip = 127.0.0.1/8 192.168.1.0/24 123.45.67.89</p> <p># 封禁时间(秒)。负数表示“永久封禁”,请谨慎使用。<br /> bantime = 3600</p> <p># 时间窗口(秒),在此时间内达到最大重试次数则触发封禁。<br /> findtime = 600</p> <p># 最大重试次数。<br /> maxretry = 5</p> <p># 使用的防火墙后端(通常自动检测,无需修改)<br /> # banaction = iptables-multiport4. 启用和配置特定的 Jail
在
jail.local文件中,继续往下翻,您会看到很多预定义的 Jail(如[sshd],[apache-auth]),它们默认都是被注释(禁用)的。要启用一个 Jail,只需取消对应段的注释并将其
enabled选项设为true。示例 1:启用 SSH 保护(这是最常用的)
[sshd]<br /> enabled = true<br /> # 您还可以为此Jail单独设置参数来覆盖DEFAULT值<br /> port = ssh<br /> logpath = %(sshd_log)s<br /> maxretry = 3<br /> bantime = 86400 # 封禁24小时示例 2:启用 Nginx 认证保护(防止登录页面被爆破)
[nginx-http-auth]<br /> enabled = true<br /> port = http,https<br /> logpath = /var/log/nginx/error.log示例 3:启用 WordPress 保护(需要先配置 filter)
这需要额外的过滤器来匹配 WordPress 的登录尝试(通常是wp-login.php)。[wordpress]<br /> enabled = true<br /> port = http,https<br /> logpath = /var/log/nginx/*access.log # 或 Apache 的 access.log<br /> maxretry = 3注意:对于像 WordPress 这样的Web应用,确保您有对应的过滤器文件(
/etc/fail2ban/filter.d/wordpress.conf)。Fail2ban 默认可能不提供,需要自行创建或从社区获取。5. 重启 Fail2ban 以使配置生效
每次修改配置文件后,都需要重启服务:
sudo systemctl restart fail2ban第二部分:常用命令与管理
Fail2ban 提供了客户端工具
fail2ban-client来交互和管理。
查看状态: 查看所有启用的 Jail 及其状态。
sudo fail2ban-client status- 查看特定 Jail 的详细状态: 查看某个 Jail(如 sshd)封禁了哪些IP。
sudo fail2ban-client status sshd输出示例:
Status for the jail: sshd<br /> |- Filter<br /> | |- Currently failed: 1<br /> | |- Total failed: 15<br /> | `- File list: /var/log/auth.log<br /> `- Actions<br /> |- Currently banned: 2<br /> |- Total banned: 5<br /> `- Banned IP list: 123.45.67.89 101.102.103.104- 手动封禁一个IP:
sudo fail2ban-client set <jail-name> banip <ip-address><br /> # 示例<br /> sudo fail2ban-client set sshd banip 202.54.1.1- 手动解封一个IP:
sudo fail2ban-client set <jail-name> unbanip <ip-address><br /> # 示例<br /> sudo fail2ban-client set sshd unbanip 202.54.1.1- 解封所有IP:
sudo fail2ban-client set <jail-name> unban --all第三部分:高级配置与自定义
1. 自定义过滤器 (Filter)
有时默认的过滤器可能不匹配您的日志格式,您需要自定义。
例如,为自定义服务创建过滤器:
创建过滤器文件:
sudo nano /etc/fail2ban/filter.d/my-service.conf编写规则。一个简单的示例:
[Definition]<br /> failregex = ^.*Failed login from <HOST>.*$ # 这是一个示例,请根据您的实际日志编写正则表达式<br /> ignoreregex =<HOST> 是一个关键标签,用于匹配IP地址。- 在
jail.local中创建一个新的 Jail 来使用这个过滤器:[my-service]<br /> enabled = true<br /> port = 12345<br /> filter = my-service<br /> logpath = /var/log/my-service.log<br /> maxretry = 3调试过滤器:使用
fail2ban-regex工具测试您的过滤器是否正确。fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf2. 自定义动作 (Action)
您可以定义更复杂的动作,例如发送邮件通知或调用Webhook。
示例:封禁时发送邮件
确保系统安装了邮件工具(如
sendmail)。在
jail.local中修改动作:[sshd]<br /> enabled = true<br /> action = %(action_mwl)s # 默认动作是 iptables-multiport,`mwl` 表示 Mail Whois Lookup(发送邮件、whois查询、并记录)您也可以完全自定义:
action = iptables-multiport[name=SSH, port="ssh", protocol="tcp"]<br /> sendmail[name=SSH, dest="your-email@example.com", sender="fail2ban@yourserver.com"]3. 防止误封:使用 Ignoreip 和更精细的 Filter
务必使用
ignoreip将您自己的IP地址、局域网IP和其他可信IP加入白名单,以免不小心把自己锁在外面。第四部分:故障排除与日志
查看 Fail2ban 的日志:这是排查问题的第一站。
sudo tail -f /var/log/fail2ban.log- 检查防火墙规则:Fail2ban 通过操作防火墙规则工作,直接查看规则是确认它是否生效的好方法。
# 如果使用 iptables<br /> sudo iptables -L -n<br /> # 或者查看 f2b- 开头的链<br /> sudo iptables -L f2b-sshd -n- 确保日志路径正确:在 Jail 配置中指定的
logpath必须绝对正确。检查文件是否存在。总结
Fail2ban 是一个“设置后就不用管”的强大安全工具,但初始配置需要细心:
安装 Fail2ban。
创建
jail.local并配置全局[DEFAULT]设置(尤其是ignoreip!)。启用 您需要的 Jail(如
[sshd])。根据需要自定义 Filter 和 Action。
重启 Fail2ban 服务。
使用
fail2ban-client命令进行管理和监控。遇到问题时查看
/var/log/fail2ban.log。通过合理配置,Fail2ban 可以极大地提高服务器对自动化攻击的抵抗力,让您的系统更加安全。
配置方案实例
保护您的网站(日志文件为
/home/wwwlogs/www.123ppp.com.log)免受恶意IP的请求。默认的jail.conf提供了基础,默认配置是很好的参考,但直接修改它会被更新覆盖。正确的做法是创建jail.local来覆盖和添加自定义配置。我们需要自定义一个专属的Jail。创建一个新的Jail,并为其配置一个合适的过滤器(Filter)。以下是详细步骤:
第1步:创建或编辑
jail.local文件sudo nano /etc/fail2ban/jail.local第2步:写入以下配置内容
将下面的配置添加到您的
jail.local文件中。这段配置做了以下几件事:
在
[DEFAULT]部分设置了全局规则(如白名单IP、封禁时间等)。创建了一个名为
[nginx-bad-request]的新Jail(名字您可以自己定)来监控您的特定日志文件。[DEFAULT]<br /> ignoreip = 127.0.0.1/8 ::1<br /> bantime = 3600<br /> findtime = 600<br /> maxretry = 5<br /> banaction = iptables-multiport</p> <p># 更全面的基础防护网,它能捕捉到更多种类的异常行为<br /> [ip-range-monitor]<br /> enabled = true<br /> logpath = /home/wwwlogs/www.123ppp.com.log<br /> filter = nginx-ip-range<br /> maxretry = 100 # 提高触发阈值,允许更多的偶发性错误<br /> findtime = 600 # 延长统计时间窗口到10分钟,观察更长时间段的行为<br /> bantime = 1800 # 缩短首次封禁时间为30分钟,对于首次违规者惩罚稍轻<br /> bantime.increment = true # 启用增量封禁<br /> bantime.factor = 1.5 # 每次封禁时间乘以1.5倍<br /> bantime.maxtime = 604800 # 最长封禁时间:一周(7天*24小时*3600秒)<br /> bantime.rndtime = 600 # 添加一个随机时间(0-600秒),避免攻击者精确计算解封时间<br /> port = http,https<br /> banaction = iptables-ipset-proto6</p> <p># 更精准的强化防护,它专门针对已知的、特定类型的攻击手法,误报率极低<br /> [nginx-bad-request-range]<br /> enabled = true<br /> logpath = /home/wwwlogs/www.123ppp.com.log<br /> filter = nginx-bad-request<br /> maxretry = 5<br /> findtime = 180<br /> bantime = 3600<br /> bantime.increment = true<br /> bantime.factor = 2<br /> bantime.maxtime = 604800<br /> bantime.rndtime = 300 #在固定的封禁时间基础上,随机增加最多300秒(5分钟)的额外封禁时间<br /> port = http,https<br /> banaction = iptables-ipset-proto6 #必须确保系统已经安装并正确配置了 ipset 工具</p> <p># 封禁特定User-Agent,封禁这些特定的爬虫<br /> [nginx-bad-bots]<br /> enabled = true<br /> logpath = /home/wwwlogs/www.123ppp.com.log<br /> filter = nginx-bad-bots<br /> maxretry = 1 # 发现一次就封<br /> bantime = 604800 # 封禁一周<br /> port = http,https<br />对于
iptables-ipset-proto6的说明:
iptables-ipset-proto6是什么?这是一个
Fail2ban的动作(action),它定义了如何执行封禁。它的工作流程是:当需要封禁一个 IP 时,
Fail2ban不会直接创建一条iptables规则,而是会调用ipset工具,将这个 IP 添加到一个预定义的集合(set) 中。然后,只需要一条
iptables规则来匹配整个这个 IP 集合即可。这比传统为每个IP创建一条iptables规则的方式效率高几个数量级。为什么必须安装
ipset?这个动作(
action)的本质是一系列封装好的shell命令,其中核心命令就是/usr/sbin/ipset。如果系统里没有
ipset这个程序,Fail2ban尝试执行封禁时,就会在日志中看到类似ERROR - Failed to execute ban jail 'ip-range-monitor' action 'iptables-ipset-proto6'的错误,并且提示ipset命令未找到。
iptables-ipset-proto6和iptables-ipset的区别?
iptables-ipset-proto6:是iptables-ipset的增强版,同时支持 IPv4 和 IPv6。这是现代环境下的推荐选择。
iptables-ipset:通常只支持 IPv4。如果你的服务器不需要处理 IPv6 流量,两者都可以。但为了更好的兼容性,通常直接使用
iptables-ipset-proto6更省心。ipset的安装和验证
1. 安装 ipset
根据你的 Linux 发行版使用对应的包管理工具安装:# 对于 CentOS / RHEL / RockyLinux / AlmaLinux<br /> sudo yum install ipset<br /> # 或使用 dnf(新版本)<br /> sudo dnf install ipset</p> <p># 对于 Debian / Ubuntu<br /> sudo apt update<br /> sudo apt install ipset验证 ipset 是否安装成功
安装后,检查一下 ipset 命令是否可用:ipset --version如果显示出版本信息(如
v7.15),说明安装成功。3. 重启 Fail2ban 服务
安装完ipset后,最好重启Fail2ban服务以确保它能够正确识别和使用新的依赖。sudo systemctl restart fail2ban检查 Fail2ban 状态和日志
重启后,检查 Fail2ban 的状态和日志,确认没有报错:# 查看服务状态<br /> sudo systemctl status fail2ban</p> <p># 查看指定 jail 的状态<br /> sudo fail2ban-client status ip-range-monitor</p> <p># 查看 Fail2ban 日志(通常有最新错误信息)<br /> sudo tail -f /var/log/fail2ban.log如果日志中没有关于
ipset命令未找到的错误,并且 Jail 状态为Active,说明配置成功。
总结
配置项 依赖 后果 banaction = iptables-ipset-proto6必须安装 ipset未安装则封禁功能失效,Fail2ban 会报错。 banaction = iptables-multiport(默认)仅依赖 iptables系统通常预装,但性能不如 ipset。 结论:为了使用
iptables-ipset-proto6这个高性能的封禁动作,安装ipset是必要的前提条件。 安装过程非常简单,完成后能极大提升 Fail2ban 在应对大量攻击 IP 时的性能。第3步:创建自定义过滤器(Filter)
Fail2ban依靠过滤器文件中的正则表达式来识别日志中的恶意行为。我们需要为您的日志创建一个。
创建过滤器文件:
vim /etc/fail2ban/filter.d/nginx-bad-request.conf- 写入过滤规则。根据日志样例,写一个通用且有效的规则,用于更精准的强化防护,它专门针对已知的、特定类型的攻击手法,误报率极低。
[Definition]<br /> failregex = ^<HOST> -.*"(GET|POST|HEAD).*\.(php|asp|env).*HTTP.*"\s404\s.*$<br /> ^<HOST> -.*"(GET|POST|HEAD).*(\/wp-admin|\/admin).*HTTP.*"\s404\s.*$<br /> ^<HOST> -.*"(GET|POST|HEAD).*\/config\.php.*HTTP.*"\s404\s.*$<br /> ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*"\s(400|403|499)\s.*$<br /> ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*"\s(4[0-35-9]\d|50\d)\s.*$</p> <p>ignoreregex = \.(jpg|jpeg|png|gif|webp|css|js|ico|svg|woff2?|ttf|eot|otf)(\?.*)?\sHTTP.*\s404\s<br /> \/(robots\.txt|favicon\.ico)(\?.*)?\sHTTP.*\s404\s</p> <p>#下面注释掉的是:用!(非)的方式来限定某些ip段。先记上,以便需要时用。<br /> #ignoreregex = ^(?!34\.174\.|172\.70\.|172\.69\.|162\.158\.)<br />
注意<HOST>是一个关键标签,Fail2ban靠它来识别IP地址。再建另一个过滤器文件,它能更全面的基础防护网,它能捕捉到更多种类的异常行为
vim /etc/fail2ban/filter.d/nginx-ip-range.conf
[Definition]<br /> failregex = ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*"\s[4-5][0-9][0-9]\s.*$<br /> ignoreregex = .*\.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$.*\s404\s</p> <p>#下面注释掉的是:用!(非)的方式来限定某些ip段。先记上,以便需要时用。<br /> #ignoreregex = ^(?!34\.174\.|172\.70\.|172\.69\.|162\.158\.)<br />过滤器规则解释
这个配置专门针对以下几种恶意行为:
常见错误状态码:
(404|400|403|499)- 封禁产生大量"未找到"、"错误请求"、"禁止访问"等错误的IP。PHP文件探测:
\.php- 攻击者常尝试访问不存在的php文件来探测漏洞。ASP文件探测:
\.asp- 针对Windows服务器的探测。后台管理目录扫描:
\/wp-admin和\/admin- 尝试寻找网站后台入口。敏感文件扫描:
\/\.env和\/config\.php- 尝试获取配置文件。第4步:测试过滤器(非常重要!)
在重启Fail2ban之前,请务必测试您的过滤器是否能正确匹配日志中的恶意行。
sudo fail2ban-regex /home/wwwlogs/www.123ppp.com.log /etc/fail2ban/filter.d/nginx-bad-request.conf如果输出中显示有匹配的条目(如
Matched: 10),说明配置成功。如果显示0 matched,则需要调整您的failregex。
第5步:配置完成后,重启Fail2ban并检查状态,务必执行以下命令:
# 检查配置文件语法是否正确<br /> fail2ban-client -t</p> <p># 重载 Fail2ban 配置使其生效<br /> systemctl reload fail2ban</p> <p># 查看该 Jail 的状态,确认它已正常运行并监控日志,这个命令会显示该Jail目前已经封禁了哪些IP地址。<br /> fail2ban-client status ip-range-monitor总结与建议
不要修改默认的
jail.conf:始终在jail.local和/etc/fail2ban/filter.d/目录下进行自定义配置。核心是过滤器:上面的
failregex是一个通用规则。要获得最佳效果,您最好提供一段真实的恶意访问日志样例,这样可以编写出更精确的过滤规则。调试工具:
fail2ban-regex命令是您调试过滤器的最好朋友,一定要善用它。观察日志:配置完成后,可以实时查看Fail2ban的日志来观察封禁情况:
sudo tail -f /var/log/fail2ban.log高级技巧:封禁特定User-Agent
从日志中可以看到一些爬虫(如
SemrushBot,GPTBot)。如果您想封禁这些特定的爬虫,可以创建另一个过滤器:vim /etc/fail2ban/filter.d/nginx-bad-bots.conf内容:
[Definition]<br /> failregex = ^<HOST> -.*"GET.*HTTP.*".*"(.*(SemrushBot|GPTBot|AhrefsBot).*)"$<br />然后在
jail.local中启用它:[nginx-bad-bots]<br /> enabled = true<br /> logpath = /home/wwwlogs/www.123ppp.com.log<br /> filter = nginx-bad-bots<br /> maxretry = 1 # 发现一次就封<br /> bantime = 604800 # 封禁一周<br /> port = http,https最终建议
先测试再启用:使用
fail2ban-regex命令充分测试您的过滤器,确保不会误封正常用户。逐步调整:开始时可以设置较短的封禁时间(如1小时),观察效果后再调整。
监控日志:封禁后查看
/var/log/fail2ban.log确认效果。这个配置将能有效防御日志中显示的各种扫描器和恶意爬虫,显著提升您的网站安全性。
补充资料
使用 ignoreip 参数让来自搜索引擎官方IP的请求不被封禁
操作步骤:
1. 获取搜索引擎官方IP段
您需要找到Google、Bing、Baidu等搜索引擎公布的爬虫IP地址段。这需要定期维护更新。Googlebot: 来自 https://developers.google.com/search/apis/ipranges/googlebot.json 或执行 nslookup -type=PTR googlebot.com 并反向解析您日志中看到的Googlebot IP。
Bingbot: 官方文档或通过 nslookup search.msn.com 等方式获取。
Baiduspider: 官方公布或通过日志分析。
2. 将IP段添加到Jail配置的 ignoreip 中
编辑您的 Jail 配置文件(/etc/fail2ban/jail.local):
[ip-range-monitor]<br /> enabled = true<br /> logpath = /home/wwwlogs/www.123ppp.com.log<br /> filter = nginx-ip-range<br /> maxretry = 30<br /> findtime = 300<br /> bantime = 3600<br /> port = http,https<br /> banaction = iptables-ipset-proto6</p> <p># 正确的方式:在这里添加IP白名单<br /> ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24<br /> # 添加搜索引擎IP段示例(请替换为真实的最新IP段)<br /> ignoreip = 66.249.64.0/19 66.249.80.0/20 # Googlebot<br /> ignoreip = 157.55.0.0/16 199.30.27.0/24 # Bingbot<br /> ignoreip = 119.63.192.0/21 180.76.0.0/16 # Baiduspider<br /> # ... 可以继续添加其他引擎的IP段
声明:本文为原创文章,版权归旷野小站所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ BZ-web前端全套视频教程-笔记课件齐全【A00656】05/11
- ♥ LNMP一键安装包自动备份工具的使用04/15
- ♥ lsyncd.conf 配置的详细实例02/25
- ♥ php语言教程学习笔记08/01
- ♥ 实现网站一个目录内的网页跳转到另一个目录的方法06/21
- ♥ Nginx连接与请求速率限制详解10/03