前言

之前买了个腾讯云轻量服务器,5M 带宽的,用来做 nas 的内网穿透,以及部署一些小网站,一直以来未关注过服务器的带宽使用情况,直到有一天通过 vps 中转看 jellyfin 视频的时候发现即使把码率设置到 2M 任然不流畅,才到控制台看了下 vps 的流量使用情况,不看不知道一看吓一跳,每天都有大量的出口流量,再通过 nginx 日志查看,发现是被人拿来刷下载了,一天有几百 M 的 access.log 记录。因此想加个简单的防火墙来自动封禁高频请求的源 ip。在网上简单搜索后了解到 fail2ban 可以满足我的需求,本篇用于记录 fail2ban 的简单使用方法。

什么是 fail2ban

fail2ban 是一个根据软件日志(nginx,ssh,apache 等)ip 访问频率来自动封禁的开源安全软件,开源地址:https://github.com/fail2ban/fail2ban,非常适合个人用户来使用。

软件安装

软件源安装

使用 linux 发行版自带的包管理器安装

sudo apt install fail2ban
sudo yum install fail2ban

注意:通过软件源安装的,通常版本会比较老旧,想要安装最新版,可通过下面的源码安装

源码安装

安装前置条件:

  • Python>=3.5
  • python-setuptools

然后 clone 代码到本地并安装

git clone https://github.com/fail2ban/fail2ban.git
cd fail2ban
sudo python setup.py install

安装完毕后通过fail2ban-client version 验证是否安装成功

简单使用

安装完毕后,可以在/etc/fail2ban目录中查看配置文件。

通过vim /etc/fail2ban/jail.local命令创建我们自己需要的配置,另外/etc/fail2ban/jail.conf 为官方配置,有兴趣的可以去看看

jail.local 中的配置将会覆盖 jail.conf 中的配置

[DEFAULT]
# 是否忽略自身
ignoreself = false
# 忽略ip,永远不会被ban
ignoreip = 192.168.1.0/24 192.168.1.2/24
ignorecommand =
# ip被ban持续时间
bantime  = 24h
# 统计周期
findtime  = 10m
# findtime时间内失败重试最大次数
maxretry = 3
# findtime时间内ip访问最大次数,%(maxretry)s表示引用maxretry的配置
maxmatches = 200

# sshd配置
[sshd]
enabled = true
# 1.1.1.dev1 版本下 debian11 需要改为auto,否则会报错无法启动
backend = auto

# nginx配置
[nginx-bad-request]
enabled = true
port    = http,https,880,8443
logpath = %(nginx_access_log)s

随后重启 fail2ban 即可生效,systemctl restart fail2ban

nginx-proxy-manager 支持

由于 nginx-proxy-manager(后简称 npm)改动了原本 nginx 的日志格式,因此 fail2ban 自动的 nginx 日志解析无法解析 npm 日志,需要我们自定义解析器。步骤如下:

  1. jail.local 新增如下内容:
[npm-general-forceful-browsing]
enabled = true
action = action-ban-docker-forceful-browsing
filter = npm-general-forceful-browsing
logpath = /var/log/npm/proxy-host-*_access.log
  1. /etc/fail2ban/filter.d目录下新增npm-general-forceful-browsing.conf

    [INCLUDES]
    
    [Definition]
    
    failregex = ^.* (405|404|403|401|\-) (405|404|403|401) - .* \[Client <HOST>\] \[Length .*\] .* \[Sent-to <F-CONTAINER>.*</F-CONTAINER>\] <F-USERAGENT>".*"</F-USERAGENT> .*$
    
    ignoreregex = ^.* (404|\-) (404) - .*".*(\.png|\.txt|\.jpg|\.ico|\.js|\.css|\.ttf|\.woff|\.woff2)(/)*?" \[Client <HOST>\] \[Length .*\] ".*" .*$
    
  2. /etc/fail2ban/action.d目录下新增action-ban-docker-forceful-browsing.conf

    [Definition]
    
    actionban = iptables -I DOCKER-USER -m string --algo bm --string 'X-Forwarded-For: <ip>' -j DROP
                iptables -A INPUT -s <ip> -j DROP
    
    actionunban = iptables -D DOCKER-USER -m string --algo bm --string 'X-Forwarded-For: <ip>' -j DROP
                  iptables -D INPUT -s <ip> -j DROP
    
  3. 执行fail2ban-client reload重新加载配置

常用命令

  • 加载配置 fail2ban-client reload
  • 检查已生效配置 fail2ban-client status
  • 查看某个配置详情 fail2ban-client status sshd

参考:

https://github.com/fail2ban/fail2ban/tree/master

https://blog.lrvt.de/fail2ban-with-nginx-proxy-manager