使用Nginx与ModSecurity搭建WAF测试环境

Page content

本文介绍使用nginx作为服务器,ModSecurity作为WAF搭建攻击测试环境的过程。总的来说分为以下几个过程:编译安装ModSecurity,编译安装nginx,在nginx中开启ModSecurity并导入owasp-modsecurity-crs,测试四个过程。由于本文的目的是搭建测试环境,因此在docker中进行。

创建容器

首先,创建一个ubuntu 20.04的容器进行下一步环境的搭建。

# 拉取ubuntu 20.04的镜像
docker pull ubuntu:20.04
# 创建容器,命名为modsecurity_test
docker run -itd --name modsecutiry_test ubuntu:20.04 /bin/bash
# 连接到容器
sudo docker exec -it mod_security /bin/bash

接下来的命令都在该容器中执行。

编译安装ModSecurity

首先,安装必要的依赖程序。

sudo apt-get install -y git build-essential libpcre3 libpcre3-dev libssl-dev libtool autoconf apache2-dev libxml2-dev libcurl4-openssl-dev automake pkgconf zlib1g-dev -y

然后,切换至某目录进行下载、编译、安装,此处目录为/usr/src。

# 切换到存放目录
cd /usr/src
# 从github下载ModSecurity
git clone -b nginx_refactoring https://github.com/SpiderLabs/ModSecurity.git
# 进入ModSecurity目录
cd ModSecurity
# 以下为ModSecurity的配置、编译、安装命令
./autogen.sh
./configure --enable-standalone-module --disable-mlogc
make
sudo make install 

编译安装nginx

首先,移除已有的nginx,重新编译安装包含ModSecurity模块的nginx。如果是从干净的容器搭建测试环境,这一步应该没有什么影响。

sudo apt-get purge nginx -y
sudo apt-get autoremove -y

然后下载、编译、安装nginx。

# nginx也下载到/usr/src
cd /usr/src
wget http://nginx.org/download/nginx-1.18.0.tar.gz
# 解压文件
tar xvzf nginx-1.18.0.tar.gz
cd nginx-1.18.0
# 以下为配置、编译、安装nginx的命令,注意--add-module指明的路径,根据上一步的实际情况更换
./configure --user=www-data --group=www-data --add-module=/usr/src/ModSecurity/nginx/modsecurity --with-http_ssl_module
make
sudo make install

然后,指定一下nginx使用的用户。

# 意为将/usr/local/nginx/conf/nginx.conf文件中的#user  nobody;更改为user www-data www-data;
# 也可以不执行以下的sed命令,手动更改
sed -i "s/#user  nobody;/user www-data www-data;/" /usr/local/nginx/conf/nginx.conf

这时,输入/usr/local/nginx/sbin/nginx -v可以看到输出nginx的版本。

开启ModSecurity并导入owasp-modsecurity-crs

这一步在nginx中开启ModSecurity配置,并导入owasp-modsecurity-crs(一个OWASP组织提供的规则集合)。首先,打开/usr/local/nginx/conf/nginx.conf文件,找到如下的内容:

location / {

    root   html;

    index  index.html index.htm;

}

将其更改为:

location / {

    ModSecurityEnabled on;

    ModSecurityConfig modsec_includes.conf;

    root   html;

    index  index.html index.htm;

}

意为打开ModSecurity,并且modsec_includes.conf为其配置文件。接下来,在/usr/local/nginx/conf/nginx.conf的同目录下,即/usr/local/nginx/conf/下编写配置文件。编写配置文件有些复杂,幸运的是,已经有一些样例存在,我们只需要进行些许修改。

# 将ModSecurity自带的配置样例复制到nginx配置文件的目录
sudo cp /usr/src/ModSecurity/modsecurity.conf-recommended /usr/local/nginx/conf/modsecurity.conf
sudo cp /usr/src/ModSecurity/unicode.mapping /usr/local/nginx/conf/
# 在复制后的modsecurity.conf文件中将SecRuleEngine DetectionOnly改为SecRuleEngine On
sudo sed -i "s/SecRuleEngine DetectionOnly/SecRuleEngine On/" /usr/local/nginx/conf/modsecurity.conf
# 接下来我们将该文件添加到modsec_includes.conf中
vim /usr/local/nginx/conf/modsec_includes.conf
# 写入 include modsecurity.conf 并保存退出

我们以上进行了两处更改,一是更改nginx的配置文件/usr/local/nginx/conf/nginx.conf来开启ModSecurity,并指明了它所需的配置文件modsec_includes.conf。接下来我们将ModSecurity自带的配置文件复制到nginx的配置目录,并在modsec_includes.conf中包含了它。

cat /usr/local/nginx/conf/modsec_includes.conf
#执行以上命令有以下输出
include modsecurity.conf

其实modsec_includes.conf中包含的modsecurity.conf文件主要是开启ModSecurity的基本配置,我们想引入更多安全规则,可以借助owasp-modsecurity-crs。

# 进入到nginx的配置文件夹
cd /usr/local/nginx/conf
# 下载owasp-modsecurity-crs
sudo git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git
# 进入项目文件夹
sudo cd owasp-modsecurity-crs
# 文件更名
sudo mv crs-setup.conf.example crs-setup.conf

其中,crs-setup.conf是owasp-modsecurity-crs的基本配置文件(如定义对一个可能的入侵作何响应),项目目录下的rules文件夹包含了ModSecurity的安全规则。假设我们测试SQL注入相关的攻击,将需要rules文件夹下的REQUEST-942-APPLICATION-ATTACK-SQLI.conf和RESPONSE-951-DATA-LEAKAGES-SQL.conf,因此modsec_includes.conf被改为如下:

cat modsec_includes.conf
# 执行以上命令,输出如下
include modsecurity.conf # ModSecurity的基本配置
include owasp-modsecurity-crs/crs-setup.conf # owasp-modsecurity-crs基本配置
include owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf # 安全规则
include owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf # 安全规则

测试

我们已经配置好了nginx和ModSecurity,下面进行测试。

# 开启nginx
/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
# 一次正常的访问
curl 'http://localhost/' -I
# 一次危险的访问,可以在/usr/local/nginx/logs/error.log中看到拦截信息
curl 'http://localhost/?id=1 AND 1=1' -I

owasp-modsecurity-crs默认情况下对危险的请求仅进行记录,可以通过修改crs-setup.conf进行配置。例如,将原来的SecDefaulAction注释掉,开启:

SecDefaultAction "phase:1,log,auditlog,deny,status:403"
SecDefaultAction "phase:2,log,auditlog,deny,status:403"

然后重新启动nginx:

/usr/local/nginx/sbin/nginx -s reload
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

那么将对危险的访问请求返回403。