timochan

timochan

让我们部署自己的 WAF - ModSecurity

Preface#

一些宝塔一键 LNMP 的站长,多半用的第三方的 Nginx 防火墙,虽好,但是规则更新不及时,而且主要针对 PHP 站;如果是其他的站,例如你的站是使用 Halo 搭建的,使用这些规则就不太合适了。让我们使用 ModSecurity(V3)来架设 WAF,并借助 OWASP ModSecurity Core Rule Set (CRS) 来更新我们 WAF 的防护规则。当然 Apache 也可以,但是我很讨厌它

1

Start#

First#

本次环境基于 Debian 11

我们应该准备一下环境,如果你是编译安装的 Nginx,那工作量就减少了很多,当然我们也可以直接拉取源码开始编译。

wget https://nginx.org/download/nginx-1.18.0.tar.gz
tar zxvf nginx-1.18.0.tar.gz

安装编译依赖

sudo apt install g++ flex bison curl apache2-dev doxygen libyajl-dev ssdeep liblua5.2-dev libgeoip-dev libtool dh-autoreconf libcurl4-gnutls-dev libxml2 libpcre++-dev libxml2-dev git

如此,我们准备好了编译所需要的依赖包

Second#

安装 ModSecurity

克隆仓库 ModSecurity 仓库

git clone https://github.com/SpiderLabs/ModSecurity.git --depth=1

注:本文提到的 GitHub 地址,如果你的网络条件不好,可以使用以下镜像地址替代

https://github.hscsec.cn/

例如

git clone https://github.hscsec.cn/SpiderLabs/ModSecurity.git

编译安装

./build.sh
git submodule init
git submodule update
./configure --prefix=/usr/local/modsecurity
make
sudo make install

如此,我们便安装好了 ModSecurity;别急,我们还需要把连接器以模块的形式编译到 Nginx 上

Third#

如果你是宝塔编译安装,那么 /www/server/nginx/src 即你当前使用的 Nginx 编译安装源码

本文以宝塔编译安装的 Nginx 为例

如果你是其他安装,请准备好 Nginx 源码,本文不再赘述

首先查看当前 Nginx 使用的编译参数

nginx -V

例如,返回如下信息

configure arguments: --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --with-threads --with-file-aio --with-compat --add-module=/www/server/nginx/src/nginx-dav-ext-module

那么这串内容则是我们需要记录的内容

--user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --with-threads --with-file-aio --with-compat --add-module=/www/server/nginx/src/nginx-dav-ext-module

进入 Nginx 源码

cd /www/server/nginx/src

克隆连接器仓库

git clone https://github.com/SpiderLabs/ModSecurity-nginx.git --depth=1

生成 Makefile

./configure --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --with-threads --with-file-aio --with-compat --add-module=/www/server/nginx/src/nginx-dav-ext-module --add-dynamic-module=/www/server/nginx/src/ModSecurity-nginx --with-compat

编译

make

#如果你的 CPU 核心数多于 2 个,建议多线程编译,示例如下

make -j 4

我们无需使用 make install ,将 objs 目录下的 Nginx 拷贝到 /www/server/nginx/sbin/ 即可,然后 objs 目录下的 ngx_http_modsecurity_module.so 我们拷贝到 /www/server/nginx/modules/ 如果没有就新建文件夹。部分情况下,该模块直接链接进了 nginx 的二进制文件,所以没有单独的 so 文件,此时默认 nginx 运行默认装载该模块,所以仅需 copy nginx 二进制文件即可。


# 复制 Nginx
cp -rf objs/nginx ../sbin/nginx
# 复制编译出的 So 模块
mkdir ../modules
cp objs/ngx_http_modsecurity_module.so ../modules/ngx_http_modsecurity_module.so

如此,我们完成了 ModSecurity 以及 Nginx 连接器的安装

Configure#

在 ModSecurity 源码目录下,有两个配置文件,我们可以复制过去,例如

cp modsecurity.conf-recommended /www/server/nginx/conf/modsecurity.conf

cp unicode.mapping /www/server/nginx/conf/unicode.mapping

克隆 OWASP ModSecurity Core Rule Set 仓库

cd /www/server/nginx/conf

git clone https://github.com/coreruleset/coreruleset.git --depth=1 wafconf

进入规则目录,编辑配置文件

cd wafconf

cp crs-setup.conf.example crs-setup.conf

编辑 crs-setup.conf,里面有如下内容

  # 该区块内容表示,根据规则进行威胁评分,超过评分阈值才会采取行动,资源开销较大
97 SecDefaultAction "phase:1,log,auditlog,pass"
98 SecDefaultAction "phase:2,log,auditlog,pass"
  # 该区块内容表示,根据规则进行直接拦截,并返回 403
117 SecDefaultAction "phase:1,log,auditlog,deny,status:403"
118 SecDefaultAction "phase:2,log,auditlog,deny,status:403"
  # 该区块内容表示,根据规则进行拦截,并重定向到首页
127 SecDefaultAction "phase:1,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"
128 SecDefaultAction "phase:2,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"

这三种措施,使用其中一种就行,然后注释掉其他两种

我们编辑 modsecurity.conf 文件

里面有如下内容

SecRuleEngine DetectionOnly

我们需要修改为

SecRuleEngine On

在文件末尾添加如下内容

Include /www/server/nginx/conf/wafconf/crs-setup.conf
Include /www/server/nginx/conf/wafconf/rules/*.conf

如此,我们算是配置妥当了,接下来将启动 WAF

Use#

编辑 nginx.conf,位于 /www/server/nginx/conf

引入模块

load_module /www/server/nginx/modules/ngx_http_modsecurity_module.so;

例如

user  www-data www-data;
worker_processes auto;
error_log  /www/wwwlogs/nginx_error.log  crit;
pid        /www/server/nginx/logs/nginx.pid;
load_module /www/server/nginx/modules/ngx_http_modsecurity_module.so;

开启 ModSecurity

我们可以选择全局开启,例如,在 nginx.conf 的 http 区域块添加如下内容

modsecurity on;
modsecurity_rules_file /www/server/nginx/conf/modsecurity.conf;

当然,我们可以分别在部分网站开启

在宝塔设定的网站配置文件下进行添加

cd /www/server/panel/vhost/nginx

例如 test.cn.conf

我们在其 server 区块内添加即可

示例如下

modsecurity on;
modsecurity_rules_file /www/server/nginx/conf/modsecurity.conf;
access_log  /www/wwwlogs/test.cn.log;
error_log  /www/wwwlogs/test.cn.error.log;

重载 nginx

sudo nginx -t
sudo nginx -s reload

或者宝塔 Nginx 重载配置文件

Adjustment#

这样,我们就开启了 WAF;我们都知道最好的规则,未必适合自己,所以我们需要适当开启 / 关闭一些规则

进行网站的日常访问,如果发现异常的情况,请查看 log

WAF 的 log 在 /var/log/modsec_audit.log

这里面详细的记录了网站的请求参数,响应参数,拦截依据的规则,根据规则 id 或者文件名进行适当的关闭即可,例如 xxx.conf 修改为 xxx.conf.bak 直接关闭这一条规则,或者把对应的动作 id 的行动部分给注释掉,然后重载 Nginx

Upgrade#

module upgrade#

因为我们是克隆的仓库,所以我们仅需拉取最新的提交,然后重新编译即可

rules upgrade#

因为我们是克隆的仓库,所以我们仅需拉取最新的提交,然后重载 Nginx 即可

End#

愉快的使用 ModSecurity 来保护你的网站吧!

此文由 Mix Space 同步更新至 xLog
原始链接为 https://www.timochan.cn/posts/jc/waf_modsecurity_for_nginx


Footnotes#

  1. https://www.timochan.cn/posts/study/upload-labs_Pass_10_for_Linux

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.