Nginx Ingress Controller with ModSecurity 環境で Core Rule Set を更新したい...

# はじめに
Nginx Ingress Controller 上に ModSecurity を実装しました。
ModSecurity の Core Rule Set(CRS/OWASP Top ten を含む幅広いシグネチャ)更新方法を確認します。

# 目的
Nginx Ingress Controller 上の Core Rule Set を定期的に更新する。

# 手段
- 理想：Nginx Ingress Controller 上の Core Rule Set のみ更新
- 妥協案：Nginx Ingress Controller 自体のコンテナイメージ含めて更新

ざっとネットを確認しましたが、恐らく妥協案になりそうな気がしています...
  
# ModSecurity 概要
ModSecurity は OSS の Web Application Firewall です。
OWASP Core Rule Set はルールのセットです。CRS は ModSecurity や互換性のある Web サーバで利用できます。

[ModSecurity公式サイト](https://www.modsecurity.org/)を確認すると、Trustwave社の ModeSecurity は2024年7月1日に End-of-Life(EOL)を迎えるとアナウンスしています。
(ModeSecurityさんもあと1年6か月の命なんですね...)
その後、OSS コミュニティに引き渡されるようですが、どうなるか(ちゃんと継続して開発されるか)は分かりません。

現在の最新は v3.x.x 系の様ですが、[Github の README](https://github.com/SpiderLabs/ModSecurity)を読むと、最初は Apache 用で作成され、Nginx や IIS をサポートするために v3 で Apache 依存を削除した模様です。
  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474478/5ac70beb-7201-8f71-adc4-75ffc007724d.png)


# Nginx Ingress Controller 概要
先人の[kubernetesにあるIngress Controllerの一覧を挙げてみる](https://qiita.com/skikkh/items/c59de1f5e188d0bbeb35#:~:text=Nginx%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%9FIngress,nginxinc%2Fkubernetes%2Dingress%E3%81%A7%E3%81%99%E3%80%82)を参考にさせて頂くと、無料で利用可能な Nginx Ingress は2つです。

1. [kubernetes/ingress-nginx](https://github.com/kubernetes/ingress-nginx)
1. [nginxinc/kubernetes-ingress](https://github.com/kubernetes/ingress-nginx)

本環境で採用しているのは前者ですので、`kubernetes/ingress-nginx` を前提に話を進めます。


# Core Rule Set 更新方法
OWASP CRSのドキュメントを確認すると、`IIS/Nginx web server with ModSecurity 3.0.8 or higher` の文言がありました。IIS/Nginx 環境で CRS v3 を利用するには ModSecurity v.3.0.8 以降が必要になります。

従い、恐らく Nginx Ingress は ModSeurity v3.0.8 以降を採用していると推測されます。

Nginx Ingress 上で CRS 関連設定は `crs-setup.conf` ファイルで管理しています。この設定ファイルを変更すれば良いと思いますが、設定ファイルから正しい記述方法が不明なので、もう少しドキュメントを読みます。。。

[KUBERNETES INGRESS CONTROLLER](https://coreruleset.org/docs/operation/kubernetes_ingress/)を読む限り、大した情報はありません。
続いて [https://github.com/coreruleset/coreruleset/blob/v4.0/dev/INSTALL](https://github.com/coreruleset/coreruleset/blob/v4.0/dev/INSTALL)内の `INSTALE` ファイルを確認します。

```txt:INSTALL
Installing on Nginx
-------------------
    1. Compile ModSecurity into Nginx
    2. Ensure that ModSecurity is loading correctly by checking error.log
    at start up for lines indicating ModSecurity is installed. An example
    might appear as follows:
    ```ModSecurity for nginx (STABLE)/2.9.1 (http://www.modsecurity.org/) configured.```
    3. The most common method of deploying ModSecurity we have seen is
    to create a new folder underneath the Nginx directory (typically
    /usr/local/nginx/conf/). Often this folder
    is called 'owasp-modsecurity-crs'. Create this folder and cd into it.
    4. Download our release from https://coreruleset.org/installation/
    and unpack it into a new owasp-modsecurity-crs folder.
    5. Move the crs-setup.conf.example file to crs-setup.conf.
    Please take this time to go through this
    file and customize the settings for your local environment. Failure to
    do so may result in false negatives and false positives. See the
    section entitled OWASP CRS Configuration for more detail.
    6. Rename rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example and
    rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example to remove the
    '.example' extension. This will allow you to add exceptions without updates
    overwriting them in the future.
    7. Nginx requires the configuration of a single ModSecurity
    configuration file within the nginx.conf file using the
    'ModSecurityConfig' directive (when using ModSecurity 2.x).
    Best practice is to set 'ModSecurityConfig' to a file from
    which you will include your other ModSecurity configuration
    files. In this example we will use:
    ```ModSecurityConfig modsec_includes.conf;```
    7. Within modsec_includes.conf create your includes to the
    CRS folder similar to as follows (The modsecurity.conf file from the
    ModSecurity installation is included in this example):
    ```
    Include modsecurity.conf
    Include owasp-modsecurity-crs/crs-setup.conf
    Include owasp-modsecurity-crs/plugins/*-config.conf
    Include owasp-modsecurity-crs/plugins/*-before.conf
    Include owasp-modsecurity-crs/rules/*.conf
    Include owasp-modsecurity-crs/plugins/*-after.conf
    ```
    8. Restart web server and ensure it starts without errors
    9. Make sure your web sites are still running fine.
    10. Proceed to the section "Testing the Installation" below.
```

nginx 用のインストール手順があります。ざっくり概要を整理します。
- まずは `ModSecurity` をコンパイルする
- error.log を確認し、正しく `ModSecurity` がロードされているか確認
- `usr/local/nginx/conf/owasp-modsecurity-crs` フォルダ作成されることを確認
- 最新の Core Rule Set をダウンロードして `owasp-modsecurity-crs` フォルダに展開
- `crs-setup.conf.example` を `crs-setup.conf` にリネイム後、必要であれば設定内容を変更
- `REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example` と `RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example` から "example" 拡張子を除く。次回 CRS アップデート時に当該ファイルは上書きされなくなる
- nginx.conf 内に ModSecurity 用の設定ファイルを指定
- `modsec_includes.conf` ファイルを作成し、CRS フォルダ等を含める
- nginx 再起動して動作確認


ここまでに登場した設定ファイルとパスを整理します。(Ingress nginx controller上で確認)
| パス | ファイル名 | 
|:-----------|:------------|
| /etc/nginx/modsecurity       | modsecurity.conf         |
| /etc/nginx/owasp-modsecurity-crs     | crs-setup.conf      |
| /etc/nginx/owasp-modsecurity-crs     | rules(ディレクトリ)      |
| /etc/nginx/owasp-modsecurity-crs       | nginx-modsecurity.conf(modsec_includes.confと同じ)        |


ここまでを整理すると、再度コンパイルせずに CRS(rules)だけ差し替えて nginx 再起動でいけんじゃね？という発想に至りました！

### 結論
まずは、Ingress nginx cotroller 上の rules フォルダを nfs-volume に切り替えます。次に、rules フォルダ配下のルールセットと `crs-setup.conf` を差し替え、nginx -s reload コマンド実行で CRS を更新することができました。


# 作業過程で気になった点
Q. Nginx Ingress Controller のバージョンは？

**A. Pod を describe する**
```shell
# kubectl describe pod xxx |grep Image
    Image:         registry.k8s.io/ingress-nginx/controller:v1.4.0
```

Q. ModSecurity で利用する Core Rule Set のバージョンは？

**A. crs-setup.conf ファイル内を確認する**
```shell
$ cat /etc/nginx/owasp-modsecurity-crs/crs-setup.conf |grep 'Core Rule Set ver'
# OWASP ModSecurity Core Rule Set ver.3.3.2 // ver3.3.2 ですね。現時点の最新は ver3.3.4 です
```
Q. ModSecurity 自体のバージョンは？

**A. CRS は v3.x.x を使用しているので ModSecurity は v3 以降で間違いありません。しかし、明示的な確認方法は見つかりませんでした。Github 上のドキュメントを細かく見れば情報はあるのかもしれません。。。**

Q. Core Rule Set だけアップデートするもの良いけど、ModSecurity 本体との互換性は大丈夫？

A. v.3.x.x 系であれば問題ないと考えられる(推測)。

# 最後に
ModSecurity の後継は [Coraza](https://coraza.io/)が存在します。CRS v4 に互換性があり、Nginx で利用できるように進められているので、ModSecurity の移行先は Coraza が有力ですね。
その時は Nginx Ingress 側も ModSecurity から Coraza に移行するのでしょうか？



# 参考文献
- [ModSecurity-wiki](https://github.com/SpiderLabs/ModSecurity/wiki/)
- [Kubernetes NGINX Ingress WAF with ModSecurity. From zero to hero!](https://systemweakness.com/nginx-ingress-waf-with-modsecurity-from-zero-to-hero-fa284cb6f54a) // 英語でこれくらいサクッと書けるようになりたい。良記事。
- [OWASP ModSecurity Core Rule Set](https://owasp.org/www-project-modsecurity-core-rule-set/)
- [OWASP® ModSecurity Core Rule Set (CRS)](https://coreruleset.org/)
- [coreruleset/coreruleset](https://github.com/coreruleset/coreruleset/) // OWASP の CRS git はここ
- [Installation Guide](https://kubernetes.github.io/ingress-nginx/deploy/) // Nginx Ingress Controller の公式ドキュメントはここ