WAFの構築とルールの追加

Nginx 版の ModSecurity を Ubuntu にインストールし，OWASP Core Rule Set を使って WAF ( Web Application Firewall )を構築し，ルールを追加する訓練をした。
書いてある通りにやって動くサイトを発見するまで本当に苦労したので，記録に残しておく。

ModSecurity に独自の ルール を 追加 する方法。
How to add your own rules to ModSecurity.

# ModSecurityのインストール

Nginx版のModSecurityをUbuntuにインストールする場合，以下のサイトに記載されているとおりに実施するだけ。
素晴らしい。
このサイトに出会うまで，１０回くらい動かないサイトに悩まされた。

https://www.linuxbabe.com/security/modsecurity-nginx-debian-ubuntu

手順通り進めると，
Step 6 で，OWASP Core Rule Set の導入
Step 10 で，False Positives 対策を学習できる。

# 独自ルールの追加

ゼロデイが発見された場合など，迅速にルールを追加する必要がある。
OWASPに頼らず，自分でルールの追加ができないとModSecurityの使い手とは言えない。
ところが，ルールの追加についても，なかなか有益なサイトを発見できず苦労した。

結論から言うと，Google等の検索サイトで「ModSecurity ルール　追加」とか「ModSecurity rule add」とか検索しても`動くもの`は１サイトも発見できなかった。

最後の手段で公式のマニュアルを見たが，やはり，マニュアル。
読めば，動くルールを作れた。
急がば回れ。ですね。

https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29

## ルールを書く場所

/etc/nginx/modsec/main.confを確認すると次のような記載がある。

```:/etc/nginx/modsec/main.conf
Include /etc/nginx/modsec/coreruleset-3.3.0/rules/*.conf
```

ルールは，ディレクトリ`/etc/nginx/modsec/coreruleset-3.3.0/rules/`に置く必要があり，ファイル名は何でもよいが，拡張子は`.conf`とする必要がある。

私の場合，test.conf とした。

## ルールの書き方

例えば，
http://10.0.2.7:8888/info.php?a=whoami
のようなwhoamiを含むリクエストを防ぐことを考える。

この場合，test.confには次のように記載する

```:/etc/nginx/modsec/coreruleset-3.3.0/rules/test.conf
SecRule ARGS whoami "phase:1,id:12345,t:lowercase,log,pass,msg:'Message text'"
SecRuleUpdateActionById 12345 "t:none,t:compressWhitespace,deny,status:403,msg:'New message text'"
```

そしてルールの点検とnginxの再起動を行う

```
sudo nginx -t
sudo systemctl restart nginx
```

動くものがあると，あとのカスタマイズは簡単。
動くものがあると，あとのカスタマイズは簡単。


## ルールの書式

Syntax: SecRule VARIABLES OPERATOR [ACTIONS]

## VARIABLES

100種類以上ある。公式ページを見るしかない。

https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#variables

が，XSSのルールだとこんな感じなので，ベースにはなると思う。

```
REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/*
```

## phases

どのデータを検閲するか？

phase:1　Request headers
phase:2　Request body
phase:3　Response headers
phase:4　Response body

https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#processing-phases

## rule id

1–99,999がローカル用にアサインされているので，勝手に使ってよい。

https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#id


# WAFをReverse Proxyにする

まずは，includeの確認
sudo cat /etc/nginx/nginx.conf
で
include /etc/nginx/conf.d/*.conf
を確認する。

Reverse Proxyの設定
sudo vi /etc/nginx/conf.d/backend.conf

```
upstream backend {
    server 10.0.2.5:80;         <-- Webサーバ
}

server {
    listen  8888;               <-- WAF      
    server_name  10.0.2.7;      <-- WAF

    location / {
        proxy_pass http://backend;
    }
}
```

# 接続元IPアドレスを伝える

## WAFの設定変更

sudo vi /etc/nginx/conf.d/backend.conf

```
upstream backend {
    server 10.0.2.5:80;
}

server {
    listen  8888;
    server_name  10.0.2.7;

    location / {
        proxy_set_header X-Forwarded-For $remote_addr;     <-- 追加
        proxy_pass http://backend;
    }
}
```

## Webサーバの設定変更

sudo vi /etc/nginx/nginx.conf

```
    # Logging Settings
    ## 
    
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    # ip
    set_real_ip_from 10.0.2.7;          <-- 追加
    real_ip_header X-Forwarded-For;     <-- 追加
    real_ip_recursive on;               <-- 追加

```

# 参考サイト

## How to Set Up ModSecurity with Nginx on Debian/Ubuntu

https://www.linuxbabe.com/security/modsecurity-nginx-debian-ubuntu

## 公式マニュアル

https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29


## ブルート・フォース攻撃対策

「ログイン試行が失敗するたびIP:FAILED_LOGINSフィールドをインクリメントします。ログイン試行の失敗数が3回を超えると、それ以降の試行はブロック」等の有益な情報アリ

https://docs.oracle.com/cd/E92951_01/otd/admin/GUID-A71DEC22-E378-4180-BDAD-198C4732D338.htm


## Oracle Cloud カスタム保護ルール

https://docs.oracle.com/ja-jp/iaas/Content/WAF/Tasks/customprotectionrules.htm


## 古いけど，日本語

https://www.itseclab.jp/security_info/security_intro/modsecurity_construction/

https://www.itseclab.jp/security_info/security_intro/modsecurity_verification/

## NginxをProxyサーバとして動かす方法

https://qiita.com/hana_shin/items/31232789f4a6510e936b

## NGINXで接続元IPアドレス(X-Forwarded-For)を設定する

https://qiita.com/takeshi_hirosue/items/ee1d0630201f792964be

## nginxで複数のproxyを経由する場合でもアクセス元IPアドレスを取得する

https://qiita.com/tjun/items/f6e68924cf6bb616e4ec

## 多段nginxでもX-Forwarded-ForできちんとバックエンドにクライアントIPアドレスを伝える

https://www.serotoninpower.club/archives/780/#%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%98%E3%83%83%E3%82%BF%E3%82%99%E3%81%AE%E6%94%B9%E3%81%95%E3%82%99%E3%82%93%E3%81%A8xff