外观
🛡️ 行为分析拦截器
📖 简介
行为分析拦截器主要用于检测客户端的异常行为,识别潜在的恶意攻击并进行拦截或记录。它可以作为 SQL 注入拦截器和 XSS 拦截器的前置防线,针对敏感路径扫描、恶意请求方法、路径穿越等特征进行检测。
💡 核心特性
- 敏感路径扫描防护:自动拦截对
/.env、/.git、/wp-admin等常见漏洞扫描路径的访问。 - 非法请求方法防护:拒绝如
TRACE、TRACK、DEBUG等存在安全风险的请求方法。 - 路径穿越防护:检测并拦截带有
../、..\试图突破目录限制的请求。 - 扫描器/爬虫拦截:识别并拦截主流漏洞扫描器或恶意爬虫的 User-Agent (如
sqlmap,nikto,curl等)。 - 非法扩展名检测:预防针对后门/木马等恶意脚本(
.jsp,.php,.exe等)的上传或执行探测。 - XSS 跨站脚本拦截:深度检测并拦截携带恶意前端执行脚本参数的 XSS 攻击请求。
- 常见攻击载荷拦截:快速拦截包含
<script、eval(、union select等特征的异常查询。 - 异常大包拦截 (DoS 防护):限制请求体最大字节数,防止攻击者发送超大 Payload 耗尽网关内存。
- 灵活的动作配置:可配置为直接
block(拦截) 或仅log(记录告警信息)。 - 蜜罐路径(HoneyPot):配置诱饵路径,任何访问即判定为恶意,支持直接封禁 IP。
- 动态频率检测 + 自动封禁:基于 Redis 滑动窗口统计异常行为频率,超阈值自动封禁 IP。
- TLS 指纹检测(JA3):通过前端代理传递的 JA3 Hash 识别恶意客户端 TLS 指纹。
⚙️ 配置说明
在 config.yaml 中,可以通过 gateway.filter.behavior-analysis 进行配置。
基础配置示例
yaml
gateway:
filter:
behavior-analysis:
enabled: true
rules:
- urls:
- "/**"
forbid-urls:
- "/static/**"
action: "block"
# 基础检测
check-sensitive-path: true
check-path-traversal: true
check-malicious-method: true
check-scanner-ua: true
check-illegal-extension: true
check-xss: true
check-common-payload: true
max-body-size: 5242880 # 5MB,超过该大小认为是攻击
# 蜜罐路径(HoneyPot)
honey-pot-urls:
- /admin/config
- /api/.env
- /wp-admin/**
honey-pot-action: auto_ban # block: 仅拦截, auto_ban: 拦截并自动封禁IP
# 自动封禁
auto-ban-enabled: true # 启用动态频率检测自动封禁
auto-ban-threshold: 10 # 窗口内触发阈值(次)
auto-ban-window: 60s # 滑动窗口时长
auto-ban-duration: 10m # 封禁时长
# TLS 指纹检测(JA3)
check-tls-fingerprint: true
tls-fingerprint-header: X-TLS-JA3-Hash
tls-fingerprint-blacklist:
# - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"配置参数详解
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
enabled | boolean | 否 | false | 是否启用行为分析拦截器 |
rules | array | 是 | - | 行为分析规则列表 |
规则 (Rule) 参数详解
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
urls | array | 是 | - | 需要进行行为分析的 URL 路径模式集合(如 /**) |
forbid-urls | array | 否 | - | 排除不进行行为分析的 URL 路径模式集合 |
action | string | 否 | block | 触发策略时的动作:block (拦截返回 403) 或 log (仅打印 Warn 级别日志并放行) |
check-sensitive-path | boolean | 否 | false | 是否检查敏感路径扫描,如 /.env、/.git、/wp-admin 等 |
check-path-traversal | boolean | 否 | false | 是否检查路径穿越,如 ../、..\ 等 |
check-malicious-method | boolean | 否 | false | 是否检查恶意或不常用请求方法,如 TRACE、TRACK、DEBUG |
check-scanner-ua | boolean | 否 | false | 是否检查漏洞扫描器、恶意爬虫、非法脚本程序的 User-Agent (如 sqlmap, nmap, 空UA 等) |
check-illegal-extension | boolean | 否 | false | 是否检查非法文件扩展名,如 .jsp, .php, .asp, .exe, .bat, .dll 等 |
check-xss | boolean | 否 | false | 是否深度检查 XSS 跨站脚本攻击,拦截带有诸如 <iframe, onload=, javascript: 等脚本特征的参数 |
check-common-payload | boolean | 否 | false | 是否检查通用的简单攻击载荷,如 <script、eval(、union select 等 |
max-body-size | int64 | 否 | 0 | 请求体最大字节数,超过该大小则认为是异常大包 DoS 攻击 (设为 0 表示不限制) |
蜜罐路径配置
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
honey-pot-urls | array | 否 | - | 蜜罐路径列表,访问这些路径的请求将被直接判定为恶意并拦截。支持 AntPath 匹配 |
honey-pot-action | string | 否 | block | 蜜罐触发后的处理动作:block (仅拦截), auto_ban (拦截并自动封禁IP,需同时启用 auto-ban-enabled) |
自动封禁配置
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
auto-ban-enabled | boolean | 否 | false | 是否启用动态频率异常检测自动封禁 |
auto-ban-threshold | int | 否 | 10 | 触发自动封禁的阈值次数,同一IP在窗口内被拦截超过此次数即封禁 |
auto-ban-window | string | 否 | 60s | 滑动窗口时长,如 30s、60s、5m |
auto-ban-duration | string | 否 | 10m | 自动封禁时长,如 5m、30m、1h。到期后自动解封 |
TLS 指纹检测配置
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
check-tls-fingerprint | boolean | 否 | false | 是否检查 TLS 指纹 (JA3) |
tls-fingerprint-header | string | 否 | X-TLS-JA3-Hash | 前端代理传递 TLS 指纹的请求头名称 |
tls-fingerprint-blacklist | array | 否 | - | 已知恶意 TLS 指纹 JA3 Hash 黑名单,匹配任一即拦截 |
tls-fingerprint-json-path | string | 否 | - | ja3.me 导出的离线 JSON 文件路径,首次使用时自动加载一次并缓存,与 tls-fingerprint-blacklist 合并使用 |
TLS 指纹检测原理
前端无需任何处理,JA3 是 TLS 协议层的指纹,由 TLS 握手自动生成,浏览器/前端 JS 代码无法干预。
工作流程:
浏览器/客户端 Nginx/HAProxy Go 网关
│ │ │
│── TLS ClientHello ───────>│ │
│ (TLS握手自动生成) │ 解析 ClientHello │
│ │ 计算 JA3 MD5 Hash │
│ │ 设置 X-TLS-JA3-Hash 头 ────>│
│ │ │ 1. 检查 isTlsBanned(动态封禁缓存)
│ │ │ 2. 比对 tls-fingerprint-blacklist
│ │ │ 3. 命中 → 累加指纹计数器
│ │ │ 4. 超阈值 → 封禁指纹(所有IP通用)双层封禁机制:
| 封禁层级 | 触发条件 | 作用范围 | Redis Key |
|---|---|---|---|
| IP 封禁 | 同一 IP 窗口内违规 ≥ 阈值 | 仅封该 IP | wueasy:auto_ban:ip:{ip} |
| 指纹封禁 | 同一 TLS 指纹窗口内被拦截 ≥ 阈值 | 封该指纹(所有 IP) | wueasy:auto_ban:tls:{ja3_hash} |
指纹封禁的优势:攻击者用同一脚本工具(如 Go 爬虫)换 IP 攻击,IP 封禁可能跟不上,但 TLS 指纹不变,指纹级封禁一次性解决。
为什么 User-Agent 可以被伪造,但 JA3 很难?
- User-Agent 是 HTTP 头,一行代码就能改:
curl -H "User-Agent: Chrome" ... - JA3 由 TLS 握手中的密码套件、椭圆曲线、扩展列表等底层参数决定,每种编程语言的 TLS 库实现不同,生成的 JA3 也不同
- 伪造 JA3 需要修改 TLS 库源码或使用特殊代理,成本远高于改 UA
前置条件:需要前端代理传递 JA3
网关是应用层(HTTP),无法直接获取 TLS 握手信息。需要 TLS 终结层的代理(Nginx/HAProxy)传递 JA3 Hash:
nginx
# Nginx 配置(需要 nginx-ssl-fingerprint 模块)
server {
listen 443 ssl;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_set_header X-TLS-JA3-Hash $ssl_ja3; # 传递 JA3 指纹
proxy_pass http://gateway:8080;
}
}haproxy
# HAProxy 配置
frontend https
bind :443 ssl crt /path/to/cert.pem
http-request set-header X-TLS-JA3-Hash %[ssl_fc_ja3]
default_backend gateway已知恶意 TLS 指纹示例:
| 工具 | JA3 Hash(示例) | 说明 |
|---|---|---|
| Go net/http | 2c0c3ed5... | Go 标准库 HTTP 客户端 |
| Python requests | d0a2f6f0... | Python requests 库 |
| curl 7.x | a0e9f5d6... | 命令行 curl |
| Java OkHttp | bfa3f9a4... | Android/Java OkHttp |
实际 Hash 值因 TLS 库版本不同会有差异,建议先用
tcpdump+ ja3.me 或 Wireshark 抓取目标工具的准确 JA3 值。
ja3.me 离线JSON文件配置
可以从 ja3.me 下载离线 JA3 指纹数据库(JSON 格式),配置后网关自动加载并拦截匹配的指纹,无需手动逐条维护黑名单。
JSON 文件格式(ja3.me 导出):
json
[
{
"ja3_hash": "e7d705a3286e19ea42f587b344ee6865",
"ja3_string": "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-...",
"source": "Go-http-client/2.0"
},
{
"ja3_hash": "a0e9f5d64349fb13191b70be95412ba8",
"ja3_string": "771,49195-49199-49196-49200-49171-49172-...",
"source": "curl/7.68.0"
}
]配置示例:
yaml
behavior-analysis:
enabled: true
rules:
- urls: [/**]
check-tls-fingerprint: true
tls-fingerprint-json-path: /etc/gateway/ja3_fingerprints.json # ja3.me 离线文件
tls-fingerprint-blacklist: # 手动补充的黑名单
- "自定义恶意指纹hash"tls-fingerprint-json-path和tls-fingerprint-blacklist同时配置时会合并,不冲突- JSON 文件数据在首次使用时加载一次后永久缓存,更新文件需重启网关生效
🚨 异常处理与日志
当拦截器检测到恶意行为时:
- 会在网关日志中输出
Warn级别的告警信息:🚨 [BehaviorAnalysisFilter] 检测到恶意行为! 攻击类型: Sensitive_Path_Scan, 客户端IP: 192.168.1.100, 载荷/路径: /.env, 请求头User-Agent: curl/7.68.0 - 如果
action为block,将直接向客户端返回 403 状态码及错误信息{"code": 403, "msg": "Access Denied: Suspicious behavior detected"}。
💡 最佳实践
- 建议在生产环境中始终开启
check-sensitive-path和check-path-traversal,因为这几乎不会产生误杀,能有效阻挡大量自动化的黑客扫描器。 - 如果您的应用是纯接口(API),强烈建议开启
check-malicious-method,只放行常用的GET,POST,PUT,DELETE等方法。 - 对于误杀敏感的业务,可以先将
action设置为log观察一段时间日志,确认没有正常请求被拦截后,再修改为block。 - 蜜罐路径推荐配置不存在于业务中的虚拟路径(如
/admin/.env、/api/debug),正常用户永远不会访问,命中即 100% 恶意。 - 自动封禁建议先用较小的
auto-ban-threshold(如 5)和较短的auto-ban-duration(如 5m)验证,避免误封正常用户。确认无误后再调整阈值。 - TLS 指纹检测需要配合前端代理(Nginx/HAProxy)将 JA3 Hash 通过
X-TLS-JA3-Hash请求头传递到网关。黑名单指纹可以通过抓取已知恶意工具的 TLS 指纹获取。
🔗 配置文件结构
yaml
gateway:
filter:
behavior-analysis:
enabled: true
rules:
- urls: # 匹配的请求路径 (AntPath)
forbid-urls: # 排除的路径
action: # block / log
check-sensitive-path: # 敏感路径扫描
check-path-traversal: # 路径穿越
check-malicious-method: # 非法请求方法
check-scanner-ua: # 爬虫/扫描器 UA
check-illegal-extension: # 非法文件扩展名
check-xss: # XSS 跨站脚本
check-common-payload: # 通用攻击载荷
max-body-size: # DoS 大包限制(字节)
honey-pot-urls: # 蜜罐路径列表
honey-pot-action: # 蜜罐动作: block / auto_ban
auto-ban-enabled: # 启用自动封禁
auto-ban-threshold: # 封禁阈值(次)
auto-ban-window: # 滑动窗口时长
auto-ban-duration: # 封禁时长
check-tls-fingerprint: # TLS 指纹检测
tls-fingerprint-header: # JA3 请求头名称
tls-fingerprint-blacklist: # 恶意指纹黑名单