nginx+Fail2Ban实现动态封禁IP

在下码不完 10小时前 ⋅ 9 阅读

nginx+Fail2Ban实现动态封禁IP

一、安装fail2ban

1、启用 EPEL 仓库(推荐)

fail2ban 包含在 EPEL(Extra Packages for Enterprise Linux)仓库中,您需要先启用它:

# 1. 安装 EPEL 仓库
sudo yum install -y epel-release

# 2. 更新仓库缓存
sudo yum makecache fast

# 3. 安装 fail2ban
sudo yum install -y fail2ban

2、如果 EPEL 安装失败,可以手动配置

# 使用阿里云镜像安装 EPEL
sudo yum install -y https://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm

# 然后安装 fail2ban
sudo yum install -y fail2ban

3、源码安装

# 安装依赖
sudo yum install -y python3 python3-pip git iptables

# 克隆 fail2ban 仓库
git clone https://github.com/fail2ban/fail2ban.git
cd fail2ban

# 安装
sudo python3 setup.py install

# 复制配置文件
sudo cp config/jail.conf /etc/fail2ban/jail.local

二、添加配置文件

安装后的默认路径:/etc/fail2ban

1、Filter

定义什么行为算违规?

vim /etc/fail2ban/filter.d/nginx-black.conf
[Definition]
#匹配所有请求
#failregex = "remote_ip":\s*"<HOST>".*"request":\s*"[^\"]+".*"response":\s*"[2345]\d\d"
#匹配/api/sms/code这个的所有请求
failregex = <HOST>.*"/api/sms/code
ignoreregex =
部分 含义 示例匹配
^ 匹配行首 -
Fail2Ban 特殊标记,自动匹配 IP 地址 192.168.1.100
\s+ 匹配 1 个或多个空白字符(空格、制表符等)
.* 匹配任意字符 0 多次 - - [30/Mar/2025:10:30:15 +0800]
" 匹配字面的双引号 "
(GET|POST) 匹配 GET 或 POST 方法 GET 或 POST
\s+ 匹配字面的双引号 "
/api/platform/staff/register/ 匹配固定的 API 路径前缀 /api/platform/staff/register/
.* 匹配任意后续路径 ?username=test 或 /verify 等
\s+ 匹配 1 个或多个空白字符
HTTP/[0-9.]+ 匹配 HTTP 协议版本 HTTP/1.1、HTTP/2.0
" 匹配结束的双引号 "
\s+ 匹配 1 个或多个空白字符
200 只匹配 HTTP 状态码 200(请求成功) 200
\s 匹配最后的空白字符(后面通常是响应字节数)

ignoreregex 忽略正则表达式

  • 空值表示不忽略任何匹配的日志
  • 如果某些正常请求也需要访问这个接口,可以在此添加排除规则 会匹配的日志
192.168.1.100 - - [30/Mar/2025:10:30:15 +0800] "GET /api/platform/staff/register/verify HTTP/1.1" 200 1234 "-" "Mozilla/5.0"
10.0.0.55 - - [30/Mar/2025:10:31:20 +0800] "POST /api/platform/staff/register?token=abc123 HTTP/1.1" 200 567 "-" "curl/7.68.0"

不会匹配的日志

# 状态码不是 200
192.168.1.100 - - [...] "GET /api/platform/staff/register HTTP/1.1" 404 123 "-" "..."
#路径不匹配:
192.168.1.100 - - [...] "GET /api/platform/staff/register HTTP/1.1" 404 123 "-" "..."
#其他请求方法(如 PUT、DELETE):
192.168.1.100 - - [...] "DELETE /api/platform/staff/register HTTP/1.1" 200 0 "-" "..."

2、action

"违规后怎么处理?"

sudo vim /etc/fail2ban/filter.d/nginx-black-action.conf

[Definition]
actionstart = docker exec nginx nginx -s reload
actionstop =
actioncheck =
actionban = echo "deny <ip>;" >> /usr/local/nginx/blockedips.conf && docker exec nginx nginx -s reload
actionunban = sed -i "/deny <ip>;/d" /usr/local/nginx/blockedips.conf && docker exec nginx nginx -s reload

3、jail.local

用于定义"监控策略"和"处置规则" 创建配置文件

  • fail2ban 启动时先读取 /etc/fail2ban/jail.conf(默认配置,只读参考)
  • 然后尝试读取 /etc/fail2ban/jail.local(用户自定义配置)
  • 如果 jail.local 存在,会覆盖 jail.conf 中的相同配置项
  • 如果 jail.local 不存在,只使用 jail.conf 的默认配置

jail.local不存在的时候,可以使用下面的方式来创建

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

[nginx-black]
enabled = true
port = http,https
filter = nginx-black
action = nginx-black-action
logpath = /usr/local/nginx/logs/access.log
# 5 次就封禁
maxretry = 5
# 封禁时长(秒)= 3600*24 *7 小时
bantime = 30
# 检测时间窗口(秒)= 30 s
findtime = 60
  • 在这个的最后面增加后面的的配置
  • nginx-black为filter的文件名字
  • nginx-black-action为action的文件名字
  • logpath是定义需要监控的文件名字

四、与nginx联动

1、http中配置

http {
    include /usr/local/nginx/blockedips.conf;
    
    ....其他的配置(直接放在第一行)

2、server(限制整个server)

server {
     include /usr/local/nginx/blockedips.conf;
    
    ....其他的配置(直接放在第一行)

2、server(限制整个server)

server {
    listen       80;
    server_name  localhost;

    # 只对 API 接口进行 IP 封禁
    location /api/ {
        include /usr/local/nginx/blockedips.conf;
    ....其他的配置(直接放在location后配置的第一行)

五、基本命令

# 启动 fail2ban
sudo systemctl start fail2ban

# 设置开机自启
sudo systemctl enable fail2ban

# 查看状态
sudo systemctl status fail2ban

# 查看 jail 列表
sudo fail2ban-client status

# 验证nginx-black匹配的结果
sudo fail2ban-regex /usr/local/nginx/logs/access.log /etc/fail2ban/filter.d/nginx-black.conf
# 查看nginx-black的状态
sudo fail2ban-client status nginx-black
# 查看nginx-black中的maxretry配置
sudo fail2ban-client get nginx-black maxretry
# 查看nginx-black中的findtime配置
sudo fail2ban-client get nginx-black findtime
# 查看nginx-black中的bantime配置
sudo fail2ban-client get nginx-black bantime
# 查看nginx-black中的封禁IP
sudo fail2ban-client get nginx-black banned
#查看fail2ban的日志
tail -n 50 /var/log/fail2ban.log

全部评论: 0

    我有话说: