欢迎光临
我们一直在努力

Fail2ban深度配置指南:从SSH防爆破到Web应用保护,打造VPS自动化防御体系

为什么你的VPS需要Fail2ban

任何一台暴露在公网的Linux VPS,从开机那一刻起就在被扫描和爆破。无论你用的是阿里云、腾讯云还是海外VPS,SSH端口、Web面板、数据库端口无一例外都会成为攻击者的目标。根据我的实际观察,一台配置了默认SSH端口(22)的全新VPS,在接入互联网后的24小时内,平均会遭受2000到5000次登录尝试。这些尝试来自全球各地的僵尸网络、扫描器以及自动化攻击脚本。

传统的防护手段——修改SSH端口、使用强密码、禁用root登录——虽然有效,但远远不够。攻击者同样会扫描其他端口(如2222、22222等常见替代端口),而密码再强也架不住撞库和字典攻击的持续轰炸。更关键的是,这些方法都是被动防御,无法在攻击发生时实时响应并阻断攻击源。

这就是Fail2ban发挥作用的地方。Fail2ban是一个基于Python的入侵防御框架,它通过扫描系统日志文件(如

1
/var/log/auth.log

1
/var/log/nginx/error.log

),识别出反复失败的登录尝试、恶意请求模式或扫描行为,然后动态地修改防火墙规则(iptables/nftables),在指定时间内临时封禁攻击源的IP地址。简单来说,Fail2ban让你的服务器拥有了”自动反击”的能力。

本文将带你从零开始,全面掌握Fail2ban的安装、配置、调优,并深入讲解如何保护SSH、Nginx、WordPress、Postfix邮件服务等常见应用,最终打造一个自动化的VPS防御体系。

服务器安全架构图

Fail2ban安装与基础配置

安装Fail2ban

主流的Linux发行版都内置了Fail2ban包,安装非常简单:


1
2
3
4
5
6
7
8
9
10
# Debian/Ubuntu
apt update && apt install -y fail2ban

# CentOS/RHEL 7/8
yum install epel-release -y
yum install fail2ban -y

# Rocky Linux / AlmaLinux 9
dnf install epel-release -y
dnf install fail2ban -y

安装完成后,先不要急着启动服务。我们需要先理解它的配置文件结构,然后根据自己的需求进行定制。

配置文件结构

Fail2ban的配置文件遵循”本地覆盖”原则,这一点非常重要:

文件路径 作用 注意事项
1
/etc/fail2ban/fail2ban.conf
Fail2ban守护进程本身的配置(日志级别、socket路径等) 一般不需要修改
1
/etc/fail2ban/jail.conf
默认的监狱配置(包含所有内置规则) 不要直接编辑,会被更新覆盖
1
/etc/fail2ban/jail.local
用户自定义的监狱配置(覆盖jail.conf中的值) 你真正需要编辑的文件
1
/etc/fail2ban/filter.d/
各种服务的日志匹配规则(正则表达式) 可以自定义

1
*.local

覆盖

1
/etc/fail2ban/action.d/
封禁动作的定义(iptables、firewallcmd、cloudflare等) 一般不需要修改

核心原则是:永远不要修改

1
<em>.conf

文件,而是在同目录下创建同名的

1
</em>.local

文件来覆盖配置。这样在升级Fail2ban时,你的自定义配置不会丢失。

创建本地配置文件

现在我们创建

1
jail.local

,这是整个Fail2ban配置的核心:


1
2
3
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# 或者直接新建一个空文件从头写
vim /etc/fail2ban/jail.local

一个最基本的

1
jail.local

配置示例:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[DEFAULT]
# 封禁时间:3600秒(1小时)。设置为 -1 表示永久封禁
bantime = 3600

# 在findtime秒内,如果失败maxretry次,则封禁
findtime = 600
maxretry = 5

# 忽略的IP列表(白名单),永远不要封禁这些IP
# 建议把你自己公司的公网IP或VPN的IP加进来
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24

# 默认的防火墙封禁动作
# iptables-allports 会封禁所有端口;iptables 只封禁目标端口
banaction = iptables-allports

# 封禁通知邮箱(可选)
# destemail = admin@example.com
# sender = fail2ban@example.com
# action = %(action_mw)s

# 日志编码
logencoding = utf-8

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

这里有几个关键参数需要理解:

  • bantime:封禁持续时间。默认3600秒(1小时)。对于SSH爆破,建议至少设置86400秒(24小时)。对于某些特别顽固的攻击者,可以考虑永久封禁。
  • findtime:检测窗口。Fail2ban会统计在findtime秒内某个IP的失败次数。
  • maxretry:触发封禁的失败次数阈值。在findtime内达到maxretry次失败,即触发封禁。
  • ignoreip:白名单IP列表。这个非常重要,一定要把自己的IP加进去,否则把自己封了就尴尬了。

深入配置:保护SSH服务

SSH是VPS管理的最基本入口,也是被攻击最多的服务。针对SSH的Fail2ban配置虽然看起来简单,但有很多调优空间。

基础SSH监狱配置


1
2
3
4
5
6
7
8
9
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 300
bantime = 86400
ignoreip = 127.0.0.1/8 ::1 你的公网IP

这个配置意味着:在5分钟内,如果有3次失败的SSH登录尝试,该IP将被封禁24小时。对于大多数场景,这已经足够有效。

SSH监狱调优技巧

如果你发现自己的SSH登录偶尔也会被误封(比如输错了一两次密码),可以适当调高

1
maxretry

或调大

1
findtime

。但更好的做法是使用

1
recidive

监狱——它实现了一种”累进惩罚”机制:


1
2
3
4
5
6
7
8
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
filter = fail2ban
maxretry = 3
findtime = 86400
bantime = 604800  # 1周
banaction = iptables-allports

这个监狱监控的是Fail2ban自己的日志。如果一个IP在过去24小时内被Fail2ban封禁过3次以上,说明这是”惯犯”,那就直接封一周。这种策略非常有效,因为大多数攻击者不会持续一周攻击同一台机器。

自定义SSH filter

有时默认的SSH filter可能无法匹配某些特殊场景。你可以创建自定义filter:


1
2
3
4
5
6
# /etc/fail2ban/filter.d/sshd-custom.local
[Definition]
failregex = ^%(__prefix_line)sFailed \w+ for .* from &lt;HOST&gt; port \d+ ssh2$
            ^%(__prefix_line)sConnection closed by authenticating user .* &lt;HOST&gt; port \d+ \[preauth\]$
            ^%(__prefix_line)sDisconnected from invalid user .* &lt;HOST&gt; port \d+ \[preauth\]$
ignoreregex =

然后修改

1
jail.local

中的 filter 指向自定义文件:


1
2
3
4
[sshd]
enabled = true
filter = sshd-custom
...

保护Web服务:Nginx和Apache

Web服务是VPS的另一大攻击面。常见的攻击包括:目录扫描、SQL注入尝试、暴力破解登录页面、CC攻击等。我们可以为Nginx配置多个监狱来应对不同场景。

Nginx基础防护


1
2
3
4
5
6
7
8
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
findtime = 600
bantime = 3600

这个监狱会检测访问不存在的URL(404错误)的请求,如果某个IP在短时间内触发大量404,说明它在扫描你的网站结构或寻找漏洞,应当封禁。

防止WordPress登录爆破

WordPress的

1
/wp-login.php

1
/xmlrpc.php

是暴力破解的重灾区。我们可以创建专门的Nginx filter来检测:


1
2
3
4
5
# /etc/fail2ban/filter.d/nginx-wordpress-login.local
[Definition]
failregex = ^&lt;HOST&gt; - - \[.*\] "POST /wp-login\.php HTTP/.*" 200
            ^&lt;HOST&gt; - - \[.*\] "POST /xmlrpc\.php HTTP/.*" 200
ignoreregex =

然后在

1
jail.local

中添加:


1
2
3
4
5
6
7
8
[nginx-wordpress-login]
enabled = true
port = http,https
filter = nginx-wordpress-login
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 300
bantime = 86400

CC攻击防护

CC攻击(Challenge Collapsar)是一种应用层DDoS攻击,通过大量看似正常的请求耗尽服务器资源。Fail2ban可以通过检测单个IP的请求频率来应对:


1
2
3
4
# /etc/fail2ban/filter.d/nginx-cc.local
[Definition]
failregex = ^&lt;HOST&gt; -.*"(GET|POST).*" \d+ \d+ ".*" ".*"$
ignoreregex =

1
2
3
4
5
6
7
8
[nginx-cc]
enabled = true
port = http,https
filter = nginx-cc
logpath = /var/log/nginx/access.log
maxretry = 300
findtime = 60
bantime = 600

这个配置的意思是:在1分钟内,如果某个IP发送了超过300个请求,就封禁10分钟。这里的阈值需要根据你的网站实际流量调整。如果网站正常访问量就很大,可以把

1
maxretry

调高到500或1000。

高级配置:Cloudflare联动与邮件通知

Cloudflare API联动封禁

如果你的网站使用了Cloudflare CDN,那么所有真实的访问IP都是Cloudflare的IP,而不是用户的实际IP。在这种情况下,Fail2ban的iptables封禁无法直接作用于真实用户。解决方法是通过Cloudflare API自动添加防火墙规则来封禁IP:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 安装Cloudflare action
cp /etc/fail2ban/action.d/cloudflare.conf /etc/fail2ban/action.d/cloudflare.local

# 编辑 action 文件,添加你的Cloudflare API凭证
# /etc/fail2ban/action.d/cloudflare.local
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = curl -s -X POST "https://api.cloudflare.com/client/v4/zones/&lt;cfzone&gt;/firewall/access_rules/rules" \
            -H "X-Auth-Email: &lt;cfuser&gt;" \
            -H "X-Auth-Key: &lt;cftoken&gt;" \
            -H "Content-Type: application/json" \
            --data '{"mode":"block","configuration":{"target":"ip","value":"&lt;ip&gt;"},"notes":"Fail2ban &lt;name&gt;"}'
actionunban = curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/&lt;cfzone&gt;/firewall/access_rules/rules/&lt;id&gt;" \
               -H "X-Auth-Email: &lt;cfuser&gt;" \
               -H "X-Auth-Key: &lt;cftoken&gt;" \
               -H "Content-Type: application/json"

然后在监狱配置中指定使用Cloudflare action:


1
2
3
4
5
6
7
8
9
10
[nginx-wordpress-login]
enabled = true
port = http,https
filter = nginx-wordpress-login
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 300
bantime = 86400
banaction = cloudflare
action = %(action_mw)s

邮件通知配置

如果你想在每次封禁时收到邮件通知:


1
2
3
4
5
6
[DEFAULT]
destemail = admin@yourdomain.com
sender = fail2ban@yourdomain.com
# action_mw = 发送邮件通知 + 封禁(带whois信息)
# action_mwl = 发送邮件通知 + 封禁(带whois信息和日志行)
action = %(action_mwl)s

这需要你配置好服务器的邮件发送能力(如Postfix或SendGrid),否则邮件发送会失败。

Fail2ban运维与调试

常用命令

掌握以下命令,日常运维会非常顺手:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看所有监狱的状态
fail2ban-client status

# 查看特定监狱的状态(包括当前被封禁的IP列表)
fail2ban-client status sshd

# 手动解封一个IP
fail2ban-client set sshd unbanip 1.2.3.4

# 手动封禁一个IP
fail2ban-client set sshd banip 1.2.3.4

# 重新加载配置
fail2ban-client reload

# 重启服务
systemctl restart fail2ban

# 查看Fail2ban运行日志
tail -f /var/log/fail2ban.log

测试正则表达式

Fail2ban的配置是否正确,关键在于filter中的正则表达式能否正确匹配日志。Fail2ban提供了测试工具:


1
2
3
4
5
6
7
8
# 测试filter是否匹配日志
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# 测试自定义filter
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-wordpress-login.local

# 实时测试模式
fail2ban-regex --print-all-missed /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

输出结果会显示匹配了多少行、失败了多少行,以及每行是否匹配。如果匹配率很低,说明正则表达式可能需要调整。

性能调优

对于流量较大的VPS,Fail2ban的日志扫描可能成为性能瓶颈。以下是一些优化建议:

  • 使用
    1
    backend = systemd

    :在支持systemd的系统中,使用systemd journal作为后端比轮询日志文件更高效。配置方法:

    1
    backend = systemd

    (默认已自动检测)。

  • 减少不必要的监狱:只启用你真正需要的监狱。每个监狱都会消耗CPU资源来扫描日志。
  • 合理设置
    1
    findtime

    :findtime越长,Fail2ban需要维护的状态表越大。对于高流量服务器,保持findtime在合理范围内。

  • 使用
    1
    ignoreip

    过滤掉已知的爬虫IP:Googlebot、Bingbot等搜索引擎的IP可以被添加到全局ignoreip中,避免它们被误封。

实战案例:搭建完整防御体系

下面是一个适用于大多数VPS场景的完整配置模板,涵盖了SSH、Nginx、WordPress和邮件服务的防护:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 你的公司IP
banaction = iptables-allports
logencoding = utf-8

[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
maxretry = 3
findtime = 300
bantime = 86400

[sshd-ddos]
enabled = true
port = ssh
logpath = %(sshd_log)s
maxretry = 6
findtime = 30
bantime = 86400

[recidive]
enabled = true
logpath = /var/log/fail2ban.log
maxretry = 3
findtime = 86400
bantime = 604800

[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
findtime = 600
bantime = 3600

[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
findtime = 300
bantime = 3600

[nginx-wordpress-login]
enabled = true
port = http,https
filter = nginx-wordpress-login
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 300
bantime = 86400

[postfix]
enabled = true
port = smtp,ssmtp,submission
filter = postfix
logpath = /var/log/mail.log
maxretry = 3
findtime = 300
bantime = 86400

应用配置后,记得重启Fail2ban:


1
2
systemctl restart fail2ban
fail2ban-client status

你应该看到类似这样的输出,列出了所有已启用的监狱:


1
2
3
Status
|- Number of jail:  6
`- Jail list:  sshd, sshd-ddos, recidive, nginx-botsearch, nginx-http-auth, postfix

进阶技巧与注意事项

误封处理

Fail2ban最让人头疼的问题就是误封。以下是一些减少误封的策略:

  • 先使用
    1
    banaction = iptables

    (只封目标端口)而不是

    1
    iptables-allports

    (封所有端口)。这样即使误封,也只是封了特定服务端口,用户的其他服务不受影响。

  • 使用
    1
    findtime

    1
    maxretry

    的黄金比例:对于SSH,

    1
    findtime=300s, maxretry=3

    基本不会误封正常用户,因为正常用户不会在5分钟内输错3次密码。

  • 配置白名单:在
    1
    ignoreip

    中添加自己常用的IP和VPN出口IP。

  • 设置合理的bantime:除非攻击非常猛烈,否则不建议永久封禁。24小时到1周的封禁时间已经足够让大多数攻击者放弃。

与CSF(ConfigServer Security & Firewall)配合使用

如果你同时使用CSF防火墙,需要注意两者的关系。CSF和Fail2ban可以共存,但需要避免冲突:

  • CSF负责端口级别的防护(阻止特定国家的IP、限制新连接数等)
  • Fail2ban负责应用级别的防护(基于日志分析触发封禁)
  • 建议将CSF的
    1
    LF_PERMBLOCK

    设置为0,将永久封禁交给Fail2ban的recidive监狱处理

数据库服务的防护

MySQL/MariaDB和Redis也是常见的攻击目标。虽然数据库通常不直接暴露在公网上,但如果有管理后台或通过Web应用间接访问,依然需要防护:


1
2
3
4
5
6
7
8
[mysqld-auth]
enabled = true
port = 3306
filter = mysqld-auth
logpath = /var/log/mysql/error.log
maxretry = 5
findtime = 600
bantime = 86400

总结

Fail2ban是VPS安全体系中不可或缺的一环。它轻量、高效、配置灵活,能够将服务器安全从”被动防守”升级为”主动反击”。通过本文的配置,你可以实现:

  • 自动封禁SSH爆破IP(24小时至1周)
  • 检测并封禁WordPress登录暴力破解
  • 抑制目录扫描和CC攻击
  • 通过Cloudflare联动封禁真实用户IP
  • 累进惩罚机制自动处理惯犯

最后,牢记安全最佳实践:Fail2ban只是防御体系的一部分,还应配合SSH密钥认证、禁用root直接登录、定期更新系统补丁、使用防火墙(UFW/CSF)等策略,构建纵深防御体系。安全没有银弹,但Fail2ban绝对是你工具箱里最趁手的那把武器。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » Fail2ban深度配置指南:从SSH防爆破到Web应用保护,打造VPS自动化防御体系
分享到: 更多 (0)