Skip to content

Latest commit

 

History

History
298 lines (212 loc) · 11.4 KB

README-ZH-CN.md

File metadata and controls

298 lines (212 loc) · 11.4 KB

ngx_waf

ngx_waf

test GitHub release (latest by date including pre-releases) GitHub 讨论 语义化版本 2.0.0

English | 简体中文

一个用于 nginx 的没有复杂配置的 Web 应用防火墙模块。

开发进度 & 更新日志

快捷跳转

功能

  • 支持 IPV4 和 IPV6。
  • CC 防御,超出限制后自动拉黑对应 IP 一段时间。
  • IP 黑白名单,同时支持类似 192.168.0.0/16fe80::/10,即支持点分十进制和冒号十六进制表示法和网段划分。
  • POST 黑名单。
  • URL 黑白名单
  • GET 参数黑名单
  • UserAgent 黑名单。
  • Cookie 黑名单。
  • Referer 黑白名单。

安装

On Unix Like

下载 nginx 源码

nginx 添加新的模块必须要重新编译,所以先下载 nginx 源码

cd /usr/local/src
wget http://nginx.org/download/nginx-version.tar.gz
tar -zxf nginx-version.tar.gz

推荐使用 nginx-1.18.0 的源码,若使用低版本的 nginx 源码则不保证本模块可以正常使用。本模块对 Mainline 版本的 nginx 做了兼容性处理,但考虑到 Mainline 版本仍在开发中,所以不保证一直可以兼容。如果遇到了兼容性问题请提 issue。

下载 ngx-waf 源码

cd /usr/local/src
git clone https://github.com/ADD-SP/ngx_waf.git
cd ngx_waf

编译和安装模块

从 nginx-1.9.11 开始,nginx 开始支持动态模块。

静态模块将所有模块编译进一个二进制文件中,所以增删改模块都需要重新编译 nginx 并替换。

动态模块则动态加载 .so 文件,无需重新编译整个 nginx。只需要将模块编译成 .so 文件然后修改nginx.conf即可加载对应的模块。


使用静态模块

cd /usr/local/src/nginx-version
./configure xxxxxx --add-module=/usr/local/src/ngx_waf
make

xxxxxx 为其它的编译参数,一般来说是将 xxxxxx 替换为nginx -V显示的编译参数。

如果您已经安装了 nginx 则可以直接替换二进制文件(假设原有的二进制文件的全路径为/usr/local/nginx/sbin/nginx

nginx -s stop
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
cp objs/nginx /usr/local/nginx/sbin/nginx
nginx

如果不想中断 nginx 服务则可以通过热部署的方式来实现升级,热部署方法见官方文档

如果您之前没有安装则直接执行下列命令

make install

使用动态模块

cd /usr/local/src/nginx-version
./configure xxxxxx --add-dynamic-module=/usr/local/src/ngx_waf
make modules

xxxxxx 为其它的编译参数,一般来说是将 xxxxxx 替换为nginx -V显示的编译参数。

此时你需要找到一个目录用来存放模块的 .so 文件,本文假设存储在/usr/local/nginx/modules

cp objs/ngx_http_waf_module.so /usr/local/nginx/modules/ngx_http_waf_module.so

然后修改nginx.conf,在最顶部添加一行。

load_module "/usr/local/nginx/modules/ngx_http_waf_module.so";

使用

在需要启用模块的 server 块添加下列配置,例如

http {
    ...
    server {
        ...
        waf on;
        waf_rule_path /usr/local/src/ngx_waf/rules/;
        waf_mode STD;
        waf_cc_deny_limit 1000 60;
        ...
    }
    ...
}

waf

  • 配置语法: waf [ on | off ];
  • 默认值:off
  • 配置段: server

是否启用本模块。

waf_rule_path

  • 配置语法: waf_rule_path dir;
  • 默认值:无
  • 配置段: server

规则文件所在目录,且必须以/结尾。

waf_mult_mount

  • 配置语法: waf_mult_mount [ on | off ];
  • 默认值:off
  • 配置段: server

进行多阶段检查,当nginx.conf存在地址重写的情况下(如rewrite配置)建议启用,反之建议关闭。

waf_mode

  • 配置语法: waf_mode mode_type ...;
  • 默认值: 无
  • 配置段: server

指定防火墙的工作模式,至少指定一个模式,最多指定八个模式。

mode_type具有下列取值(不区分大小写):

  • GET: 当Http.Method=GET时启动检查。
  • HEAD: 当Http.Method=HEAD时启动检查。
  • POST: 当Http.Method=POST时启动检查。
  • PUT: 当Http.Method=PUT时启动检查。
  • DELETE: 当Http.Method=DELETE时启动检查。
  • MKCOL: 当Http.Method=MKCOL时启动检查。
  • COPY: 当Http.Method=COPY时启动检查。
  • MOVE: 当Http.Method=MOVE时启动检查。
  • OPTIONS: 当Http.Method=OPTIONS时启动检查。
  • PROPFIN: 当Http.Method=PROPFIN时启动检查。
  • PROPPATCH: 当Http.Method=PROPPATCH时启动检查。
  • LOCK: 当Http.Method=LOCK时启动检查。
  • UNLOCK: 当Http.Method=UNLOCK时启动检查。
  • PATCH: 当Http.Method=PATCH时启动检查。
  • TRAC: 当Http.Method=TRAC时启动检查。
  • IP: 启用 IP 地址的检查规则。
  • URL: 启用 url 的检查规则。
  • RBODY: 启用请求体的检查规则。
  • ARGS: 启用 args 的检查规则。
  • UA: 启用 user-agent 的检查规则。
  • COOKIE: 启用 cookie 的检查规则。
  • REFERER: 启用 referer 的检查规则。
  • CC: 启用 CC 防御。
  • STD: 等价于 GET POST CC IP URL ARGS RBODY UA
  • FULL: 任何情况下都会启动检查并启用所有的检查规则。

注意: CC是独立于其它模式的模式,其生效与否不受到其它模式的影响。典型情况如URL模式会受到GET模式的影响,因为如果不使用GET模式,那么在收到GET请求时就不会启动检查,自然也就不会检查 URL,但是CC模式不会受到类似的影响。

waf_cc_deny_limit

  • 配置语法: waf_cc_deny_limit rate duration;
  • 默认值:无
  • 配置段: server

包含两个参数,第一个参数rate表示每分钟的最多请求次数(大于零的整数),第二个参数duration表示超出第一个参数rate的限制后拉黑 IP 多少分钟(大于零的整数)。

测试

https://example.com/www.bak

如果返回 403 则表示安装成功。

规则文件

规则中的正则表达式均遵循PCRE 标准

  • rules/ipv4:IPV4 黑名单,每条规则独占一行。每行只能是一个由点分十进制表示的 IPV4 地址,允许通过类似 192.168.0.0/16 的方式划分网段。拦截匹配到的 IP 并返回 403。
  • rules/ipv6:IPV6 黑名单,每条规则独占一行。每行只能是一个由冒号十六进制表示的 IPV6 地址,通过类似 fe80::/10 的方式划分网段。拦截匹配到的 IP 并返回 403。
  • rules/url:URL 黑名单,每条规则独占一行。每行一个正则表达式,当 URL 被任意一个规则匹配到就返回 403。
  • rules/args:GET 参数黑名单,每条规则独占一行。每行一个正则表达式,当 GET 参数(如test=0&test1=)被任意一个规则匹配到就返回 403。
  • rules/referer:Referer 黑名单,每条规则独占一行。每行一个正则表达式,当 referer 被任意一个规则匹配到就返回 403。
  • rules/user-agent:UserAgent 黑名单,每条规则独占一行。每行一个正则表达式,当 user-agent 被任意一个规则匹配到就返回 403。
  • rules/cookie:Cookie 黑名单,每条规则独占一行。每行一个正则表达式,当 Cookie 中的内容被任意一个规则匹配到就返回 403。
  • rules/post:POST 黑名单,每条规则独占一行。每行一个正则表达式,当请求体中的内容被任意一个规则匹配到就返回 403。
  • rules/white-ipv4:IPV4 白名单,写法同rules/ipv4
  • rules/white-ipv6:IPV6 白名单,写法同rules/ipv6
  • rules/white-url:URL 白名单。写法同rules/url
  • rules/white-referer:Referer 白名单。写法同rules/referer

变量

在书写 nginx.conf 文件的时候不可避免地需要用到一些变量,如$remote_addr可以用来获取客户端 IP 地址。

本模块增加了三个可用的变量。

  • $waf_blocked: 本次请求是否被本模块拦截,如果拦截了则其的值为'true',反之则为'false'
  • $waf_rule_type:如果本次请求被本模块拦截,则其值为触发的规则类型。下面是可能的取值。若没有生效则其值为'null'
    • 'BLACK-IPV4'
    • 'BLACK-URL'
    • 'BLACK-ARGS'
    • 'BLACK-USER-AGENT'
    • 'BLACK-REFERER'
    • 'BLACK-COOKIE'
    • 'BLACK-POST'
  • '$waf_rule_details':如果本次请求被本模块拦截,则其值为触发的具体的规则的内容。若没有生效则其值为'null'

日志

拦截日志日志存储在 error.log 中。拦截记录的日志等级为 ALERT。基本格式为xxxxx, ngx_waf: [拦截类型][对应规则], xxxxx,具体可看下面的例子。

2020/01/20 22:56:30 [alert] 24289#0: *30 ngx_waf: [BLACK-URL][(?i)(?:/\.env$)], client: 192.168.1.1, server: example.com, request: "GET /v1/.env HTTP/1.1", host: "example.com", referrer: "http:/example.com/v1/.env"

2020/01/20 22:58:40 [alert] 24678#0: *11 ngx_waf: [BLACK-POST][(?i)(?:select.+(?:from|limit))], client: 192.168.1.1, server: example.com, request: "POST /xmlrpc.php HTTP/1.1", host: "example.com", referrer: "https://example.com/"

开发文档

安装依赖

请确保已经安装 doxygengraphviz,且 doxygen 的版本至少要为 1.8.17。

生成文档

./mkdocs.sh

docs/ZH-CN/html 目录下会生成开发文档。你可以直接用浏览器打开 docs/ZH-CN/html/index.html 文件来浏览文档。

开源许可证

BSD 3-Clause License

其它

感谢