作为一名站长,每天面对的都是一个充满风险的网络世界。在阴暗的角落里,总有一小撮人带着各种目的,对网络上的服务器发起攻击。这些攻击行为五花八门:有的在搜索站点漏洞,伺机入侵;有的通过非正常高频访问页面,耗尽服务器资源;还有的属于专门薅流量的灰色产业,紧盯网页上的媒体资源进行恶意抓取......因此,Web 服务器的安全防护话题愈发重要,甚至可以说已成为刚需。如何有效保护在线资源免受异常访问的侵扰,成为每一位站长必须直面的关键问题。本文将重点介绍服务器安全工具库中一款出色的开源工具------Fail2Ban,详细讲解其安装、使用方法,以及如何通过开箱即用的功能,为服务器筑起一道坚固的防线,减少攻击带来的影响。
使用 Fail2Ban 工具的前提
Fail2Ban 是基于Linux平台WebServer的一个插件,如果你的站点资源现托管在 Windows 服务器上的IIS上,而恰好又是基于单实例的架构,那么你需要对现有的Server 站点架构做一些改造。通常一个可靠的结构会包含一个前置的 Nginx 服务器用作反向代理或者负载均衡,后面则是负责站点资源托管的服务器或者集群。更进一步,为了增加整体可用性,前置反向代理会适当增加冗余备份等。不过这些不是我们今天主要讨论的话题。在完成上述改造后,在整个结构中,我们就有了一个 Linux + Nginx 的结构,这是我们开启 Fail2Ban 工具之旅的一个基础。
传统运维的弊端
传统的服务器安全运维,站长同学会定期人肉监控服务器各项状态,如 CPU、内存或者 DiskIO、数据库资源占用异常偏高,再或者在连接数释放不及时等导致的异常情况时,及时登到服务器上,查看最近访问日志中,识别存在明显攻击行为的访问,最终对这些 IP 或者 IP 段进行封禁,阻止后续的异常访问,降低服务器的非可控资源占用。但在典型的访问日志中,存在着以下问题:
- 滞后性:通常只能在实际发生服务器性能明显下降时,开始干预,此时给正常的客户提供的服务已经或多或少的受到了影响,服务质量下降。
- 需要纯人工,或者借助一些其他三方工具从海量的日志中分析明显不正统的流量,耗时、费力
- 国内很多服务器的 IP 是动态获取的,攻击流量存在一定的时效性,可能一段时间内使用 A 地址扫描网站,再过 24 小时会自动变成地址 B,封禁、解封存在着时效性,会存在误伤的可能
因此,亟需一种可以能够可以识别攻击行为、阻止异常访问的自动化工具参与到日常运维中来。
Fail2Ban 的核心原理
Fail2Ban 之所以能成为服务器安全的得力助手,核心在于其动态监控的防护机制。它会持续监控服务器的各类日志文件(如 SSH 登录日志、Web 服务器访问日志等),通过预设的规则识别异常访问行为。当某一 IP 地址的违规次数达到设定阈值时,Fail2Ban 会自动调用防火墙(如 iptables、firewalld 等)对该 IP 进行临时或永久封禁,从而阻止其继续发起攻击,降低服务器资源被进一步消耗。这种机制的优势在于灵活性和实时性。它不局限于特定的攻击类型,只要能在日志中体现出异常特征,就能有效拦截。同时,临时封禁的设置也避免了误封正常用户后难以恢复的问题。
Fail2Ban 的安装步骤
不同的操作系统,Fail2Ban 的安装方式略有差异,以下是几种常见系统的安装方法:
- Ubuntu/Debian 系统 :在终端中输入命令
sudo apt-get update
更新软件源,然后执行sudo apt-get install fail2ban
即可完成安装,安装过程中,系统会自动处理依赖关系,无需额外操作。 - CentOS/RHEL 系统 :由于 CentOS 默认的软件源中可能没有 Fail2Ban,需要先安装 EPEL 源。输入
sudo yum install epel-release
安装 EPEL 源,之后再运行sudo yum install fail2ban
进行安装。 - Fedora 系统 :直接在终端中输入
sudo dnf install fail2ban
即可安装,Fedora 的软件源中通常包含 Fail2Ban。
安装完成后,可以通过 sudo systemctl start fail2ban
启动服务,再用 sudo systemctl enable fail2ban
设置开机自启动,确保服务器重启后 Fail2Ban 能自动运行。
后面我们将以Ubuntu为例,讲解Fail2Ban的核心功能配置。
Fail2Ban 的核心功能配置
Fail2Ban 的配置文件主要位于 /etc/fail2ban/
目录下,其中 jail.conf
是主要的配置文件,Fail2Ban 支持针对不同的服务进行配置,如 SSH、Apache、Nginx 等。每个服务都有自己的配置段落,例如 SSH 服务的配置段落为 [sshd]
,Apache 服务的配置段落为 [apache]
等,Nginx WebService有[nginx]
的相应配置。
但为了避免升级时配置被覆盖,建议先创建自定义配置文件jail.local
并在其中进行自定义配置。在 jail.local
中,你可以根据需要标记自定义服务的防护,以及调整其相关参数。
- 基本设置 :在
jail.local
中,可以设置默认的封禁时间(bantime
)、触发封禁的最大尝试次数(maxretry
)以及检测时间窗口(findtime
)。例如,将bantime = 3600
设置为封禁 1 小时,maxretry = 5
表示 5 次失败尝试后触发封禁,findtime = 600
意味着在 10 分钟内的失败尝试会被累计。 - 针对特定服务的配置 :Fail2Ban 支持对多种服务进行防护,如 SSH、Apache、Nginx 等。以 SSH 为例,在配置文件中找到
[sshd]
部分,将enabled = true
开启防护,还可以根据实际情况调整该服务的maxretry
、bantime
等参数。 - 邮件通知设置 :如果希望在有 IP 被封禁时收到邮件通知,可以配置
destemail
(目标邮箱)、sendername
(发件人名称)等参数,并确保服务器已安装邮件发送工具(如 sendmail )。
如,某天我们Nginx WebServer 出现了异常多的 404 错误请求,虽然我们在一定程度上允许WebServer 有合理范围的404错误请求,但如果超出了一定的度,势必会造成服务器资源的过度消耗,所以这里超出范围的规则,就需要我们在 jail.local
中合理的添加配置去封禁这些 "恶意" 发起IP:
先在 /etc/fail2ban/filter.d/
目录下创建一个自定义的过滤器文件 nginx-ban-404ips.conf
,内容如下:
ini
[Definition]
failregex = ^<HOST> - .* "GET .* HTTP/1\..*" 404 .*$
ignoreregex =
再在jail.local
中添加如下配置,启用上面我们定义的过滤器:
ini
[nginx-ban-404ips]
enabled = true
filter = nginx-ban-404ips # 声明前面定义的 nginx-ban-404ips 过滤器
logpath = /var/log/nginx/access.log # nginx访问日志路径
maxretry = 5 # 最大重试次数
findtime = 600 # 检测时间窗口
bantime = 3600 # 封禁时长
该配置实现了如下自动化机制:
当某个 IP 在指定时间内(10 分钟)对服务器发起的 HTTP/HTTPS 请求中,有 5 次及以上返回 "404 Not Found" 错误时,fail2ban会自动通过 iptables 防火墙封禁该 IP,封禁时长为 1 小时(3600 秒)。
配置完成后,需要通过 sudo systemctl restart fail2ban
重启服务,使配置生效。这样就很方便实现了通过预定义的过滤器,来自动封禁异常行为访问。
实际场景演练
在完成 Fail2Ban 基础安装与核心功能配置后,一般我们通过 bantime
(封禁时长 )、maxretry
(最大重试次数 )、findtime
(检测时间窗口 )等关键配置,即可应对较为常见的攻击场景。后面我们会模拟不同的攻击场景,详解如何自动化防护:
一、核心配置介绍
属性名 | 功能介绍 | 示例 |
---|---|---|
bantime |
判定攻击后,封禁 IP 的时长(秒),可设永久封禁(如 bantime = -1 ) |
bantime = 3600 (封禁3600秒/1小时) |
maxretry |
检测时间窗口内,IP 触发规则的最大异常次数,超过则封禁 | maxretry = 5 (5次尝试) |
findtime |
统计异常行为的时间窗口(秒),若 IP 在此窗口内触发 maxretry 次则封禁 |
findtime = 600 (600秒/10分钟) |
二、场景模拟与配置实践
场景1:零散 IP 大量访问无特征页面
攻击特征 :大量随机 IP 短时间内,对网站普通页面(如首页、产品列表页)高频访问,无固定路径规律,消耗带宽与服务器连接数。
配置思路 :通过 findtime
缩小检测窗口、maxretry
降低触发阈值,快速拦截零散试探。
在 /etc/fail2ban/filter.d/ 目录下新建 nginx-noscene.conf Filter 文件
ini
[Definition]
# 匹配任意路径的高频访问(日志格式为 Nginx 标准访问日志)
# 示例日志:1.2.3.4 - - [01/Jan/2024:12:00:00 +0800] "GET /random-page HTTP/1.1" 200 1234
failregex = ^<HOST> .* "GET .* HTTP/1\.[01]" .*$
^<HOST> .* "POST .* HTTP/1\.[01]" .*$
ignoreregex =
jail.local添加配置:
ini
# 假设防护 Nginx 普通访问,在 jail.local 新增 [nginx-noscene] 配置
[nginx-noscene]
enabled = true
filter = nginx-noscene # 调用默认 Nginx 异常请求过滤规则,可自定义
logpath = /var/log/nginx/access.log # 需替换为实际 Nginx 访问日志路径
bantime = 1800 # 封禁30分钟,给零散 IP 短暂惩罚,避免误封长期影响
maxretry = 10 # 10分钟(findtime)内超10次访问即判定攻击
findtime = 600
配置原因 :零散 IP 攻击分散但高频,缩短 findtime
让检测更灵敏,适度降低 maxretry
覆盖 "小额多次" 试探;bantime
设为 30 分钟,平衡拦截效率与误封恢复周期。
场景2:异常 IP 访问敏感页面(login/admin 等)
攻击特征 :大量未知 IP 高频访问登录页(/login
)、管理后台(/admin
)、密码重置页(/password
),尝试暴力破解或探路。
配置思路 :针对敏感路径单独配置规则,缩小 findtime
、降低 maxretry
,快速拦截试探。
在 /etc/fail2ban/filter.d/ 目录下新建 nginx-sensitive.conf
ini
[Definition]
failregex = ^<HOST> .* "GET /(login|admin|password) HTTP/1\.[01]" .*$
^<HOST> .* "POST /(login|admin|password) HTTP/1\.[01]" .*$
ignoreregex =
jail.local添加配置:
ini
[nginx-sensitive]
enabled = true
filter = nginx-sensitive
logpath = /var/log/nginx/access.log
bantime = 3600 # 封禁1小时,给暴力破解类攻击及时惩罚
maxretry = 3 # 10分钟内超3次访问敏感页即触发
findtime = 300 # 缩短检测窗口至5分钟,快速响应高频试探
配置原因 :敏感页面是攻击重灾区,findtime
缩短让检测更实时,maxretry
设为 3 严格限制尝试次数;bantime
封禁1小时,既拦截攻击,也避免正常用户偶尔误操作被长期封禁。
场景3:雷同 UA 洪水攻击
攻击特征 :大量请求使用相同或高度雷同的 User-Agent(UA),如伪装成搜索引擎爬虫(Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)
),但行为异常(短时间内遍历页面、请求频率异常)。
配置思路 :自定义 filter 规则匹配雷同 UA,结合 findtime
、maxretry
限制频率。
在 /etc/fail2ban/filter.d/
目录下新建 nginx-ua-flood.conf
ini
[Definition]
failregex = ^.*"(?P<ua>Mozilla/5.0 \(compatible; Baiduspider/2.0; .*\))".*$
jail.local添加配置:
ini
[nginx-ua-flood]
enabled = true
filter = nginx-ua-flood # 调用自定义 UA 过滤规则
logpath = /var/log/nginx/access.log
bantime = 10800 # 封禁3小时,针对批量 UA 攻击延长惩罚
maxretry = 5 # 10分钟内超5次雷同 UA 请求触发
findtime = 600
配置原因 :雷同 UA 攻击易伪装、规模大,自定义 filter 精准识别 UA 特征;bantime
延长可减少同一批 UA 短时间内反复攻击;maxretry
控制触发门槛,避免单 IP 正常浏览被误封。
场景4:用户尝试登录服务器(SSH 暴力破解)
除监控WebServer外,Fail2ban还可监控Server的SSH服务。下面简单介绍如何监控SSH日志,自动封禁异常IP,减少因暴力破解而导致的密码泄露。
攻击特征 :大量 IP 尝试 SSH 登录,密码错误日志高频出现(如 /var/log/auth.log
中 Failed password for root from...
)。
配置思路 :利用 Fail2Ban 默认 sshd
规则,调整 bantime
、maxretry
适配服务器安全策略。
ini
# 编辑 jail.local 中添加 [sshd] 配置
[sshd]
enabled = true
bantime = 86400 # 封禁1天,对 SSH 暴力破解重罚
maxretry = 3 # 10分钟内3次密码错误即触发
findtime = 600
配置原因 :SSH 是服务器核心入口,暴力破解风险极高。maxretry
设为 3 严格限制尝试次数,bantime
设1天,大幅增加攻击成本;findtime
保持10分钟,覆盖典型暴力破解的试探周期。
注:这里没有显式指定ssh的logpath,是因为fail2ban默认包含了用于[sshd]的过滤器,过滤器已中已经包含了 /var/log/auth.log
这个文件,所以这里无需显式指定,这需要关注访问行为设置规则配置即可。
Fail2Ban 的其他技巧
- 查看封禁列表 :使用命令
sudo fail2ban-client status 自定义过滤器
可以查看当前被封禁的 IP 地址以及相关状态信息,便于了解服务器的受攻击情况。
- 手动封禁 IP :如果发现个别 IP 被规则遗漏,可以执行
sudo fail2ban-client set 自定义过滤器 banip 192.168.1.1
(封禁 192.168.1.1)。 - 解除误封 IP :如果发现正常 IP 被误封,可以执行
sudo fail2ban-client set 自定义过滤器 unbanip 192.168.1.1
(解除封禁 192.168.1.1 )。
通过以上场景演练,可精准调控 Fail2Ban 核心参数,针对如上场景构建防护网。关键在于理解 bantime
控制惩罚力度、maxretry
定义触发门槛、findtime
划定检测范围,结合日志特征与攻击模式灵活和动态的调整配置,让服务器防御既 "精准打击" 又 "容错可控"。站长可以大幅提升服务器的安全性,有效抵御各类网络攻击,为网站的稳定运行提供有力保障。
参考文档
Fail2Ban 项目 Github 官方地址:https://github.com/fail2ban/fail2ban