只想知道配置哪些东西可以直接跳到覆盖默认配置

Fail2ban

Github仓库地址:Fail2ban

Fail2ban是使用python编写的自动检测非法访问并进行封禁的开源工具。

Fail2ban按照一个服务一个jail(监狱),每个监狱负责监控一个服务对应的文件(如ssh登录日志、nginx访问日志等),
按指定规则(过滤器)从监控的文件中提取失败的事件(如ssh密码错误,用户名不存在,nginx的404,401)和对应ip,对达到最大失败次数的ip执行封禁动作(action)。

不仅仅是ip,也可以是用户名、UUID或其他标识物,封禁动作也不仅仅是通过防火墙封禁ip,也可以通过执行命令封禁用户名。

sshd服务的jail:

fail2ban

配置文件说明

所有配置文件存放目录为/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配置解析顺序为:

  1. /etc/fail2ban/jail.conf
  2. /etc/fail2ban/jail.d/*.conf
  3. /etc/fail2ban/jail.local
  4. /etc/fail2ban/jail.d/*.local

后解析的配置会覆盖先解析的配置,相当于/etc/fail2ban/jail.d/*.local文件具有最高优先级。

因此一般情况下在/etc/fail2ban/jail.d目录中编写xxx.local指定某个jail的配置。

Fail2ban安装与配置

安装:sudo yum install fail2ban

Note

/etc/fail2ban/jail.conf为全局监狱(jail)文件

文件中有如下定义:

1
2
3
4
5
6
7
8
9
10
11
 38 # The DEFAULT allows a global definition of the options. They can be overridden
39 # in each jail afterwards.
41 [DEFAULT]
...
152 # "enabled" enables the jails.
153 # By default all jails are disabled, and it should stay this way.
154 # Enable only relevant to your setup jails in your .local or jail.d/*.conf
155 #
156 # true: jail will be enabled and log files will get monitored for changes
157 # false: jail is not enabled
158 enabled = false

[DEFAULT]节表示后面的属性是所有jail的默认配置,其中enabled = false表示所有jail默认是不启用的。

不建议修改此文件,更新fail2ban时可能会覆盖此文件。

正确的配置方法是在/etc/fail2ban/jail.local中配置jail的默认参数,
/etc/fail2ban/jail.d/中分别为每个jail配置参数。

覆盖默认配置

创建文件/etc/fail2ban/jail.local并写入配置:

1
2
3
4
[DEFAULT]
bantime = 1d
maxretry = 3
findtime = 60

设置所有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
2
3
4
[sshd] ; jail的名称
mode = normal
enabled = true ; 启用sshd jail
port = 12345 ; 默认端口号为22,如果你使用其他端口号如12345,在这里修改

sshd的jail在全局默认配置文件/etc/fail2ban/jail.conf已定义,这里只需要使能并按需添加自定义。

添加或修改配置后需要重启fail2ban:sudo systemctl restart fail2ban

nginx防扫描

封禁大量扫描*.php.env.vscode的ip,例如这些:

hider
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
45.148.10.42 - - [04/May/2025:14:44:11 +0800] "GET /backup/.git/config HTTP/1.1" 404 597 "-" "l9explore/1.2.2"
45.148.10.42 - - [04/May/2025:14:44:12 +0800] "GET /core/.git/config HTTP/1.1" 404 597 "-" "l9explore/1.2.2"
45.148.10.42 - - [04/May/2025:14:44:13 +0800] "GET /server/.git/config HTTP/1.1" 404 597 "-" "l9explore/1.2.2"
45.148.10.42 - - [04/May/2025:14:44:14 +0800] "GET /admin/.git/config HTTP/1.1" 404 597 "-" "l9explore/1.2.2"
45.148.10.42 - - [04/May/2025:14:44:15 +0800] "GET /.env.backup HTTP/1.1" 404 597 "-" "l9explore/1.2.2"
45.148.10.42 - - [04/May/2025:14:44:15 +0800] "GET /.env.save HTTP/1.1" 404 597 "-" "l9explore/1.2.2"
45.148.10.42 - - [04/May/2025:14:44:16 +0800] "GET /config/.env HTTP/1.1" 404 597 "-" "l9explore/1.2.2"
45.148.10.42 - - [04/May/2025:14:44:17 +0800] "GET /.env.test HTTP/1.1" 404 597 "-" "l9explore/1.2.2"
45.148.10.42 - - [04/May/2025:14:44:18 +0800] "GET /.env.live HTTP/1.1" 404 597 "-" "l9explore/1.2.2"
104.41.205.21 - - [04/Sep/2025:08:48:34 +0800] "GET /class20.php HTTP/1.1" 404 1834 "-" "-"
104.41.205.21 - - [04/Sep/2025:08:48:34 +0800] "GET /ol.php HTTP/1.1" 404 1834 "-" "-"
104.41.205.21 - - [04/Sep/2025:08:48:35 +0800] "GET /wp-gr.php HTTP/1.1" 404 1834 "-" "-"
104.41.205.21 - - [04/Sep/2025:08:48:35 +0800] "GET /pp.php HTTP/1.1" 404 1834 "-" "-"
104.41.205.21 - - [04/Sep/2025:08:48:36 +0800] "GET /error.php HTTP/1.1" 404 1834 "-" "-"
104.41.205.21 - - [04/Sep/2025:08:48:36 +0800] "GET /axx.php HTTP/1.1" 404 1834 "-" "-"

添加过滤器配置:
/etc/fail2ban/filter.d/添加文件nginx-scan.conf,输入内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Fail2Ban filter to match web requests for HTTP code 4xx
#

[INCLUDES]

# Load regexes for filtering
#before = botddsearch-common.conf

[Definition]

failregex = ^<HOST> - .* "(GET|POST|HEAD) /(wp-admin|wp-login\.php|phpinfo\.php|\.git/?|\.env|\.vscode|\.ssh).*" (400|404|422).*$
^<HOST> - .* "(GET|POST|HEAD) /([^/]+?\.(php|json|py|yml|yaml|ini)).*" 404.*$

ignoreregex =

datepattern = {^LN-BEG}%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)?
^[^\[]*\[({DATE})
{^LN-BEG}

# DEV Notes:
#
# Author: yuy

添加 jail 配置
/etc/fail2ban/jail.d/添加文件nginx-scan.local,输入内容:

1
2
3
4
5
6
7
8
9
10
11
[nginx-scan]
enabled = true
port = http,https
filter = nginx-scan
logpath = /var/www/logs/*.log
backend = auto

# 1分钟内发现10次直接ban 30天
findtime = 1m
maxretry = 10
bantime = 30d

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
2
3
if ($http_user_agent ~* (Baiduspider|Applebot)) {
return 403;
}

添加过滤器规则/etc/fail2ban/filter.d/nginx-bad-bot.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Ban spiders

[INCLUDES]

# Load regexes for filtering
# 没用上
before = botsearch-common.conf

[Definition]

failregex = ^<HOST> \- \S+ \[\] \"(GET|POST|HEAD) \/.*?(Baiduspider|Applebot).+$

ignoreregex =

datepattern = {^LN-BEG}%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)?
^[^\[]*\[({DATE})
{^LN-BEG}
# DEV Notes:
# 拉黑百度和苹果的bot
# Author: yuy

添加jail规则/etc/fail2ban/jail.d/nginx-bad-bot.local

1
2
3
4
5
6
7
8
9
[nginx-bad-bot]
enabled = true
port = http,https
filter = nginx-bad-bot
logpath = /var/www/logs/*xyz.log
# 10分钟内发现两次直接ban 30天
findtime = 10m
maxretry = 2
bantime = 30d

一定要将logpath = /var/www/logs/*xyz.log的日志文件改成你需要监听的文件。

强制断开连接

对于nginx的http/https的tcp连接,由于触发封禁只是对之后建立的tcp链接有效,在封禁前建立的连接仍能够继续,就像下面这样
,一个ip被封禁后短时间内仍能够继续访问。

hider
1
2
3
4
5
6
7
8
2026-04-10 08:42:09,777 fail2ban.filter         [19482]: INFO    [nginx-scan] Found 20.205.1.146 - 2026-04-10 08:42:09
...
2026-04-10 08:42:10,381 fail2ban.filter [19482]: INFO [nginx-scan] Found 20.205.1.146 - 2026-04-10 08:42:10
2026-04-10 08:42:10,446 fail2ban.actions [19482]: NOTICE [nginx-scan] Ban 20.205.1.146
2026-04-10 08:42:10,583 fail2ban.filter [19482]: INFO [nginx-scan] Found 20.205.1.146 - 2026-04-10 08:42:10
...
2026-04-10 08:42:12,191 fail2ban.filter [19482]: INFO [nginx-scan] Found 20.205.1.146 - 2026-04-10 08:42:12
2026-04-10 08:42:12,265 fail2ban.actions [19482]: NOTICE [nginx-scan] 20.205.1.146 already banned

因此在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
2
3
# 强制断开连接命令
force-break = conntrack -D -p tcp -s <ip> --state ESTABLISHED || true
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

解释: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连接。

验证

Important

如果改了配置,需要重启fail2ban:
sudo systemctl restart fail2ban

使用ssh命令重复多次输入错误密码,可在/var/log/fail2ban.log看到新的ip触发ban,并且ssh无法连接上时表示配置成功