当前位置:首页 > 技术分享

Nginx 开源免费 WAF 防火墙宝塔插件 新增PHP2Shell 防护

admin1小时前技术分享7

基于 OpenResty (ngx_lua) 的高性能 Web 应用防火墙,宝塔面板(BT Panel)插件。

ScreenShot_2026-10-23_113312_836.png

Gitee 仓库:

https://gitee.com/web/bt_ngx_lua_waf

php2shell漏洞防护指南 (2).jpg



目录


功能特性

  • 极低磁盘 IO 运行时:init_by_lua 阶段一次性加载所有配置和规则到内存,access_by_lua 阶段纯内存匹配,仅拦截日志同步直写(对齐 free_waf),性能接近原生 Nginx

  • CC 攻击防护:基于 shared_dict 的滑动窗口频次统计 + CC2 挑战验证,支持自定义阈值、检测周期、自适应封禁时长、自动永久拉黑阈值、每小时请求硬上限

  • 恶意 HEAD 零容忍拦截:首次命中即封 IP(对齐 free_waf),爬虫 UA 和白名单 URI 放行

  • 多维度攻击拦截:URL 路径、URL 黑名单、GET 参数、POST 内容、Cookie、User-Agent、扫描器特征头

  • IP 黑白名单:支持精确 IP 匹配及 IP 段范围匹配,独立响应状态码

  • 海外 IP 拦截:基于国内 IP 段列表自动拦截海外访问(含 SSL 验证 IP 白名单豁免)

  • 文件上传保护:禁止上传目录脚本执行 + 全局/站点两级扩展名黑名单

  • ThinkPHP 漏洞防护:内置 ThinkPHP 5.x RCE 和 3.x 日志泄露防护规则

  • PHP2Shell 防护:双层防御 multipart 请求滥用——POST 规则层检测空字节注入/嵌套 multipart/超长 Disposition,Content-Type 层校验 boundary 合法性(缺失/空/超长/控制字符/重复),防护 CVE-2026-109618/9

  • 域名映射表:domains.json 构建 O(1) 精确查找,自动将绑定域名(如 www.example.com)归一化到站点主名

  • 站点级独立配置:全局 → 站点三态配置(开启/关闭/继承),每个站点可单独启停任意防护模块

  • 站点专属防护:每个站点可配置专属 URL 白名单、禁止 PHP 路径、禁止路径访问、禁止扩展名、URI 自定义拦截规则(url_rule_ex)、URI 参数校验(url_tell)

  • 规则精准跳过:基于 hash set 的 disable_rule 机制,O(1) 时间复杂度跳过指定站点的禁用规则

  • CDN / 反向代理支持:自定义 cdn_header 从请求头获取真实客户端 IP,支持多头部按顺序回溯

  • 系统防火墙集成:支持将 IP 封禁同步写入 iptables / firewalld / ufw,实现全端口封锁

  • 分类拦截模板:GET、POST、Cookie、User-Agent 各模块独立拦截页面和 HTTP 状态码

  • 统计与日志:分类统计每个模块和每个站点的拦截数,JSON 格式日志含完整 HTTP 请求包

  • 安全锁机制:IP 封禁时使用 shared_dict:add 实现并发安全的一次性封锁,避免重复写文件

  • 自动重载生效:Python 后端每次修改配置自动执行 nginx -t && nginx reload,零停机热更新


运行原理

┌─────────────────────────────────────────────────────────────────┐
│                        Nginx 启动 / reload                      │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │  init_by_lua_file  →  init.lua                          │    │
│  │  • 加载 config.json / site.json 到全局变量              │    │
│  │  • 加载 rule/*.json 规则文件到内存数组                  │    │
│  │  • 预加载 html/*.html 拦截模板                          │    │
│  │  • 加载 domains.json → 构建 domains_map (O(1) 域名归一) │    │
│  │  • 初始化 shared_dict 统计计数 + 历史恢复与校准         │    │
│  │  • 构建站点级 disable_rule hash set                     │    │
│  │  • 提取站点专属白名单 / PHP禁止路径 / 禁止上传扩展名    │    │
│  └─────────────────────────────────────────────────────────┘    │
│                            ↓                                     │
│  access_by_lua_file  →  waf.lua                                 │
│  • 纯内存匹配,仅拦截日志同步直写,零 JSON 解析                 │
│  • domains_map O(1) 归一化绑定域名 → 站点主名                  │
│  • get_effective_cfg() 合并全局开关 + 站点三态配置              │
│  • 短路匹配:规则命中即返回,后续规则不再遍历                   │
│  • shared_dict 实现 IP 封禁、CC 计数、自动永久拉黑              │
└─────────────────────────────────────────────────────────────────┘

请求过滤流程

请求进入(domains_map 归一化域名 → 加载生效配置)
  │
  ├─► ① IP 白名单 → 放行
  │
  ├─► ② IP 黑名单 → 拦截
  │
  ├─► ③ 已封锁 IP(drop 检查)→ 拦截
  │
  ├─► ④ URL 白名单 → 放行
  │
  ├─► ⑤ 恶意 HEAD 请求拦截 → 拦截(零容忍,首次命中即封IP)
  │
  ├─► ⑥ URL 黑名单检查 → 拦截
  │
  ├─► ⑦ 海外 IP 拦截(SSL验证IP豁免)→ 拦截
  │
  ├─► ⑧ CC 攻击检测(滑动窗口 + CC2挑战验证 + 自动永久拉黑)→ 拦截
  │
  ├─► ⑨ 扫描器特征检测(Cookie/Header/Args)→ 拦截
  │
  ├─► ⑩ UA 恶意规则 → 拦截
  │
  ├─► ⑪ URL 路径规则 → 拦截
  │
  ├─► ⑫ GET 参数规则 → 拦截
  │
  ├─► ⑬ Cookie 规则 → 拦截
  │
  ├─► ⑭ ThinkPHP 漏洞防护(5.x RCE + 3.x 日志泄露)→ 拦截
  │
  ├─► ⑮ PHP2Shell 防护(multipart boundary 合法性校验)→ 拦截
  │
  ├─► ⑯ POST 检查(内容攻击 + 文件上传扩展名黑名单 + disable_rule 跳过)→ 拦截
  │
  ├─► ⑰ 站点级自定义规则(PHP禁止路径 / 禁止路径 / 禁止扩展名 / url_rule / url_tell)→ 拦截
  │
  └─► 放行

每个环节命中即短路返回,不做多余检查,最大化性能。模块开关由 get_effective_cfg() 根据全局配置与站点三态配置计算得出。


文件结构

bt_ngx_waf/
├── info.json                        # 宝塔插件元数据(版本、作者、安装入口)
├── install.sh                       # 安装 / 更新 / 卸载脚本
├── migrate.py                       # 配置补全脚本(通用默认值补全,对齐 free_waf 模式)
├── bt_ngx_waf_main.py               # Python 后端 API(面板数据读写 + 自动生成 domains.json + 系统防火墙集成)
├── index.html                       # 前端管理界面
├── icon.png                         # 插件图标
├── conf/
│   └── bt_ngx_waf.conf              # Nginx 配置片段(shared_dict + lua hook)
└── data/
    ├── config.json                  # 全局配置模板
    ├── site.json                    # 站点级配置存储(支持多站点 + 三态继承)
    ├── domains.json                 # 域名映射表(Python 后端自动生成)
    ├── total.json                   # 统计计数持久化(含分类计数 + 站点级计数 + 校准)
    ├── drop_ip.log                  # IP 封禁历史日志
    ├── operation.log                # 操作日志
    ├── lua/
    │   ├── init.lua                 # 初始化脚本(init_by_lua,仅 reload 时执行)
    │   ├── waf.lua                  # 请求过滤主逻辑(access_by_lua,每请求执行 + API 端点分流)
    │   └── api.lua                  # Lua 端 API 接口(仅 127.0.0.1 可访问,已整合进 waf.lua handle_api)
    ├── rule/
    │   ├── args.json                # GET 参数规则(SQL注入/XSS等)
    │   ├── cookie.json              # Cookie 攻击规则
    │   ├── ip_black.json            # IP 黑名单(支持精确匹配和IP段)
    │   ├── ip_white.json            # IP 白名单
    │   ├── post.json                # POST 内容规则
    │   ├── url.json                 # URL 路径规则
    │   ├── url_black.json           # URL 黑名单规则(独立于 url 规则)
    │   ├── url_white.json           # URL 白名单规则
    │   ├── whiteurl.json            # URL 白名单规则(兼容旧版命名)
    │   ├── user_agent.json          # User-Agent 规则(恶意爬虫/扫描器)
    │   ├── scan_black.json          # 扫描器特征规则(Cookie / Header / Args)
    │   ├── head_white.json          # HEAD 请求白名单规则(爬虫UA自动放行)
    │   └── cn.json                  # 国内 IP 段列表(海外拦截用)
    └── html/
        ├── get.html                 # GET/URL 拦截页面
        ├── post.html                # POST 拦截页面
        ├── cookie.html              # Cookie 拦截页面
        └── user_agent.html          # UA 拦截页面

运行时目录(安装后):

/www/server/bt_ngx_waf/
├── lua/*.lua           # Lua 脚本(来自 data/lua/)
├── rule/*.json         # 规则文件(来自 data/rule/,保留用户自定义)
├── html/*.html         # 拦截模板(来自 data/html/,保留用户自定义)
├── config.json         # 全局配置(面板修改后自动 reload)
├── site.json           # 站点配置
├── domains.json        # 域名映射表(Python 后端写入,与 site.json 同步)
├── total.json          # 统计持久化
└── drop_ip.log         # IP 封禁历史

规则格式

规则文件采用 JSON 数组格式,每条规则为一个子数组:

[启用状态, "正则表达式", "规则说明", 是否自定义]
字段类型说明
启用状态number1 = 启用,0 = 禁用
正则表达式stringPCRE 正则语法,自动添加 ijo flag(不区分大小写、UTF-8、优化)
规则说明string中文描述,便于在面板管理
是否自定义number0 = 官方内置,1 = 用户自定义

示例:

[
  [1, "(?:select|union|insert|update|delete)\\s+", "SQL注入", 0],
  [1, "<script.*?>", "XSS攻击", 1],
  [0, "已禁用的规则", "这条不会生效", 0]
]

IP 黑白名单(ip_black.json / ip_white.json)支持两种格式:

[  "192.168.1.1",  "10.0.0.1",
  [ [173, 224, 195, 2], [173, 224, 195, 10] ],
  [ [203, 106, 0, 1], [203, 106, 0, 255] ]
]

配置说明

全局配置 (config.json)

字段类型默认值说明
versionnumber3配置文件版本号
openbooleantrueWAF 总开关
logbooleantrue攻击日志开关
log_dirstring/www/wwwlogs/bt_ngx_waf/日志存储目录
log_savenumber30日志保留天数
Redirectbooleantrue拦截后是否返回 302 跳转
post_max_sizenumber10485760POST Body 最大字节数(10MB)
retrynumber5N 秒内累计多少次拦截后封锁 IP
retry_cyclenumber60N 秒统计周期
retry_timenumber600基础封锁时长(秒),多次累积自适应延长
black_fileExtarray["php", "jsp"]全局禁止上传脚本扩展名
ipWhitelistarray["127.0.0.1"]全局 IP 白名单(可在 rule/ip_white.json 扩展)
ipBlocklistarray[]全局 IP 黑名单(可在 rule/ip_black.json 扩展)
cc.openbooleantrueCC 防护开关
cc.limitnumber100周期内最大请求次数
cc.cyclenumber60检测周期(秒)
cc.endtimenumber300基础 CC 封锁时长(秒)
cc.statusnumber444CC 拦截 HTTP 状态码
cc.auto_black_countnumber4被 CC 拦截累计达 N 次后升级为永久拉黑(TTL=0,0=关闭)
cc.force_black_per_hournumber36000每小时请求硬上限,超过直接永久拉黑(0=关闭)
head.openbooleantrue恶意 HEAD 请求拦截开关(首次命中即封 IP,爬虫 UA 放行)
head.statusnumber444HEAD 请求拦截状态码
get.openbooleantrueGET/URL 模块总开关
get.statusnumber403GET/URL 拦截状态码
url.openbooleantrueURL 路径规则开关
url.statusnumber403URL 拦截状态码
url.reqfilestringget.htmlURL 拦截模板
args.openbooleantrueGET 参数规则开关
args.statusnumber403GET 参数拦截状态码
args.reqfilestringget.htmlGET 参数拦截模板
post.openbooleantruePOST 规则开关
post.statusnumber403POST 拦截状态码
post.reqfilestringpost.htmlPOST 拦截模板
cookie.openbooleantrueCookie 规则开关
cookie.statusnumber403Cookie 拦截状态码
cookie.reqfilestringcookie.htmlCookie 拦截模板
user_agent.openbooleantrueUser-Agent 规则开关
user_agent.statusnumber403UA 拦截状态码
user_agent.reqfilestringuser_agent.htmlUA 拦截模板
white_module.openbooleantrueURL 白名单开关
scan.openbooleantrue扫描器防护开关
scan.statusnumber444扫描器拦截状态码
drop_abroad.openbooleanfalse海外 IP 拦截开关
drop_abroad.statusnumber444海外 IP 拦截状态码
block.statusnumber444IP 被封锁后的拦截状态码
ipBlocklist_statusnumber444IP 黑名单拦截状态码
from_databooleantrue是否记录 multipart form-data 完整数据到日志
php2shell.openbooleantruePHP2Shell 防护开关(multipart boundary 合法性校验)
php2shell.boundary_max_lennumber70boundary 最大允许长度(RFC 2046 规定 70 字节)
php2shell.statusnumber403PHP2Shell 拦截 HTTP 状态码

站点配置 (site.json)

每个站点字段支持三态配置:null = 继承全局,true = 强制开启,false = 强制关闭

{  "example.com": {    "open": true,    "cdn": false,    "cdn_header": ["x-forwarded-for", "x-real-ip"],    "cc": { "open": true, "limit": 80, "cycle": 30, "endtime": 600, "auto_black_count": 4, "force_black_per_hour": 36000 },    "disable_rule": {      "args": [2, 5],      "post": [1]
    },    "whiteurl": ["^/api/public/", "^/upload/"],    "disable_php_path": ["^/uploads/", "^/data/"],    "disable_upload_ext": ["php", "jsp", "asp", "exe"],    "disable_path": ["^/admin/backup/", "^/config/"],    "disable_ext": ["bak", "sql", "ini"],    "url_rule": [["^/api/order", "price.*=.*99999"], ["^/api/user", "role.*=.*admin"]],    "url_tell": [["^/api/internal", "token", "secret123"]],    "scan": true,    "drop_abroad": false,    "head": true,    "retry": 3,    "retry_time": 300,    "retry_cycle": 60
  }
}
字段类型说明
openboolean/null站点 WAF 总开关
cdnboolean/null是否启用 CDN 模式(从请求头获取真实 IP)
cdn_headerarray/nullCDN 真实 IP 头名称列表,按顺序回溯
cc.openboolean/null站点级 CC 防护开关
cc.limitnumber/null周期内最大请求次数
cc.cyclenumber/null检测周期(秒)
cc.endtimenumber/null基础 CC 封锁时长(秒)
cc.auto_black_countnumber/null被 CC 拦截累计达 N 次后升级为永久拉黑
cc.force_black_per_hournumber/null每小时请求硬上限,超过直接永久拉黑(0=关闭)
cc.increaseboolean/null是否开启 CC2 挑战验证模式
disable_ruleobject/null站点禁用的规则索引({args: [0,1], post: [2]}),O(1) hash set 跳过
whiteurlarray/null站点专属 URL 白名单正则(命中则跳过所有检查)
disable_php_patharray/null禁止 PHP 解析的路径正则(如 ^/uploads/)
disable_upload_extarray/null站点专属禁止上传扩展名(覆盖全局 black_fileExt)
disable_patharray/null禁止直接访问的路径正则(如备份目录、配置目录)
disable_extarray/null禁止直接访问的文件扩展名(如 .bak、.sql)
url_rulearray/null站点级 URI 自定义拦截 [[uri_pattern, params_regex], ...]
url_tellarray/null站点级 URI 参数校验 [[uri_pattern, param_name, expected_value], ...],实际值≠预期值则拦截
scanboolean/null扫描器防护开关
drop_abroadboolean/null海外 IP 拦截开关
headboolean/null恶意 HEAD 请求拦截开关
retry / retry_cycle / retry_timenumber/nullIP 封禁参数(覆盖全局)

安装部署

前置条件

  • Nginx / OpenResty:必须编译 lua-nginx-module 支持

  • Lua 版本:5.1+(与 OpenResty 内置一致)

  • 宝塔面板:7.x / 8.x / 正式版均可

  • 互斥说明:不能与宝塔 free_waf 插件共存

安装步骤

# 方式一:通过宝塔面板插件市场直接安装https://gitee.com/web/bt_ngx_lua_waf/releases/download/latest/bt_ngx_waf.zip# 方式二:源码部署cd /www/server/panel/plugin/bt_ngx_waf
bash install.sh install# 方式三:更新现有安装bash install.sh update# 卸载bash install.sh uninstall

安装脚本做了什么

  1. 创建 /www/server/bt_ngx_waf/ 运行目录和 /www/wwwlogs/bt_ngx_waf/ 日志目录

  2. 拷贝 Lua 脚本、规则文件、HTML 模板(保留用户已修改的文件)

  3. 写入 bt_ngx_waf.conf 到 Nginx 虚拟主机配置目录

  4. 自动 nginx -t && nginx reload 生效

手动生效(可选)

# 如果安装脚本自动重载失败,手动执行/etc/init.d/nginx configtest && /etc/init.d/nginx reload# 验证 shared_dict 是否加载curl -s http://127.0.0.1/bt_ngx_waf_api?action=ping# 应返回 {"status":"ok"}

热更新配置

修改任何配置文件(config.json / site.json / rule/*.json)后:

/etc/init.d/nginx reload

规则和配置在 init_by_lua 阶段重新加载到内存,零停机生效。


API 接口

Lua 端 API(仅限 127.0.0.1)

仅限 127.0.0.1 内网访问,防止外部探测。在 waf.lua 的 API 端点分流中统一处理。

访问方式:http://127.0.0.1/bt_ngx_waf_api?action=xxx

接口说明
?action=ping健康检查,返回 {"status":"ok"}
?action=get_total获取全局拦截统计(总数 + 分类计数 + 站点级计数 + 启动时间)
?action=get_site_total&siteName=xxx获取指定站点的拦截统计(含所有分类计数)
?action=get_drop_ip获取当前活跃的封禁 IP 列表(从 bt_ngx_waf_drop 字典遍历)
?action=remove_drop_ip&ip=xxx解除指定 IP 的封禁(同时清理 bt_ngx_waf_drop 和 bt_ngx_waf_cc)
?action=clean_drop_ip清空所有封禁 IP(同时清理两个字典的封锁记录)

Python 后端管理接口

bt_ngx_waf_main.py 提供完整的管理接口(通过宝塔面板前端调用),每次写配置自动执行 nginx -t && nginx reload:

全局配置类

接口说明
getConfig读取全局配置
saveConfig保存全局配置
get_html_tpl获取拦截模板内容
save_html_tpl保存拦截模板

站点配置类

接口说明
getSiteConfig读取所有站点配置
saveSiteConfig保存所有站点配置(自动同步生成 domains.json)
getSiteConfig_byname&siteName=xxx按名称读取单个站点配置
getSiteDetail&siteName=xxx获取站点详情(含域名列表)
getSiteRule&siteName=xxx获取站点专属规则
addSiteRule&siteName=xxx添加站点专属规则(url_rule_ex / url_tell / disable_path 等)
getSiteDisableRule&siteName=xxx获取站点禁用的规则索引列表
addSiteDisableRule&siteName=xxx添加站点禁用规则索引
addSiteWhiteurl&siteName=xxx添加站点专属 URL 白名单
getSiteCdnHeader&siteName=xxx获取站点 CDN 真实 IP 头配置
addSiteCdnHeader&siteName=xxx保存站点 CDN 真实 IP 头配置

规则管理类

接口说明
getRule&name=xxx读取指定类型规则文件(args/post/url/cookie/user_agent 等)
saveRule&name=xxx保存规则文件
addRule添加自定义规则(指定 type + pattern + description)
deleteRule删除自定义规则
saveScanRule保存扫描器特征规则(scan_black.json)
saveHeadWhite保存 HEAD 请求白名单规则(head_white.json)
addUrlWhite添加全局 URL 白名单规则
addUrlBlack添加全局 URL 黑名单规则
addIpWhite添加 IP 白名单
addIpBlack添加 IP 黑名单
addCnip添加国内 IP 段(扩展 cn.json)

系统防火墙集成

接口说明
addFirewallBlackIp&ip=xxx将 IP 同步写入系统防火墙(自动检测 iptables / firewalld / ufw),实现全端口封锁

统计与日志类

接口说明
getTotal获取全局拦截统计(从 shared_dict 读取)
getTotalAll获取全量拦截统计数据
getLogs / getGlLogs获取攻击日志列表(解析 {site}_{date}_sec.log)
getLog&siteName=xxx&date=xxx获取指定站点指定日期的攻击日志
getLogsList获取日志文件列表
cleanLogs清理过期日志文件
getSafeLogs / getSafeLogsIp获取 IP 封锁历史(解析 drop_ip.log)
getBlockHistory获取封锁历史详情
cleanWafDropIp清空所有活跃封禁 IP(同步清理 shared_dict)
cleanDropHistory清空封禁历史日志(drop_ip.log)

测试工具

项目根目录提供 test_waf.php 全功能测试工具,用于验证 WAF 各模块拦截效果和误拦截情况。

部署与使用

# 将 test_waf.php 放到任意被 WAF 保护的站点根目录cp test_waf.php /www/wwwroot/example.com/test_waf.php# 浏览器访问http://example.com/test_waf.php

打开后在页面顶部输入目标站点地址,即可开始测试。

测试模式

模式说明
一键全测自动运行所有测试用例,输出通过/失败汇总
分步测试手动选择单项测试,逐条验证
误拦截检测发送正常请求,验证 WAF 不会误拦

测试覆盖范围

分组用例数说明
GET 参数攻击8SQL 注入、XSS、PHP 危险函数、目录穿越、SSRF
URL 路径攻击8敏感文件(phpinfo/.svn/.git/shell.sql)、ThinkPHP、composer、phpMyAdmin
UA 攻击5sqlmap/nmap/nikto/hydra 恶意 UA + 正常 UA 放行
Cookie 攻击2Cookie 中 SQL 注入、XSS
POST 攻击2POST 中 SQL 注入、eval
特殊请求2正常 HEAD 放行 + 恶意 HEAD 拦截
站点自定义规则3url_rule_ex / url_tell 拦截 / url_tell 放行
封锁机制1连发恶意请求验证 IP 封锁闭环
误拦截检查5正常首页/参数/POST/文件上传 + 正常 UA
恶意扫描3扫描器特征 Args / Header / Cookie
禁止的扩展名3.php/.jsp/.bak 上传或访问
恶意文件上传1自定义禁止扩展名上传
禁止 PHP 脚本1禁止 PHP 解析路径测试
禁止路径访问1禁止目录访问测试
PHP2Shell 防护10第一层 post.json 规则(4) + 第二层 boundary 校验(5) + 正常 multipart 放行(1)

拦截判定逻辑

WAF 拦截可能返回以下状态,测试工具据此判定:

状态说明
403规则命中拦截
503IP 封锁拦截(drop)
444海外 IP / 直接断开连接
code=0 + curl 错误WAF 直接 RST 断连,curl 收不到 HTTP 响应

技术要点

性能设计

  • 极低磁盘 IO(请求阶段):init_by_lua 阶段完成所有配置和规则文件读取,access_by_lua 阶段仅操作内存变量和 shared_dict,唯一磁盘 IO 为拦截日志同步直写(对齐 free_waf,避免 worker 段错误)

  • 短路匹配:规则命中即返回,后续规则不再遍历

  • Hash set 跳过:disable_rule 使用 Lua table 构建 hash set,O(1) 判断站点是否跳过某规则

  • 预加载模板:HTML 拦截模板在 init_by_lua 阶段一次性读入内存变量

  • lazy init:arrip() 等字符串处理函数延迟到真正需要时才执行

shared_dict 隔离

使用四个独立的共享内存字典,避免与其他插件或应用冲突:

字典名用途默认大小
bt_ngx_waf统计计数、分类统计、站点级统计20m
bt_ngx_waf_ccCC 攻击频次统计、CC2 挑战验证10m
bt_ngx_waf_dropIP 封禁记录、并发安全锁10m
bt_ngx_waf_drop_sumIP 封禁累计次数(用于自适应延长)10m

安全锁机制

IP 封禁时使用 shared_dict:add(lock_key, 1, 1) 实现分布式安全锁:

  • 只有拿到锁的那个请求执行实际封禁和写日志

  • 其他并发请求检测到锁后只更新状态,避免重复写文件

日志写入方式

拦截日志采用同步直写(对齐 free_waf):命中规则后立即通过 io.open 追加写入日志文件,不使用异步定时器或队列缓冲,避免 worker 段错误(signal 11)。安全锁机制保证同一时刻只有一个请求执行写操作,避免并发重复写入。

access 阶段的 IO 限制

操作是否允许说明
io.open() / io.close()仅限日志写入拦截日志同步直写是唯一允许的磁盘 IO,其他场景禁止
cjson.decode()禁止JSON 解析耗时,应在 init 阶段完成
socket.connect()禁止网络 IO 阻塞
ngx.location.capture()禁止可能导致请求嵌套死循环

与 free_waf 的关系

bt_ngx_waf 与宝塔 free_waf 是互斥的两个防火墙插件,架构上有以下区别:

对比项bt_ngx_waffree_waf
基础Lua 全量重写传统 Nginx + Lua 混合
运行时磁盘 IO仅拦截日志同步直写有(规则逐行读取 + 日志写入)
配置格式JSON(结构化)纯文本(每行一条规则)
规则加载init 阶段一次性载入数组access 阶段逐行遍历文件
站点级配置完整三态继承基础支持
CC 防护滑动窗口 + CC2 挑战基础频次限制
依赖OpenResty + lua-cjsonOpenResty + lua-cjson

本项目参考了 ngx_lua_waf 和 free_waf 的防护逻辑,结合现代 OpenResty 最佳实践进行了重构优化。

关于 webshell 查杀模块

bt_ngx_waf 未实现 webshell 查杀模块。如需服务器端木马检测功能,请到宝塔面板插件市场搜索 "木马检测" 插件安装使用。


许可证

本项目基于开源许可证发布,具体请查看仓库中的 LICENSE 文件。


扫描二维码推送至手机访问。

版权声明:本文由小刚刚技术博客发布,如需转载请注明出处。

本文链接:https://blog.bitefu.net/post/770.html

分享给朋友:

“Nginx 开源免费 WAF 防火墙宝塔插件 新增PHP2Shell 防护” 的相关文章

解决 SVN Skipped 'xxx' -- Node remains in conflict

更新命令:svn up提示代码:意思就是说 ,这个文件冲突了,你要解决下Updating '.': Skipped 'data/config.php' -- …

[教程] WTG备份新方法——FFU镜像格式

[教程] WTG备份新方法——FFU镜像格式

FFU(Full Flash Update) 格式是一种基于扇区的磁盘镜像文件格式,默认使用快速哈夫曼压缩(Xpress-Huffman)算法压缩,在捕获和部署时会生成哈希表进行校验,并可以使用DISM修改捕获的镜像。FFU格式很适合WTG…

微软版Ghost Win10:FFU映像备份和还原

微软版Ghost Win10:FFU映像备份和还原

在日常的维护中,系统的备份和还原是大家经常需要操作的事情。虽然Windows 10已经提供很多的工具,如系统还原、WIM备份/还原,VHD备份等。不过这些工具大多是基于文件的备份/还原。我们以前经常的使用的Ghost则是基于扇区的备份/还原…

遭遇国外ip抓取或攻击怎么办一招解决禁止海外IP访问

遭遇国外ip抓取或攻击怎么办一招解决禁止海外IP访问

究发现很多网站被攻击都是来自海外的肉鸡,所以禁掉海外IP访问网站也是不错的防护手段,而且国内网站几乎很少有国外用户访问,称之为大局域网也不为过。今天主机吧来教大家如何利用域名解析禁止掉海外IP访问网站。绝大多数域名解析服务商都是提供电信联通…

Nginx服务崩溃自动重启脚本(监控进程服务并自动重启进程服务)脚本

有一台服务器运行着Ngin最近突然有一次崩溃,导致使用方当天无法访问网页端,然后我不得不登录服务器,检查各项服务,发现nginx崩溃了,于是重启Nginx,问题解决。后来为了防止Nginx再发生这种情况给运维带来的运维成本,于是写了一个脚本…

用CMD命令查询域名的DNS解析记录:A,NS,MX,CNAME,TXT

1、查询域名的A记录nslookup -qt=A bitefu.net当然查询A记录你直接用ping命令来ping域名也可以获得A记录。2、查询域名的NS记录nslookup -qt=NS bitefu.net3、查询域名的MX记录nslo…

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。