moosery/fwallascan2ban
GitHub: moosery/fwallascan2ban
一个类 Fail2ban 的 Linux 守护进程,监控 Web 服务器日志并通过 Firewalla MSP API 在网络边界自动封禁恶意 IP。
Stars: 0 | Forks: 0
# fwallascan2ban
一个类 fail2ban 的 Linux 守护进程,用于监控 Web 服务器访问日志,使用 PCRE2 正则表达式模式检测恶意请求,并通过 [Firewalla MSP API](https://docs.firewalla.net) 自动封禁违规 IP 地址——通过将其添加到由防火墙阻止规则支持的托管目标列表中。
## 工作原理
1. 使用 Linux inotify 实时监控 Web 服务器日志文件
2. 将每条新日志行与可配置的 `failregex` 模式进行匹配(fail2ban 兼容的 PCRE2 语法)
3. 当某个 IP 的命中次数达到 `maxretry` 时,通过 REST API 将其添加到 Firewalla MSP 目标列表
4. Firewalla 上的关联阻止规则在网络边界强制执行封禁——来自被封禁 IP 的流量在到达服务器之前就会被丢弃
5. 运行定期同步以保持本地状态与 Firewalla 同步
被封禁的 IP 会持久化到本地 `banned.db` 文件中,并在守护进程重启后保留。日志轮转会自动处理。
## 需求
- Linux(需要 inotify)
- 配备 MSP(托管安全门户)的 Firewalla
- MSP API 2.10.0 或更高版本(规则创建 API)
- libcurl(用于 HTTPS API 调用)
- libpcre2-8(用于 PCRE2 正则匹配)
```
apt install libcurl4-openssl-dev libpcre2-dev
```
## 构建
```
make
```
生成两个二进制文件:
- `fwallascan2ban` — 守护进程
- `fwallascan2ban-client` — CLI 客户端
## 安装
```
sudo make install
```
这将安装:
- `/usr/local/sbin/fwallascan2ban`
- `/usr/local/bin/fwallascan2ban-client`
- `/etc/fwallascan2ban/fwallascan2ban.conf`(如果尚不存在,则从示例复制)
- `/etc/fwallascan2ban/fwallascan2ban.env`(如果尚不存在,则从示例复制)
- `/etc/systemd/system/fwallascan2ban.service`
## 多日志源
单个守护进程实例可以使用配置文件中命名的 `[Log:name]` 部分同时监控最多 8 个日志文件。每个源都有自己的文件路径、`maxretry` 和 `failregex` 模式。至少需要 一个 `[Log:name]` 部分。
```
[Log:tomcat]
log_pattern = /var/log/tomcat10/access_log.%Y-%m-%d.log
maxretry = 3
failregex = ^ - - \[.*\] "(GET|POST|HEAD) .*\.(php|env|git).*"
^ - - \[.*\] "CONNECT .*"
[Log:safeline]
log_pattern = /var/log/safeline-waf/attacks.log
maxretry = 1
failregex = "src_ip":\s*""[^}]*"action":\s*"deny"
```
封禁带有源限定的标签:`auto:tomcat`、`auto:safeline` 等。
### SafeLine WAF 集成
[SafeLine WAF](https://waf.chaitin.com/) 在独立的 VM 上阻止恶意 HTTP 请求。fwallascan2ban 可以通过轮询 SafeLine 开放平台 API 自动在 Firewalla 边界封禁这些 IP。
#### 工作原理
一个轻量级 Python 脚本(`safeline-poll`)作为 systemd 计时器安装,每 60 秒运行一次。它查询 SafeLine REST API 以获取新的拒绝 IP 事件,将每个事件作为 JSON 行写入 `/var/log/safeline-waf/attacks.log`,并在状态文件中记录最高事件 ID 以避免重新处理旧事件。fwallascan2ban 将该日志文件作为 `[Log:safeline]` 源进行监控。
写入文件的日志行格式如下:
```
{"src_ip": "1.2.3.4", "deny_count": 1, "action": "deny", "id": 34}
```
使用 `maxretry = 1`,每个 SafeLine 阻止事件都会立即触发 Firewalla 封禁。
#### 安装 SafeLine 轮询器
在 `/etc/fwallascan2ban/fwallascan2ban.env` 中取消注释并填写 `SAFELINE_API_TOKEN` 和 `SAFELINE_HOST`。API 令牌在 SafeLine 控制台的 **系统 → 开放平台** 下生成——只能看到一次,请立即复制。
然后安装轮询器组件:
```
sudo make install-safeline
```
这将安装:
- `/usr/local/sbin/safeline-poll` — 轮询脚本
- `/etc/systemd/system/safeline-poll.service` — 一次性 systemd 服务
- `/etc/systemd/system/safeline-poll.timer` — 每 60 秒运行一次
在 `/etc/fwallascan2ban/fwallascan2ban.conf` 中添加 `[Log:safeline]` 部分:
```
[Log:safeline]
path = /var/log/safeline-waf/attacks.log
maxretry = 1
log_scan_interval = 0
failregex = "src_ip":\s*""[^}]*"action":\s*"deny"
```
启用并启动计时器,然后重新加载 fwallascan2ban 以加载新的配置部分:
```
systemctl enable --now safeline-poll.timer
fwallascan2ban-client reload
```
卸载 SafeLine 轮询器(保留日志和状态文件):
```
sudo make uninstall-safeline
```
## 配置
### 凭据
编辑 `/etc/fwallascan2ban/fwallascan2ban.env`(chmod 600):
```
# Firewalla MSP(必填)
FW_MSP_DOMAIN=yourname.firewalla.net
FW_MSP_TOKEN=your_personal_access_token
# SafeLine WAF poller(仅在使用 make install-safeline 时需要)
#SAFELINE_API_TOKEN=your_safeline_api_token_here
#SAFELINE_HOST=10.0.0.1
#SAFELINE_PORT=9443
```
您的 MSP 域是登录 MSP 门户时在浏览器中看到的主机名。您的个人访问令牌在门户的账户设置下生成。
只有运行 `make install-safeline` 才需要 SafeLine 变量。详见 [SafeLine WAF 集成](#safeline-waf-integration) 部分。
### 配置文件
编辑 `/etc/fwallascan2ban/fwallascan2ban.conf`。该文件注释详细——请参阅 `fwallascan2ban.conf.example` 以获取每个选项的完整文档。
关键设置:
| 设置 | 描述 | 默认值 |
|---|---|---|
| `box_name` | Firewalla 设备在 MSP 中显示的友好名称 | 必填 |
| `target_list_name` | MSP 目标列表的名称,用于添加被封禁的 IP | 必填 |
| `max_targets` | 每个目标列表的最大 IP 数,超出后创建溢出列表 | 1000 |
| `reconcile_interval` | 定期同步轮次之间的秒数 | 3600 |
每个日志源的设置(必填;每个源一个 `[Log:name]` 部分):
| 设置 | 描述 | 默认值 |
|---|---|---|
| `log_pattern` | 日志文件路径,支持 strftime 格式代码以处理轮转 | 必填 |
| `maxretry` | 封禁 IP 前的模式匹配次数 | 3 |
| `log_scan_interval` | 目录扫描间隔(检测日志轮转) | 60 |
| `failregex` | 一个或多个匹配模式;每个必须包含 `` | 必填 |
### Failregex 模式
模式使用标准 PCRE2 语法。特殊标记 `` 在启动时被替换为匹配 IPv4 和 IPv6 地址的捕获组。语法与 fail2ban 过滤器文件兼容。
Tomcat/Web 服务器的示例模式(放在 `[Log:tomcat]` 中):
```
failregex = ^ - - \[.*\] "(GET|POST|HEAD) .*\.(php|env|git|cgi|sh|sql).*"
^ - - \[.*\] "(GET|POST|HEAD) .*/(wp-admin|wp-content|config|backup).*"
^ - - \[.*\] "CONNECT .*"
^ - - \[.*\] "-" 400 (?:-|\d+)
^ - - \[.*\] "GET .*/manager/html.*" 401 \d+
```
SafeLine WAF 的示例模式(放在 `[Log:safeline]` 中):
```
failregex = "src_ip":\s*""[^}]*"action":\s*"deny"
```
### 忽略列表
在 `[Filters]` 部分的 `ignoreregex` 中添加您自己的 IP、内部网络和受信任的地址,以防止意外封禁。忽略列表全局应用于所有日志源。支持单个 IP 和 CIDR 范围。占位符 IP 和环回地址会自动被忽略。
```
[Filters]
ignoreregex = 192.168.1.0/24
203.0.113.10
```
## 运行
```
systemctl enable --now fwallascan2ban
```
要在启动时从日志开头重新扫描当前日志(捕获守护进程运行前发生的攻击),请在服务文件的 `ExecStart` 中添加 `-r`:
```
ExecStart=/usr/local/sbin/fwallascan2ban -c /etc/fwallascan2ban/fwallascan2ban.conf -r
```
查看日志:
```
journalctl -u fwallascan2ban -f
```
## 客户端命令
`fwallascan2ban-client` 工具通过 Unix socket 与运行的守护进程通信。
| 命令 | 描述 |
|---|---|
| `fwallascan2ban-client status` | 守护进程状态、运行时间、目标列表库存、待处理 IP |
| `fwallascan2ban-client banned` | 所有被封禁的 IP,带有源标签和时间戳,按列表分组 |
| `fwallascan2ban-client banned --fw-rules` | 同上,外加一个单独的部分显示被 Firewalla 单独规则阻止的 IP |
| `fwallascan2ban-client banned --sort-date` | 按日期排序的所有被封禁 IP,最旧的在前(最新的在底部) |
| `fwallascan2ban-client banned --sort-date --fw-rules` | 排序的被封禁 IP,然后是 Firewalla 单独规则 IP 的单独排序部分 |
| `fwallascan2ban-client pending` | 已匹配模式但尚未达到 maxretry 的 IP |
| `fwallascan2ban-client rules` | 显示活动的 failregex 扫描模式和 maxretry 阈值 |
| `fwallascan2ban-client ban ` | 立即手动封禁一个 IP |
| `fwallascan2ban-client unban ` | 从 Firewalla 和本地数据库中移除被封禁的 IP |
| `wallascan2ban-client isbanned ` | 检查 IP 当前是否被封禁;如果是被封禁,则显示源和时间戳 |
| `fwallascan2ban-client testline ''` | 测试原始日志行是否符合所有配置的 failregex 模式(只读——不影响命中计数器);报告匹配的源、提取的 IP、特定匹配的模式以及该 IP 当前的封禁/命中状态 |
| `fwallascan2ban-client reload` | 重新加载配置并触发同步(等同于 SIGHUP) |
| `fwallascan2ban-client rescan` | 切换到最新的日志文件 |
| `fwallascan2ban-client rescan-all` | 从头重新处理当前日志文件 |
## 目标列表溢出
当目标列表达到 `max_targets` 时,守护进程会自动创建带编号的溢出列表(`WebServer-Blocklist-2`、`-3` 等)以及每个列表对应的阻止规则。同步可以在有空间时合并列表。
## 封禁源
被封禁列表中的每个条目都带有源标签:
| 标签 | 含义 |
|---|---|
| `auto:` | 通过日志模式匹配自动封禁(例如 `auto:tomcat`、`auto:safeline`) |
| `manual` | 通过 `fwallascan2ban-client ban` 手动封禁 |
| `firewalla` | 在 Firewalla 目标列表中找到但不在本地数据库中(通过 MSP 门户或移动应用从外部添加) |
| `fw-rule` | 被 Firewalla 单独 IP 阻止规则阻止;从我们的目标列表中移除以释放容量 |
| `placeholder` | 保持 otherwise 空列表存活的占位符 IP(永远不是真正的封禁) |
## 与 Firewalla 自身阻止规则的共存
Firewalla 的威胁情报可能会独立为 fwallascan2ban 通过其目标列表管理的相同地址创建单独的 IP 阻止规则。在每次同步轮次中,fwallascan2ban 检测到这些单独规则后,会自动从其托管的目标列表中移除相应的 IP,为新的封禁释放容量。受影响的 IP 会在本地数据库中记录为 `fw-rule` 源标签。
这意味着:
- **同步主动去重** — 如果 Firewalla 为目标列表中的 IP 添加了单独的阻止规则,下次同步会将其从列表中移除。该 IP 仍会在 Firewalla 级别被阻止。无需任何操作。
- **过滤器引擎被初始化** — 同步后,日志扫描器将所有 `fw-rule` IP 标记为已封禁,因此不会重新处理。如果同一 IP 再次出现在日志中,会被静默忽略。
- **未来同步跳过 `fw-rule` IP** — 它们不会作为"预期在目标列表中"呈现给同步逻辑,因此不会产生重新添加循环。
- **解除封禁** — `fwallascan2ban-client unban ` 从目标列表和本地数据库中移除该 IP,但不会触动任何单独的 Firewalla 阻止规则。该 IP 仍会在 Firewalla 级别被阻止,直到该规则通过 MSP 门户手动移除。
- **如果 Firewalla 移除了单独规则** — 本地数据库中的 `fw-rule` 标签会保留,直到下次日志匹配或手动 `ban` 命令通过正常路径重新添加该 IP。
## 数据库版本控制
本地 `banned.db` 文件包含 `# db_version: 2` 标头(v1.3.0 中引入)。从任何 v1.3.0 之前的版本升级后首次启动时,守护进程会自动检测旧格式并将现有数据库复制到 `banned.db.v1.bak` 后再继续。原始数据被保留,数据库透明升级。
## 文件
| 路径 | 描述 |
|---|---|
| `/etc/fwallascan2ban/fwallascan2ban.conf` | 主配置文件 |
| `/etc/fwallascan2ban/fwallascan2ban.env` | 凭据(MSP 域和令牌) |
| `/etc/fwallascan2ban/rsyslog-safeline.conf.example` | rsyslog 配置示例(备选方案:SafeLine 的 syslog 转发) |
| `/var/lib/fwallascan2ban/banned.db` | 所有被封禁 IP 的本地持久状态 |
| `/var/lib/fwallascan2ban/banned.db.v1.bak` | v1.3.0 之前数据库格式的备份(在首次升级时创建一次) |
| `/run/fwallascan2ban/fwallascan2ban.sock` | 客户端通信的 Unix socket |
| `/usr/local/sbin/safeline-poll` | SafeLine WAF 事件轮询脚本(通过 `make install-safeline` 安装) |
| `/var/log/safeline-waf/attacks.log` | SafeLine 拒绝 IP 事件日志(由 `safeline-poll` 写入) |
| `/var/lib/fwallascan2ban/safeline-poll.state` | 看到的最高事件 ID;防止重新处理旧事件 |
标签:API集成, CISA项目, fail2ban, Firewalla, MSP, PCRE2, Web安全, Web应用防护, XXE攻击, 免杀技术, 入侵防御, 可观测性, 多平台, 威胁防护, 守护进程, 客户端加密, 恶意IP封禁, 暴力破解检测, 正则匹配, 系统加固, 结构化查询, 网络安全, 网络边缘防护, 自动化安全, 蓝队分析, 逆向工具, 防火墙, 隐私保护