0x01 前言

前些天我写了几篇关于modsecurity的文章,但和最新的nginx(openresty)并不兼容。经过查询了解后发现在modsecurity v3中已经解决了这些BUG。

在这里我记录下编译的过程,以下是软件版本:

  • nginx:openresty-1.11.2.5
  • ModSecurity:ModSecurity v3.0.0rc1 (Linux)
  • modsecurity connector:ModSecurity-nginx v0.1.1-beta

安装测试都在centos7上进行。

0x02 准备

首先通过以下地址将软件下载到本地,先建立并进入相应的文件夹:

[root@modsecurity ~]# mkdir /root/codex/

然后下载或克隆文件到本地:

#下载openresty
[root@modsecurity ~]# wget https://openresty.org/download/openresty-1.11.2.5.tar.gz

#克隆ModSecurity
git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity

#克隆modsecurity nginx connector
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git

0x03 编译安装

0x03.1 Modsecurity Lib

先编译Modsecurity Lib,进入ModSecurity源码文件夹并运行以下命令:

#进入文件夹
[root@modsecurity codex]# cd ModSecurity

#初始化submodule
[root@modsecurity ModSecurity]# git submodule init 
Submodule 'bindings/python' (https://github.com/SpiderLabs/ModSecurity-Python-bindings.git) registered for path 'bindings/python'
Submodule 'others/libinjection' (https://github.com/client9/libinjection.git) registered for path 'others/libinjection'
Submodule 'test/test-cases/secrules-language-tests' (https://github.com/SpiderLabs/secrules-language-tests) registered for path 'test/test-cases/secrules-language-tests'

#更新submodule
[root@modsecurity ModSecurity]# git submodule update 
Cloning into 'bindings/python'...
remote: Counting objects: 38, done.
remote: Total 38 (delta 0), reused 0 (delta 0), pack-reused 38
Unpacking objects: 100% (38/38), done.
Submodule path 'bindings/python': checked out 'bc625d5bb0bac6a64bcce8dc9902208612399348'
Cloning into 'others/libinjection'...
remote: Counting objects: 9937, done.
remote: Total 9937 (delta 0), reused 0 (delta 0), pack-reused 9937
Receiving objects: 100% (9937/9937), 5.45 MiB | 1.24 MiB/s, done.
Resolving deltas: 100% (6083/6083), done.
Submodule path 'others/libinjection': checked out 'bf234eb2f385b969c4f803b35fda53cffdd93922'
Cloning into 'test/test-cases/secrules-language-tests'...
remote: Counting objects: 232, done.
remote: Total 232 (delta 0), reused 0 (delta 0), pack-reused 232
Receiving objects: 100% (232/232), 89.18 KiB | 85.00 KiB/s, done.
Resolving deltas: 100% (131/131), done.
Submodule path 'test/test-cases/secrules-language-tests': checked out 'e6b03e46046ce9ce6dcfc0e6ad0820194e21db35'

完成后,在根目录下会有一个build.sh的可执行文件:

[root@modsecurity ModSecurity]# ll -h
total 92K
-rw-r--r--  1 root root  152 Sep 21 10:02 AUTHORS
drwxr-xr-x  3 root root   19 Sep 21 10:02 bindings
drwxr-xr-x  2 root root 4.0K Sep 21 10:02 build
-rwxr-xr-x  1 root root  273 Sep 21 10:02 build.sh
-rw-r--r--  1 root root  14K Sep 21 10:02 configure.ac
drwxr-xr-x  2 root root   81 Sep 21 10:02 doc
drwxr-xr-x  7 root root 4.0K Sep 21 10:02 examples
drwxr-xr-x  3 root root   24 Sep 21 10:02 headers
-rw-r--r--  1 root root  12K Sep 21 10:02 LICENSE
-rw-r--r--  1 root root  15K Sep 21 10:02 Makefile.am
-rw-r--r--  1 root root 8.1K Sep 21 10:02 modsecurity.conf-recommended
drwxr-xr-x  4 root root   74 Sep 21 10:02 others
-rw-r--r--  1 root root  12K Sep 21 10:02 README.md
drwxr-xr-x 11 root root 4.0K Sep 21 10:02 src
drwxr-xr-x  9 root root 4.0K Sep 21 10:02 test
drwxr-xr-x  3 root root   42 Sep 21 10:02 tools

运行build.sh:

[root@modsecurity ModSecurity]# ./build.sh 
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `build'.
libtoolize: copying file `build/libtool.m4'
libtoolize: copying file `build/ltoptions.m4'
libtoolize: copying file `build/ltsugar.m4'
libtoolize: copying file `build/ltversion.m4'
libtoolize: copying file `build/lt~obsolete.m4'
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.
configure.ac:44: installing './ar-lib'
configure.ac:119: installing './config.guess'
configure.ac:119: installing './config.sub'
configure.ac:39: installing './install-sh'
configure.ac:39: installing './missing'
parallel-tests: installing './test-driver'
examples/multiprocess_c/Makefile.am: installing './depcomp'
configure.ac: installing './ylwrap'
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.

在build的过程中会出现以下错误,忽略即可:

fatal: No names found, cannot describe anything.

然后是configure、编译和安装:

#configure
[root@modsecurity ModSecurity]# ./configure 
...
ModSecurity -  for Linux
 
 Mandatory dependencies
   + libInjection                                  ....
   + SecLang tests                                 ....04f7009
 
 Optional dependencies
   + GeoIP                                         ....found v1.5.0
      -lGeoIP  , -I/usr/include/  
   + LibCURL                                       ....found v7.29.0
      -lcurl  ,  -DWITH_CURL
   + YAJL                                          ....not found
   + LMDB                                          ....not found
   + LibXML2                                       ....found v2.9.1
      -lxml2 -lz -lm -ldl, -I/usr/include/libxml2 -DWITH_LIBXML2
 
 Other Options
   + Test Utilities                                ....disabled
   + SecDebugLog                                   ....enabled
   + afl fuzzer                                    ....disabled
   + library examples                              ....enabled
   + Building parser                               ....disabled

#编译
[root@modsecurity ModSecurity]# make

#安装
[root@modsecurity ModSecurity]# make install

编译的需要的时间比较长,请耐心等待。完成后即可查看相关目录与文件:

[root@modsecurity ModSecurity]# tree /usr/local/modsecurity/
/usr/local/modsecurity/
├── bin
│   └── modsec-rules-check
├── include
│   └── modsecurity
│       ├── actions
│       │   └── action.h
│       ├── anchored_set_variable.h
│       ├── anchored_variable.h
│       ├── audit_log.h
│       ├── collection
│       │   ├── collection.h
│       │   ├── collections.h
│       │   └── variable.h
│       ├── debug_log.h
│       ├── intervention.h
│       ├── modsecurity.h
│       ├── reading_logs_via_rule_message.h
│       ├── rule.h
│       ├── rule_message.h
│       ├── rules_exceptions.h
│       ├── rules.h
│       ├── rules_properties.h
│       ├── transaction.h
│       └── variable_origin.h
└── lib
    ├── libmodsecurity.a
    ├── libmodsecurity.la
    ├── libmodsecurity.so -> libmodsecurity.so.3.0.0
    ├── libmodsecurity.so.3 -> libmodsecurity.so.3.0.0
    └── libmodsecurity.so.3.0.0

6 directories, 24 files

0x03.2 nginx

先解压openresty,然后进入openresty的源码文件夹:

#进入文件目录
[root@modsecurity codex]# cd /root/codex/ 

#解压文件
[root@modsecurity codex]# tar zxvf openresty-1.11.2.5.tar.gz 

#进入openresty文件夹
[root@modsecurity codex]# cd openresty-1.11.2.5/

然后使用以下configure参数编译nginx:

#configure
[root@modsecurity openresty-1.11.2.5]# ./configure --prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/var/run/nginx.pid --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --lock-path=/var/lock/nginx.lock --with-luajit --with-http_gunzip_module --with-pcre --with-pcre-jit --with-http_perl_module --with-ld-opt="-Wl,-E" --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-select_module --with-poll_module --with-file-aio --with-http_degradation_module --with-libatomic --http-client-body-temp-path=/var/tmp/nginx/client_body --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --add-dynamic-module=/root/codex/ModSecurity-nginx/
...
Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library
  + using system libatomic_ops library

  nginx path prefix: "/usr/local/nginx/nginx"
  nginx binary file: "/usr/sbin/nginx"
  nginx modules path: "/usr/local/nginx/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx"
  nginx configuration file: "/usr/local/nginx/nginx.conf"
  nginx pid file: "/var/run/nginx.pid"
  nginx error log file: "/var/log/nginx/error.log"
  nginx http access log file: "/var/log/nginx/access.log"
  nginx http client request body temporary files: "/var/tmp/nginx/client_body"
  nginx http proxy temporary files: "/var/tmp/nginx/proxy"
  nginx http fastcgi temporary files: "/var/tmp/nginx/fastcgi"
  nginx http uwsgi temporary files: "/var/tmp/nginx/uwsgi"
  nginx http scgi temporary files: "/var/tmp/nginx/scgi"

cd ../..
Type the following commands to build and install:
    gmake
    gmake install

请注意最后的–add-dynamic-module参数,这里以动态模块的形式连接modsecurity。然后编译和安装:

#编译
[root@modsecurity openresty-1.11.2.5]# make 

#安装
[root@modsecurity openresty-1.11.2.5]# make install 

最后查看nginx版本与检查编译参数:

[root@modsecurity openresty-1.11.2.5]# nginx -V
nginx version: openresty/1.11.2.5
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx/nginx --with-cc-opt=-O2 --add-module=../ngx_devel_kit-0.3.0 --add-module=../echo-nginx-module-0.61 --add-module=../xss-nginx-module-0.05 --add-module=../ngx_coolkit-0.2rc3 --add-module=../set-misc-nginx-module-0.31 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.06 --add-module=../srcache-nginx-module-0.31 --add-module=../ngx_lua-0.10.10 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.32 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.18 --add-module=../redis2-nginx-module-0.14 --add-module=../redis-nginx-module-0.3.7 --add-module=../rds-json-nginx-module-0.14 --add-module=../rds-csv-nginx-module-0.07 --with-ld-opt='-Wl,-rpath,/usr/local/nginx/luajit/lib -Wl,-E' --sbin-path=/usr/sbin/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/var/run/nginx.pid --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --lock-path=/var/lock/nginx.lock --with-http_gunzip_module --with-pcre --with-pcre-jit --with-http_perl_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-select_module --with-poll_module --with-file-aio --with-http_degradation_module --with-libatomic --http-client-body-temp-path=/var/tmp/nginx/client_body --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --add-dynamic-module=/root/codex/ModSecurity-nginx/

0x04 其他

规则的部分请参考以下文章:

使用modsecurity v3并不会出现2.9版本的BUG,日志的问题也恢复正常,在也不需要手动修改配置。如果不介意,可以直接使用默认配置。那么日志的路径和格式如下:

#日志路径
[root@modsecurity ~]# vim /var/log/modsec_audit.log 

#日志格式
---h3LEDdYX---A--
[21/Sep/2017:10:29:19 +0800] 150596095971.505560 123.59.156.221 0 123.59.156.221 443
---h3LEDdYX---B--
GET /feed HTTP/1.0
Host: ngx.hk
X-Forwarded-For: 123.59.156.221
X-Scheme: https
Connection: close
user-agent: Go-http-client/2.0

---h3LEDdYX---F--
HTTP/1.0 403
Server: nginx
Date: Thu, 21 Sep 2017 02:29:19 GMT
Content-Type: text/html
Connection: close
Strict-Transport-Security: max-age=31536000; preload; includeSubDomains

---h3LEDdYX---H--
ModSecurity: Warning. Matched "Operator `PmFromFile' with parameter `scanners-user-agents.data' against variable `REQUEST_HEADERS:user-agent' (Value: `Go-http-client/2.0' ) [file "/root/codex/owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf"] [line "17"] [id "913100"] [rev "2"] [msg "Found User-Agent associated with security scanner"] [data "Matched Data: Go-http-client found within REQUEST_HEADERS:user-agent: Go-http-client/2.0"] [severity "2"] [ver "OWASP_CRS/3.0.0"] [maturity "9"] [accuracy "9"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-reputation-scanner"] [tag "OWASP_CRS/AUTOMATION/SECURITY_SCANNER"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [ref "o0,14v114,18t:lowercase"]
ModSecurity: Warning. Matched "Operator `Ge' with parameter `%{tx.inbound_anomaly_score_threshold}' against variable `TX:ANOMALY_SCORE' (Value: `5' ) [file "/root/codex/owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "36"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "2"] [ver ""] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [ref ""]
ModSecurity: Warning. Matched "Operator `Ge' with parameter `%{tx.inbound_anomaly_score_threshold}' against variable `TX:INBOUND_ANOMALY_SCORE' (Value: `5' ) [file "/root/codex/owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf"] [line "61"] [id "980130"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 5 - SQLI=0,XSS=0,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0): Found User-Agent associated with security scanner"] [data ""] [severity "0"] [ver ""] [maturity "0"] [accuracy "0"] [tag "event-correlation"] [ref ""]

---h3LEDdYX---Z--

0x05 结语

编译安装的过程与2.9版本的有一点点却别,但v3修复了和最新版nginx不兼容的问题。

0x06 相关视频

https://www.bilibili.com/video/av16555265/