3 Star 14 Fork 7

克莱里昂/easy_ngx_waf

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
README.md 40.62 KB
一键复制 编辑 原始数据 按行查看 历史

easy_ngx_waf

应用于 nginxwaf (建议用 openresty

项目由来:

bt面板相信很多人都不陌生也有用过(或正在用),这无疑是一个很好的产品,为广大站长提供了极其方便的管理功能(包括有免费的WAF功能),但同时也有大家都知道的问题(懂得自然懂的)。

之前也一直使用一键包,但最近(2023年9月 10月)爆出两大流行脚本都被同一公司收购且脚本有被投DU情况,为此我也改用纯手动安装方式。

针对 WAF 这块,之前基于 loveshell/ngx_lua_waf 改造了一个 cls_lua_waf 项目,此项目也是为了学习下 lua 及熟悉下 openresty ,故功能也比较简单。

在研究了下 ModSecurity 后,就想将其规则相关的设计借鉴一下(本项目在规则设计这块进行了相当的简化),于是就有了当前这个项目。(同时当前项目中一些功能也借鉴了 bt WAF中的部分功能设计)

功能特点

  • 防护功能:见 检测流程 中各个检测阶段;

  • 简单易写的规则文件

    (说明请参见 rules/README.mdeasy_ngx_waf_rule 项目);

  • IP检测 全面支持 IPv4IPv6CIDR 格式;

  • SEO 爬虫放行,避免误拦截

    (说明请参见 rules/spider/README.mdeasy_ngx_waf_rule 项目);

  • 可指定域名取消WAF检测,针对同时拥有多域名的服务器更加灵活;

    • 支持指定 "具体域名" / "通配符域名"
    • 支持 "全局" / "某一检测阶段" 取消WAF检测

检测流程

IP白名单、IP黑名单、UA白名单、URL白名单、URL过滤、UA+IP蜘蛛校验、境外IP过滤、UA过滤、CC攻击检测、COOKIE过滤、GET参数、POST参数过滤、HEADER过滤

<img alt="waf检测流程">

目录结构

./easy_ngx_waf/  # 项目根目录
   |   .gitignore
   |   access.lua    # access_by_lua_file 对应的文件
   |   config.lua    # easy_ngx_waf 配置文件
   |   init.lua      # init_by_lua_file 对应的文件
   |   log.lua       # log_by_lua_file 对应的文件
   |   README.md
   |   report.lua    # 当前waf概要报告;详见文件内容有说明;
   |
   +---data/      # 数据目录
   |       Country.mmdb  # geoip数据文件
   |
   +---lib/       # 工具库目录
   |   |   ccutil.lua          # CC检测 工具调用类
   |   |   cc_redis.lua        # CC检测 redis存储的具体实现
   |   |   cc_shared_dict.lua  # CC检测 shared_dict存储的具体实现
   |   |   cls_redis.lua       # redis封装
   |   |   post.lua            # post请求相关解析工具
   |   |   string_util.lua     # string工具类(修改自项目https://github.com/stein197/lua-string)
   |   |   util.lua            # 工具类
   |   |
   |   +---rule_core/  # 规则解析库
   |   |       act.lua
   |   |       host.lua
   |   |       operator.lua
   |   |       rule.lua
   |   |       value.lua
   |   |       var.lua
   |   |
   |   \---packages/    # 第三方lua模块目录(文件说明详见该目录下README)
   |
   \---rules/     # 主规则目录(文件说明详见该目录下README;此目录下所有文件可通过easy_ngx_waf_rule项目覆盖更新)
   |   |   .gitignore
   |   |   demo.rule      # 规则演示文件
   |   |   README.md
   |   |
   |   +---simple/   # 简单规则文件目录
   |   |       args             # query参数过滤规则
   |   |       cookie           # cookie过滤规则
   |   |       ip_black         # IP黑名单
   |   |       ip_white         # IP白名单
   |   |       post             # post参数过滤规则
   |   |       url              # url过滤规则
   |   |       url_white        # url白名单
   |   |       user_agent       # user-agent过滤规则
   |   |       user_agent_white # user-agent白名单
   |   |
   |   \---spider/   # 蜘蛛数据目录(文件格式说明详见该目录下README)
   |   |   README.md
   |   |       ......
   |
   +---rules_custom/   # 用户自定义规则目录(文件说明详见该目录下README)
   |   |   .gitignore
   |   |   README.md
   |   |   custom_demo.rule  # 用户自定义规则演示文件
   |   |
   |   +---simple/   # 用户自定义:简单规则文件目录
   |   |       ......    # 文件列表同主规则目录下的简单规则文件列表相同
   |   |
   |   \---spider/   # 用户自定义:蜘蛛数据目录
   |           myself.data   # 用户自定义蜘蛛数据演示文件
   |
   \---tpl/    # 模板目录
           report.html   # WAF概要报告模板文件

安装使用

1. 安装 openresty/nginx

安装好 openrestynginx + luajit + lua-nginx-module + lua-resty-core (安装教程请自行度娘 或 参考 lua-nginx-module 安装说明)

当前文档假设已安装好 openresty

  • 安装目录为 /usr/local/openresty
  • 配置文件目录为 /usr/local/openresty/nginx/conf/
  • nginx 主配置文件为 /usr/local/openresty/nginx/conf/nginx.conf

2. 安装 libmaxminddb

本库使用 libmaxminddb (https://github.com/maxmind/libmaxminddb) 作为IP地区查询工具

请下载最新 libmaxminddb 库并安装 (写此文档时版本为 1.7.1)

  • linux安装

    # linux 安装--------
    $ wget https://github.com/maxmind/libmaxminddb/releases/download/1.7.1/libmaxminddb-1.7.1.tar.gz
    $ tar -zxvf libmaxminddb-1.7.1
    $ cd libmaxminddb-1.7.1
    $ ./configure
    $ make
    $ make check
    $ sudo make install
    $ sudo ldconfig
    # 默认安装路径 /usr/local/lib/libmaxminddb.so
    # 此路径需要在 ./easy_ngx_waf/config.lua 文件中使用
    
    
  • windows安装

    # windows 下可自行编译动态库;
    # 当前 easy_ngx_waf 提供有编译好的 dll 方便童鞋们在开发阶段使用,路径为:
    # ./easy_ngx_waf/lib/packages/libmaxminddb_win/libmaxminddb.dll
    

补充: 定期更新 IP地址库

IP地址库保存路径 ./easy_ngx_waf/data/Country.mmdb

IP地址库项目地址 https://github.com/Loyalsoldier/geoip

IP地址库下载地址 https://raw.githubusercontent.com/Loyalsoldier/geoip/release/Country.mmdb

IP地址库备用下载地址 https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/Country.mmdb

下载 Country.mmdb 即可

# 可自定义定时任务自动下载
# 每周六00:00下载文件保存到 /usr/local/openresty/nginx/conf/easy_ngx_waf/data/Country.mmdb
0 0 * * 6 wget -O /usr/local/openresty/nginx/conf/easy_ngx_waf/data/Country.mmdb https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/Country.mmdb

3. 安装lfs

本库使用了 luafilesystem (https://github.com/lunarmodules/luafilesystem)

用以操作文件系统 (如扫描目录下的文件等,本库在加载 .rule 文件时用到)

lfs 使用API请自行查找

请下载安装最新版本 (实际该库应该较稳定了,很久没更了)

  • linux下安装使用

    # linux 安装--------
    # 下载源码包并命名为 luafilesystem.zip
    $ wget -O luafilesystem.zip https://github.com/lunarmodules/luafilesystem/archive/refs/heads/master.zip
    # 解压 (没有unzip命令的请先安装)
    $ unzip luafilesystem.zip
    # luafilesystem.zip包中实际是一个目录,解压后会在当前目录下多出 luafilesystem-master 目录
    $ cd luafilesystem-master
    # 编辑 config 文件中的几个配置 
    $ vim config
    # ---------- config 文件内容 S ----------
    # 原来这两行注释掉(或者直接改一个,另一行注释)
    # LUA_INC += -I$(PREFIX)/include
    # LUA_INC += -I/usr/include/lua$(LUA_VERSION) -I/usr/include/lua/$(LUA_VERSION)
    
    # 设置为实际已经安装的 openresty 下 luajit/include/luajit-2.1 (包含 lua.h 的目录)
    LUA_INC += -I/usr/local/openresty/luajit/include/luajit-2.1
    # 保存退出
    # ---------- config 文件内容 E ----------
    
    # 编译
    $ make
    # 等待编译完成(不报错即可),此时已经在 ./src/ 目录下生成 lfs.so 文件
    # 笔者编译结束,最后一行提示如下:
    # gcc -O2 -Wall -fPIC -W -Waggregate-return -Wcast-align -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings -pedantic -I/usr/local/openresty/luajit/include/luajit-2.1   -c -o src/lfs.o src/lfs.c MACOSX_DEPLOYMENT_TARGET=10.5; export MACOSX_DEPLOYMENT_TARGET; gcc -shared  -o src/lfs.so src/lfs.o
    
    # 将编译好的 .so 文件复制到相关目录中
    # 方法1: 复制 ./src/lfs.so 到 openresty安装路径下的 lualib/ 目录中
    #      (此路径已经包含在lua_package_cpath中,不用做其他设置)
    $ cp ./src/lfs.so /usr/local/openresty/lualib/
    
    # 方法2 (推荐): 复制 ./src/lfs.so 到 其他目录(假设 /web_server/tools/libs/)
    $ cp ./src/lfs.so /web_server/tools/libs/
    # nginx.conf 文件添加:
    #   lua_package_cpath "/web_server/tools/libs/?.so;;";
    
    # 测试-----
    # 	任意 lua 代码块中 require('lfs')
    # 	重启 nginx 运行不报错即可
    
  • windows下安装使用

    # windows 下可自行编译动态库;
    # 当前 easy_ngx_waf 提供有编译好的 dll 方便童鞋们在开发阶段使用,路径为:
    # 	./easy_ngx_waf/lib/packages/clib_win/lfs.dll
    # 使用方法1: 使用时可在lua代码中添加 
    #   package.cpath = package.cpath .. ';{easy_ngx_waf目录绝对路径}/lib/packages/clib_win/?.dll;'
    # 使用方法2 (推荐): 在 nginx.conf 中添加 lua_package_cpath 配置
    #   lua_package_cpath "{easy_ngx_waf目录绝对路径}/lib/packages/clib_win/?.dll;;";
    
    # 测试-----
    # 	任意 lua 代码块中 require('lfs')
    # 	重启 nginx 运行不报错即可
    

4. 配置

  1. 上传 easy_ngx_waf 项目到服务器

    本文档假设 easy_ngx_waf 根目录为 /web_server/tools/easy_ngx_waf/

  2. 设置 ./easy_ngx_waf/config.lua 相关配置(具体配置参考 完整配置文件 )

  3. nginx 主配置文件的 http 段 添加如下几行

# nginx.conf 文件 http 段

# ============= easy_ngx_waf配置 START =============

# easy_waf_cc_dict 此共享内存主要保存cc相关特征变量,内存大小根据访问量调整设置(此处为20MB大小)
# 如果 ./easy_ngx_waf/config.lua 配置文件中使用redis作为cc_dict_type(配置为 config.cc_dict_type = 'redis' ),则 easy_waf_cc_dict 这一行可注释
lua_shared_dict easy_waf_cc_dict 20m;

# 用于通用缓存,内存大小根据实际情况调整
lua_shared_dict easy_waf_cache 10m;

# 设置lua库加载路径(注意最后的 ;; 不可写错了)
lua_package_path "{easy_ngx_waf目录绝对路径}/?.lua;;";

# 如果是windows环境,请加下一行配置
# lua_package_cpath "{easy_ngx_waf目录绝对路径}\\lib\\packages\\clib_win\\?.dll;;";

# 如果是linux环境, lfs.so 保存在了非 openresty/lualib/ 目录,设置一下 cpath
# lua_package_cpath "{动态库文件目录绝对路径}/?.so;;";

init_by_lua_file {easy_ngx_waf目录绝对路径}/init.lua;

# 推荐写在 http 段作为全局使用, 写在 server 段就只针对当前 server 生效
access_by_lua_file {easy_ngx_waf目录绝对路径}/access.lua;

log_by_lua_file {easy_ngx_waf目录绝对路径}/log.lua;
# ============= easy_ngx_waf配置 END =============
  1. (此步骤非必须) 在 {easy_ngx_waf目录绝对路径}/rules/custom/ 自定义规则目录下可添加自定义规则

    • 不建议对 {easy_ngx_waf目录绝对路径}/rules/ 规则主目录下添加/修改规则,原因请见规则主目录下 README
    • 规则文件中,以 ## 开头的行是注释行(不支持行内注释),不作为规则
  2. 重载/重启 nginx

    ** 任何 lua 文件的修改,都需要重载/重启 nginx

    # 如果使用 systemd 
    $ systemctl reload nginx   # 重载 nginx (生产环境下建议重载)
    $ systemctl restart nginx  # 重启 nginx
    
    # 如果其他linux
    # 检测配置文件正确性
    $ /usr/local/openresty/nginx/sbin/nginx -t -c /usr/local/openresty/nginx/conf/nginx.conf
    # 重载 nginx
    $ /usr/local/openresty/nginx/sbin/nginx -s reload -c /usr/local/openresty/nginx/conf/nginx.conf
    # 停止 nginx
    $ /usr/local/openresty/nginx/sbin/nginx -s stop
    # 启动 nginx
    $ /usr/local/openresty/nginx/sbin/nginx -s start
    

完整配置文件

配置文件中的开关项

  • 打开状态可用值有: "on" / "yes" / "y" / "true" / "1" / true / 1 (字符串不区分大小写)

  • 关闭状态可用值有: "off" / "no" / "n" / "false" / "0" / false / 0 (字符串不区分大小写)

  • 通过 lib/util.check_switch_is_on(value) 检测开关状态

    打开状态返回 true

    关闭状态返回 false

    非以上值返回 nil

-- ./easy_ngx_waf/config.lua 文件

local config = {}

-- 总开关
config.waf_enable = "on"

-- 是否记录waf拦截日志(拦截日志总开关)
config.waf_log = "on"
-- waf拦截日志路径(绝对路径,确保nginx用户有写权限;文件未生成前,所属目录需要有写权限)
--     文件名可自定义,只要nginx用户有写权限即可。
--     配置示例: "{nginx_log目录}/easy_ngx_waf.log"
--     如果使用日志处理服务,一定要注意生成日志文件时的权限,所有者一定要是nginx用户,否则新日志无法写入。
--        笔者在日志这块踩的坑请参见  注意事项 -- WAF日志不记录章节
config.waf_log_file = "/web_server/web/logs/easy_ngx_waf.log"

-- waf基础目录(绝对路径,库中规则目录及某些文件路径依赖此路径)
--     示例: "/web_server/tools/easy_ngx_waf"
--          "D:\\server\\easy_ngx_waf"
config.waf_base_path = "/web_server/tools/easy_ngx_waf"

-- WAF排除域名列表(host_exclude)
-- 可在此设置不参与WAF检测的域名(可设置全局排除,也可针对各检测阶段排除)
--      排除域名设置注意事项
--          "abc.com" => 具体域名,只针对 "abc.com" 域名排除,"www.abc.com" 还是参与waf检测的
--          "*.abc.com" => 通配符域名,针对所有 "abc.com" 域名("abc.com"  "www.abc.com"  "x.y.abc.com")都排除
config.host_x = {

    -- "all" 全局排除域名列表
    --      包含在此列表的域名直接跳过所有WAF检测
    all = {
        "*.easy_ngx_waf.xxx",
        "localhost",
    },

    -- "ip_white" IP白名单检测阶段排除域名列表
    ip_white = {
        "www.example.xxx",
        "*.example2.xxx",
    },

    -- "ip_black" IP黑名单检测阶段排除域名列表
    ip_black = {
    },

    -- "ip_foreign" 境外IP检测阶段排除域名列表
    ip_foreign = {
    },

    -- "ua" user-agent检测阶段排除域名列表(同时也不参与ua白名单检测)
    ua = {
    },

    -- "cookie" cookie检测阶段排除域名列表
    cookie = {
    },

    -- "cc" cc检测阶段排除域名列表
    cc = {
    },

    -- "args" args检测阶段(也就是get参数检测)排除域名列表
    args = {
    },

    -- "post" post检测阶段排除域名列表
    post = {
    },

    -- "header" header检测阶段排除域名列表
    header = {
    },

} -- END config.host_x


-- libmaxminddb编译安装后的库文件路径(绝对路径)
-- IP归属地区检测
--   linux下需要先安装libmaxminddb(项目地址 https://github.com/maxmind/libmaxminddb)
--       默认安装路径 "/usr/local/lib/libmaxminddb.so"
--   windows下已预置了动态库 config.waf_base_path.."\\lib\\packages\\libmaxminddb_win\\libmaxminddb.dll"
config.libmaxminddb_path = "/usr/local/lib/libmaxminddb.so"


-- IP白名单: 所有规则中, "var":"ip"  "act":"allow" 的都算作IP白名单(不管是 ip_match, ip_region 运算)
--      "op":"ip_match"  时, 规则 value 可以是符合CIDR规则的IP
--      "op":"ip_region" 时, 规则 value 可以是所在地区的代码(如: "CN","MO"...)
-- 是否开启IP白名单校验(白名单命中,后续校验都不做)
config.ip_white_check = "on"
-- IP白名单命中时是否记录日志(推荐关闭,可减少日志);此设置只针对简单规则有效,常规规则中有单独的日志开关;
config.ip_white_log = "off"


-- IP黑名单: 所有规则中, "var":"ip"  "act":"deny" 的都算作IP黑名单(不管是 ip_match, ip_region 运算)
--      "op":"ip_match"  时, 规则 value 可以是符合CIDR规则的IP
--      "op":"ip_region" 时, 规则 value 可以是所在地区的代码(如: "US","TW"...)
-- 是否开启IP黑名单校验
config.ip_black_check = "on"
-- IP黑名单命中时是否记录日志(推荐关闭,可减少日志);此设置只针对简单规则有效,常规规则中有单独的日志开关;
config.ip_black_log = "on"
-- IP黑名单校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容)
config.ip_black_deny_return = ngx.HTTP_NOT_FOUND


-- 是否开启user-agent白名单校验(开启可放行UA白名单)
config.user_agent_white_check = "off"
-- user-agent白名单命中时是否记录日志(关闭可减少日志);此设置只针对简单规则有效,常规规则中有单独的日志开关;
config.user_agent_white_log = "off"


-- 是否开启user-agent校验
config.user_agent_check = "on"
-- user-agent校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容)
config.user_agent_deny_return = "user_agent_deny"


-- 是否开启url白名单校验
config.url_white_check = "on"
-- url白名单命中时是否记录日志(关闭可减少日志);此设置只针对简单规则有效,常规规则中有单独的日志开关;
config.url_white_log = "off"


-- 是否开启url校验
config.url_check = "on"
-- url校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容)
config.url_deny_return = "url_deny"


-- 是否开启SEO蜘蛛校验
config.seo_spider_check = "on"
-- SEO蜘蛛校验命中时是否记录日志(关闭可减少日志)
config.seo_spider_log = "off"


-- 是否开启 禁止境外IP访问
config.ip_foreign_check = "on"
-- 禁止境外IP命中时是否记录日志(推荐关闭,可减少日志)
config.ip_foreign_log = "on"
-- 非境外IP地区列表(在这个列表中的地区为非境外IP),注意大小写
config.domestic_iso_code = {
    "CN",      -- 中国CODE
    "HK",      -- 香港CODE
    "MO",      -- 澳门CODE
    "TW",      -- 台湾省CODE
    "PRIVATE", -- 内网CODE
    -- 内网IP段
    --      10.0.0.0 - 10.255.255.255
    --      172.16.0.0 - 172.31.255.255
    --      192.168.0.0 - 192.168.255.255
}
-- 禁止境外IP访问时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容)
config.ip_foreign_deny_return = "ip_foreign_deny"


-- 是否开启cookie校验
config.cookie_check = "on"
-- cookie校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容)
config.cookie_deny_return = "cookie_deny"


-- 是否开启args参数校验
config.args_check = "on"
-- args参数校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容)
config.args_deny_return = "args_deny"


-- 是否开启post参数校验
config.post_check = "on"
-- post参数校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容)
config.post_deny_return = "post_deny"


-- 是否开启header校验(此检测阶段已将user-agent cookie剥离)
config.header_check = "on"
-- header校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容)
config.header_deny_return = "header_deny"


-- 是否开启CC校验
config.cc_check = "on"
-- CC频率 单位:请求次数N/M秒 默认100/60:60秒请求100次即触发CC攻击
config.cc_rate = "100/60"
-- CC校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容)
config.cc_deny_return = ngx.HTTP_NOT_FOUND
-- CC检测命中,封锁IP时长(单位:秒,如果为0则永久封锁)
config.cc_ip_lock_time = 300
-- CC防护使用的数据存储类型( "redis" / "shared_dict" )
--   如果使用redis,需要正确配置下方redis相关配置项
--   如果使用shared_dict,需要在 nginx.conf 的 http 段配置 lua_shared_dict easy_waf_cc_dict ?m;
config.cc_dict_type = "shared_dict"

-- redis主机
config.redis_host = "127.0.0.1"
-- redis端口
config.redis_port = 6379
-- redis数据库编号(默认0号库,通常可选0-15)
config.redis_db_index = 0
-- redis密码(没有留空字符串)
config.redis_password = ""

-- 防火墙拦截后,默认返回响应状态码 及 html内容(如果各个拦截响应配置项设置为"default"时)
config.default_return_code = ngx.HTTP_NOT_FOUND
config.default_return_html = [[MMP...]]

return config

注意事项

SSL自动续签失败

如果服务器使用了 文件验证 的方式自动续签 SSL 证书,且 WAF 开启了 禁止境外IP 功能,一些CA机构执行验证的IP会被视为 境外IP 被拦截,导致续签失败 (在 error.log 中会看到 GET /.well-known/acme-challenge/<TOKEN> 此类的信息)。

  • 解决方法1(推荐):添加 URL白名单

    ## 在 rules/custom/ 目录下某个 .rule 文件中添加一条常规规则
    {
      "name": "ACME-validate-url",
      "var": "request_uri",
      "op": "re",
      "value": "^/\.well-known/\.*",
      "act": "allow",
      "log": "on",
      "msg": "ACME续签文件验证"
    }
    
    ## 或者在 rules/custom/simple/url_white 文件中添加一行:
    ^/\.well-known/\.*
    
  • 解决方法2: 添加 IP白名单

    # 比如常见的有
    91.199.212.132
    91.199.212.133
    

    执行验证的IP也不是不变的,比如 Let's Encrypt 文档中就有说明 =点击查看文档=

    引用一段原文如下:

    ​ 如果您 “http-01” ACME 验证方法,您需要允许 80 端口上的入站通信。 我们不会公布执行验证的 IP 范围,它们可能在不另行通知的情况下改变。

规则误报

目前项目中添加了一些 CRS 规则,其中一些 CRS 规则比较严格,每个项目的请求数据各式各样,难免出现误报。

  • 简单粗暴的方法:删除 /rules/ 目录下所有 CRS-xxxx.rule 的规则文件即可 (简单规则中也包含了常用拦截规则,也能防范一些常见攻击)

  • 慢慢排查法:每个 CRS 规则都编号,注意查看 easy_ngx_waf.log 防火墙日志,根据日志中编号找到对应规则,将其设置成如下所示即可。

{
    ## 某规则内容
    ......
    ## act 由 "deny" 改为 "next"
    "act": "next",
    ## log  "on" 表示记录日志   "off" 表示不记录日志,结合 "act":"next" 完成忽略此规则
    "log": "off",
    ......
}

WAF日志不记录

笔者的 WAF 日志文件使用了 logrotate 做处理,在最初时为图方便直接使用了原有的 *nginx.log 的规则,但后来发现这个默认的规则在创建新日志文件时给的 权限不对 ,导致后来都没有 WAF日志 了(但 WAF 功能还是在运行的)

# 查看 waf 日志目录会发现权限为  root root
# 而正常情况下,所有者应为 nginx 用户(我目前nginx用户是 www ,参见下方解决办法中处理)
$ ll easy*
-rw-r--r-- 1 root root  489054 Jul 17 16:44 easy_ngx_waf.log
-rw-r--r-- 1 root root   36478 Jun 29 23:51 easy_ngx_waf.log-20230630.gz
-rw-r--r-- 1 root root   40912 Jun 30 23:57 easy_ngx_waf.log-20230701.gz
...

解决办法(只针对 logrotate ,其他情形思路都是一样的)

# 此处只针对 logrotate
# 其他情形思路都是一样的,waf 日志文件所有者应为 nginx 用户(我目前nginx用户是 www )

# 1. 进入 logrotate 规则目录,新建 waf 规则 (文件名自定义,此处文件为 easy_ngx_waf )
$ cd /etc/logrotate.d/
$ vim easy_ngx_waf
# 进入 vim 后加入以下内容(关于logrotate规则请自行搜索)

# /web_server/web/logs/   为WAF日志所在目录绝对路径
#     easy_ngx_waf*.log   为WAF日志文件前缀,跟WAF配置文件中的一致
/web_server/web/logs/easy_ngx_waf*.log {
  # 每日执行
  daily
  # 保留25份备份
  rotate 25
  missingok
  dateext
  compress
  notifempty
  sharedscripts
  copytruncate
  # 重点是这一行,创建新文件时指定权限: 权限0664 所有者www 所属组root
  create 0644 www root
  postrotate
    [ -e /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
  endscript
}
# 完成 vim 编辑后保存退出

# 重启logrotate服务
# 我的系统是systemd管理服务,命令如下
$ systemctl restart rsyslog 

后续功能

  • 目前针对WAF的设置都是基于 config 文件及各个规则文件的,暂时还没有前端管理,后期时间允许或许会出;

    (目前 config 文件中配置说明及各个 README 中的说明其实也相当清楚了)

  • 目前所有配置修改、规则添加 / 修改等操作都需要重载 / 重启 nginx ,后期增加动态刷新功能;

License

MulanPSL-2.0

Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Lua
1
https://gitee.com/chleniang/easy_ngx_waf.git
git@gitee.com:chleniang/easy_ngx_waf.git
chleniang
easy_ngx_waf
easy_ngx_waf
master

搜索帮助