Nginx + ModSecurity

環境

Nginx 1.19.6, ModSecurity3, Ubuntu 12.04

ModSecurityインストール

ModSecurityのライブラリとルールをリポジトリからインストール

$ sudo apt install libmodsecurity3 libmodsecurity-dev modsecurity-crs

Nginxとの連携用コネクタ導入

コンパイルに必要なもろもろをインストール

$ sudo apt install build-essential
$ sudo apt install libpcre3 libpcre3-dev zlib1g zlib1g-dev

Githubからソースをダウンロード
https://github.com/SpiderLabs/ModSecurity-nginx

$ mkdir work
$ cd work
$ wget https://github.com/SpiderLabs/ModSecurity-nginx/releases/download/v1.0.1/modsecurity-nginx-v1.0.1.tar.gz
$ tar zxvf modsecurity-nginx-v1.0.1.tar.gz

サーバーにインストールしてあるNginxのバージョン確認

$ nginx -v

コネクタをコンパイルするため、Nginxのソースをダウンロード
http://nginx.org/en/download.html
※ 同じバージョンのNginxを選択

$ cd work
$ wget http://nginx.org/download/nginx-1.19.6.tar.gz
$ tar zxvf nginx-1.19.6.tar.gz

オプションをつけてコネクタをコンパイル

$ cd nginx-1.19.6
$ ./configure --add-dynamic-module=/path/to/modsecurity/modsecurity-nginx-v1.0.1 --with-compat
$ make modules

作成したモジュールをNginxの管理フォルダ配下へコピー

$ sudo cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/

Nginxの設定変更

Nginxの設定ファイルを更新してライブラリをロード

$ sudo vi /etc/nginx/nginx.conf
---
user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
load_module modules/ngx_http_modsecurity_module.so;
---

ModSecurityの設定ファイルを取得

$ sudo mkdir /etc/nginx/modsec
$ cd /etc/nginx/modsec
$ sudo wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/unicode.mapping
$ sudo wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended
$ sudo mv modsecurity.conf-recommended modsecurity.conf

modsecurity.confは、デフォルトだと「SecRuleEngine DetectionOnly」
検知した通信を遮断する場合は「SecRuleEngine On」へ変更

$ sudo vi /etc/nginx/modsec/modsecurity.conf
# -- Rule engine initialization ----------------------------------------------
# Enable ModSecurity, attaching it to every transaction. Use detection
# only to start with, because that minimises the chances of post-installation
# disruption.
#
SecRuleEngine DetectionOnly

ModSecurityのルールをGitから取得
(Ubuntuのリポジトリから取得するルールよりも新しいことを期待)

$ wget https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/v3.2.0.tar.gz
$ tar zxvf v3.2.0.tar.gz
$ rm v3.2.0.tar.gz
$ sudo cp owasp-modsecurity-crs-3.2.0 /usr/local/
$ cd /usr/local/owasp-modsecurity-crs-3.2.0
$ sudo mv crs-setup.conf.example crs-setup.conf
$ sudo mv rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
$ sudo mv rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf

ルールの読み込み設定ファイルを作成
読み込むルールは適宜取捨選択。(903周りは利用するアプリに応じてなど)

$ sudo vi /etc/nginx/modsec/main.conf
---
Include "/etc/nginx/modsec/modsecurity.conf"
Include /usr/local/owasp-modsecurity-crs-3.2.0/crs-setup.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-901-INITIALIZATION.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-903.9003-NEXTCLOUD-EXCLUSION-RULES.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-903.9004-DOKUWIKI-EXCLUSION-RULES.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-903.9005-CPANEL-EXCLUSION-RULES.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-903.9006-XENFORO-EXCLUSION-RULES.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-905-COMMON-EXCEPTIONS.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-910-IP-REPUTATION.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-911-METHOD-ENFORCEMENT.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-912-DOS-PROTECTION.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-913-SCANNER-DETECTION.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-921-PROTOCOL-ATTACK.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-949-BLOCKING-EVALUATION.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/RESPONSE-950-DATA-LEAKAGES.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/RESPONSE-959-BLOCKING-EVALUATION.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/RESPONSE-980-CORRELATION.conf
Include /usr/local/owasp-modsecurity-crs-3.2.0/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
---

保護したいディレクティブに対して、Nginxの設定をいい感じに変更

$ sudo vi /etc/nginx/conf.d/<xxx>.conf
---
server {
     listen 443 ssl;
     modsecurity on;
     modsecurity_rules_file /etc/nginx/modsec/main.conf;
}
---

Nginxの再起動

$ sudo systemctl reload nginx

動作確認

テストアクセスを実行

$ curl -H "User-Agent: Nikto" https://<hostname>/

上記は「REQUEST-913-SCANNER-DETECTION.conf」にマッチしてブロックされる。
「SecRuleEngine On」としている場合は403 応答になる。

$ curl -H "User-Agent: Nikto" https://<hostname>/
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.19.6</center>
</body>
</html>

なお検知した結果は監査ログ「/var/log/modsec_audit.log」に出力される。