Fail2ban概念、安装与配置
只想知道配置哪些东西可以直接跳到覆盖默认配置
Fail2ban
Github仓库地址:Fail2ban
Fail2ban是使用python编写的自动检测非法访问并进行封禁的开源工具。
Fail2ban按照一个服务一个jail(监狱),每个监狱负责监控一个服务对应的文件(如ssh登录日志、nginx访问日志等),
按指定规则(过滤器)从监控的文件中提取失败的事件(如ssh密码错误,用户名不存在,nginx的404,401)和对应ip,对达到最大失败次数的ip执行封禁动作(action)。
不仅仅是ip,也可以是用户名、UUID或其他标识物,封禁动作也不仅仅是通过防火墙封禁ip,也可以通过执行命令封禁用户名。
sshd服务的jail:
配置文件说明
所有配置文件存放目录为/etc/fail2ban,配置文件为ini语法,详细语法和配置说明可参考:manpage jail.conf [en],安装软件后会在/etc/fail2ban/下生成一些默认配置和目录:
action.d: 存放所有action的目录fail2ban.conf:fail2ban的软件配置fail2ban.d: fail2ban的软件额外配置filter.d: 存放所有过滤规则filter的目录jail.conf: 全局jail配置jail.d:存放其他jail配置的目录paths-common.conf:一些预定义变量,在jail.conf中被导入paths-fedora.conf:一些预定义变量,在jail.conf中被导入
fail2ban自身的配置文件为/etc/fail2ban/fail2ban.conf,一般不改,可以在这里配置fail2ban自身的loglevel和日志路径(默认/var/log/fail2ban.log)。
日志
/var/log/fail2ban.log可以分析fail2ban对ip的封禁情况。
jail配置解析顺序为:
/etc/fail2ban/jail.conf/etc/fail2ban/jail.d/*.conf/etc/fail2ban/jail.local/etc/fail2ban/jail.d/*.local
后解析的配置会覆盖先解析的配置,相当于/etc/fail2ban/jail.d/*.local文件具有最高优先级。
因此一般情况下在/etc/fail2ban/jail.d目录中编写xxx.local指定某个jail的配置。
Fail2ban安装与配置
安装:sudo yum install fail2ban
/etc/fail2ban/jail.conf为全局监狱(jail)文件
文件中有如下定义:
1 | 38 # The DEFAULT allows a global definition of the options. They can be overridden |
[DEFAULT]节表示后面的属性是所有jail的默认配置,其中enabled = false表示所有jail默认是不启用的。
不建议修改此文件,更新fail2ban时可能会覆盖此文件。
正确的配置方法是在/etc/fail2ban/jail.local中配置jail的默认参数,
在/etc/fail2ban/jail.d/中分别为每个jail配置参数。
覆盖默认配置
创建文件/etc/fail2ban/jail.local并写入配置:
1 | [DEFAULT] |
设置所有jail默认配置为60秒内触发3次失败后封禁1天.
配置说明
[DEFAULT]表示后面的参数是所有jail的默认配置
bantime为ip的封禁时间,默认单位为秒,可以使用y,mo,w,d,h,m,s分别表示年月周日时分秒,以下为一些示例:
bantime = 300: 封禁300秒bantime = 30d: 封禁30天bantime = 6mo: 封禁6个月bantime = 1y6mo: 封禁1年加6个月bantime = 1y6mo12h: 封禁1年加6个月加12小时
findtime: 统计时间窗口,需要和maxretry结合使用,在findtime的时间内达到maxretry的最大失败次数时触发封禁,语法同bantime
maxretry: 最大失败次数
添加自定义配置
添加ssh保护和nginx扫描保护。
sshd防爆破
在/etc/fail2ban/jail.d/添加文件sshd.local,输入内容:
1 | [sshd] ; jail的名称 |
sshd的jail在全局默认配置文件/etc/fail2ban/jail.conf已定义,这里只需要使能并按需添加自定义。
添加或修改配置后需要重启fail2ban:
sudo systemctl restart fail2ban
nginx防扫描
封禁大量扫描*.php、.env、.vscode的ip,例如这些:
1 | 45.148.10.42 - - [04/May/2025:14:44:11 +0800] "GET /backup/.git/config HTTP/1.1" 404 597 "-" "l9explore/1.2.2" |
添加过滤器配置:
在/etc/fail2ban/filter.d/添加文件nginx-scan.conf,输入内容:
1 | # Fail2Ban filter to match web requests for HTTP code 4xx |
添加 jail 配置:
在/etc/fail2ban/jail.d/添加文件nginx-scan.local,输入内容:
1 | [nginx-scan] |
logpath = /var/www/logs/*.log需要换成你要监听的log文件路径,可以使用通配符*
添加或修改配置后需要重启fail2ban:
sudo systemctl restart fail2ban
nginx 禁止指定爬虫(可选)
根据nginx访问日志发现有大量爬虫和ai-bot访问网站,但是Baiduspider和Applebot在没有读取到robot.txt时爬了我的网站,而其他爬虫没有,
因此我认为这两只爬虫是坏蛋!给他ban了
提示:直接在nginx中ban掉爬虫
可以直接在/etc/nginx/nginx.conf中的http域中添加如下代码屏蔽指定爬虫:
1 | if ($http_user_agent ~* (Baiduspider|Applebot)) { |
添加过滤器规则/etc/fail2ban/filter.d/nginx-bad-bot.conf:
1 | # Ban spiders |
添加jail规则/etc/fail2ban/jail.d/nginx-bad-bot.local:
1 | [nginx-bad-bot] |
一定要将logpath = /var/www/logs/*xyz.log的日志文件改成你需要监听的文件。
强制断开连接
对于nginx的http/https的tcp连接,由于触发封禁只是对之后建立的tcp链接有效,在封禁前建立的连接仍能够继续,就像下面这样
,一个ip被封禁后短时间内仍能够继续访问。
1 | 2026-04-10 08:42:09,777 fail2ban.filter [19482]: INFO [nginx-scan] Found 20.205.1.146 - 2026-04-10 08:42:09 |
因此在ban ip时需要强制断开当前已建立的连接。
注意:以下修改仅对firewalld规则有效,其他防火墙未尝试过。如果使用iptables或ufw等其他防火墙则应去对应的action文件中修改。
打开文件/etc/fail2ban/action.d/firewallcmd-rich-rules.conf,找到actionban定义:
1 | actionban = ports="$(echo '<port>' | sed s/:/-/g)"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="%(fwcmd_rich_rule)s";%(force-break)s; done |
替换为:
1 | # 强制断开连接命令 |
解释:actionban变量是实际上ban某个ip时执行的命令,firewall-cmd --add-rich-rule就是添加防火墙规则拒绝某个ip的连接,在firewall-cmd --add-rich-rule之后添加命令conntrack -D -p tcp -s <ip> --state ESTABLISHED || true,使用conntrack强制移除已建立的tcp连接信息。
conntrack是一个连接跟踪工具,实际上是一个内核模块 nf_conntrack ,可以使用命令 lsmod | grep nf_conntrack 来检查内核模块是否加载或使用conntrack -L -p tcp看能否正常列出当前已建立的tcp连接。
验证
如果改了配置,需要重启fail2ban:
sudo systemctl restart fail2ban
使用ssh命令重复多次输入错误密码,可在/var/log/fail2ban.log看到新的ip触发ban,并且ssh无法连接上时表示配置成功