OCI WAFで脆弱なアプリを保護する - エッジ・ポリシーの場合 -

[前回の記事](https://qiita.com/western24/items/36862526216d6eb886a8)では、WAFポリシーを作成しましたので、今回はGlobal WAFであるエッジ・ポリシーの手順を紹介します。エッジ・ポリシーは、OCI WAFがリリース時から提供されている基本のWAF機能で、OCI以外のプラットフォームで動作するWEBアプリケーションを対象にすることができます。
また、Regional WAFの場合は、ロードバランサーのIPで直接動作させることができましたが、Global WAFでは、ターゲットとなるWEBサーバへのアクセスをWAF経由になるようにDNSレコードの書き換えが必要になります。

そのため、今回のターゲットとなる[DVWA(脆弱なアプリケーション)](https://qiita.com/western24/items/92bc1b82d164d9be41f6)は、パブリックのIPに対するFQDNが必要です。ドメインを持っていない場合は、無料のドメインを取得するなどの準備をしておいて下さい。

※詳細な手順は、[OCIチュートリアル](https://oracle-japan.github.io/ocitutorials/id-security/waf-edge-policy/)にもありますので、こちらもあわせてご参照下さい。


## エッジ・ポリシーの作成
- OCIメニューから、アイデンティティとセキュリティ -> WEBアプリケーション・ファイアウォール -> ポリシーからWAFポリシーの作成を選択。エッジポリシーの場合は、画面下部のレガシー・ワークフローから作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/3d9df244-b8f2-983a-05b2-698bacf2aab5.png)

- プライマリ・ドメインとWAFのオリジン名には、DVWAのFQDN、URIにDVWAのパブリックIPを指定して作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/82be84ba-35b9-f5c7-cefb-367ff06cec15.png)

- 作成されたエッジ・ポリシーの保護ルールに以下の3つのルールIDでフィルタし、ルールに対するアクションをブロックに変更する
9420000, 941140, 9410000
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/c71048e3-1a9a-a6dd-d899-98f82246c8e9.png)

- すべて公開を選択し、ポリシーの編集を反映させる。更新には10分以上かかるので、その間にDNSにCNAMEのレコードを追加する。[参考手順](https://oracle-japan.github.io/ocitutorials/id-security/waf-edge-policy/#6-cname%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E7%99%BB%E9%8C%B2)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/d75c4182-d3e7-0937-bb58-4f3df4424446.png)

## ＷAFポリシーの動作確認
FQDNでDVWAにアクセス(DNS名前解決されCNAMEで指定したWAF -> DVWAのアクセスルートになる)
http://DVWAのFQDN/DVWA-master/login.php

- [この手順](https://qiita.com/western24/items/92bc1b82d164d9be41f6#dvwa%E3%81%AE%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D)でクロスサイト・スクリプティングとSQLインジェクションを実行する。正しくWAFが動作していれば、下記のリクエストをブロックしたメッセージが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/55750c9e-0b51-9d51-e52e-3b8a45b53eb9.png)

- エッジポリシーの詳細 -> ログから確認する。エッジポリシーの場合は、Loggingとの連携機能がないので、ログ参照できるのはこの画面のみでフィルターやグラフなどの機能はない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/d7ed85ea-df86-c390-45ab-b48b089a896e.png)

## Logging Analyticsとのログ連携
エッジポリシーのログは7日間保存。実際の運用では、ログを長期保管するためのオブジェクト・ストレージのバケットを用意し、WAFのログを常にバケットに書き込むようにOracle Supportにリクエストする必要がある。もしくは、OCI-CLIコマンドから自身でWAFのログを取得することも可能

ここでは、手早く確認するためにCLIを使ってログをダウンロードし、そのログをオブジェクトストレージに置き、Logging Analyticsがそこから直接収集するという方式を試してみる

※OCI-CLIが実行できる事前設定が必要。また、SR依頼で出力されるログとCLIで出力されるログのフォーマットは異なるため、以下の手順やログ・ソースは、CLIの場合のみ有効

```
#Object Storageのバケット作成
oci os bucket create --name waflog --compartment-id ocid1.compartment.oc1..

#CLIでWAFのログをダウンロード ※パラメータで日付を指定し、ファイル名に日時を追加
oci waas waf-log list --waas-policy-id ocid1.waaspolicy.oc1.. --time-observed-greater-than-or-equal-to 2023-06-02T00:00+09:00 --time-observed-less-than 2023-06-03T00:00+09:00 --all > waflog_`date +%Y%m%d%H%M`.log

#ログをObject Storageにアップロード
oci os object put -bn waflog --file waflog_xxxxxxx.log

#ログのフォーマットを正しく読み込むためのカスタム・ソースを下記のGithubからダウンロードする
wget https://github.com/western24/wafedge/blob/main/waf_edge_v1.zip
```

- カスタム・ソースをLogging Analyticsにインポートする
ログ・アナリティクス -> 管理、画面下部にある構成コンテンツのインポート。ソース、パーサーにwaf_edge_v1がそれぞれ追加されていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/bb28989e-72e3-e54c-e422-b93675b8056e.png)

- Object Storageの位置を記述したJSONを準備。ここでは、waf_edge_log.jsonのファイル名で作成
{
"name": "<font color="Red">名前</font color>",
"compartmentId": "<font color="Red">コンパートメントID</font color>",
"osNamespace": "<font color="Red">Object Storageのネームスペース</font color>",
"osBucketName": "<font color="Red">バケット名</font color>",
"logGroupId": "<font color="Red">Logging Analyticsのロググループ ID</font color>",
"logSourceName": "waf_edge_log"
}

```
#Logging AnalyticdがObject Storageからログの収集を開始するコマンド。パラメータ HISTORIC_LIVEは、バケットにある古いログから順に収集し、継続的に最新のログを取得することを意味する
oci log-analytics object-collection-rule create --from-json file://waf_edge_log.json --namespace-name namespace --collection-type HISTORIC_LIVE --poll-since BEGINNING
```

- waf_edge_v1のログ・ソースのログがLogging Analtyicsに表示される。Logging Analyticsは定期的にバケットを参照しているので、新規ファイルが追加されるとログを取り込んでいく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/11081052-3b22-dd74-4b02-60f76c48310c.png)

## OCIサポート経由のWAFログとLogging Analytics連携
WAFのログをオブジェクト・ストレージに出力する方法は、[こちら](https://docs.oracle.com/ja-jp/iaas/Content/WAF/Tasks/logs.htm)のCLIタブにあるオブジェクト・ストレージへのWAFログの配信の手順に従い設定する
大まかな手順の流れは、WAFのログを格納するObject Storageのバケットを作成、そのバケットにアクセスできる権限を持つユーザーを作成。そして、以下の必要な情報を埋めて、SRでエッジポリシーのログ出力としてリクエスト。通常1～2日でログの出力されるようになる

1) Primary Domain name of the application: <font color="Red">エッジポリシーで指定した対象のFQDN</font color>
2) Access Key: <font color="Red">ユーザーの顧客秘密キーのアクセス・キー</font color>
3) Secret Key: <font color="Red">ユーザーの顧客秘密キーのアクセス・キーのパスワード</font color>
4) WAF Policy: <font color="Red">エッジポリシーのOCID</font color>
5) Bucket Name: <font color="Red">Object Storageのバケット名</font color>
6) Bucket OCID: <font color="Red">バケットのOCID </font color>
7) Bucket Region: <font color="Red">Object Storageのリージョン</font color>
8) Namespace: <font color="Red">Object Storageのネームスペース</font color>
9) Tenancy OCID: <font color="Red">テナントのOCID</font color>
10) Compartment OCID: <font color="Red">コンパートメントのOCID</font color>
11) Region identifier: <font color="Red">エッジ・ポリシーのあるリージョン</font color>

- バケットのWAFログは、以下のようなディレクトリ構成となり、caching_logsはアクセス・ログ、modsec_logsはポリシーに違反したログが書き込まれる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/0cf4d997-f90e-ed56-193f-0796a3d7091c.png)

- ここでは、ポリシー違反したログ(modsec_logs)をLogging Analyticsに連携する設定を行う。ログのフォーマットを正しく読み込むためのカスタム・ソースを下記のGithubからダウンロードする
https://github.com/western24/wafedge/blob/main/waf_modseclogs.zip

- カスタム・ソースをLogging Analyticsにインポートする
ログ・アナリティクス -> 管理、画面下部にある構成コンテンツのインポート。ソース、パーサーにwaf_modseclogsがそれぞれ追加されていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/bb28989e-72e3-e54c-e422-b93675b8056e.png)

Object Storageの位置を記述したJSONを準備。ここでは、waf_modseclogs.jsonのファイル名で作成
{
"name": "名前",
"compartmentId": "コンパートメントID",
"osNamespace": "Object Storageのネームスペース",
"osBucketName": "バケット名",
"logGroupId": "Logging Analyticsのロググループ ID",
"logSourceName": "waf_modseclogs",
"objectNameFilters":["FQDN/年/月/日/modsec_logs/*"]
}

※objectNameFiltersは、実際に出力さているバケットのmodsec_logsログのディレクトリを見ながら設定する。ワイルドカード(*)の指定も可能

```
#Logging AnalyticdがObject Storageからログの収集を開始するコマンド。パラメータ HISTORIC_LIVEは、バケットにある古いログから順に収集し、継続的に最新のログを取得することを意味する
oci log-analytics object-collection-rule create --from-json file://waf_modseclogs.json --namespace-name namespace --collection-type HISTORIC_LIVE --poll-since BEGINNING
```

- waf_modseclogsのログ・ソースのログがLogging Analtyicsに表示される。Logging Analyticsは定期的にバケットを参照しているので、新規ファイルが追加されるとログを取り込んでいく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/e5be2baa-f5ff-b28a-d12a-b405965dcef3.png)

※Object Collectionルールで指定できるObject Storageのバケットは一つのみ。
WAFのログは、caching_logsとmodsec_logsに２種類のログがひとつのバケットにまとめて出力されるので、caching_logsも同様にLogging Analyticsに取り込む場合は、別のバケットを作成し、移動するなどの対応が必要 

以上がGlobal WAFと呼ばれるエッジポリシーの設定手順の流れです。ロードバランサー型のWAFポリシーとは、動作や設定がかなり異なる点がご理解頂けるのではないかと思います。
特にエッジポリシーのログは、Logging Analyticsにログを分析するパーサーが提供されていないので、今回のように自身でカスタム・パーサーを作成する必要があります。ただ、JSON形式の場合は比較的簡単にできますので、SR経由の場合のログはご自身で験してみて下さい。JSONではないですが、カスタムパーサーの作成手順は[こちら](https://oracle-japan.github.io/ocitutorials/management/logginganalytics_customparser/)

また、ポリシーの保護ルールの設定もWAFポリシーとは若干異なったり、ポット対策などWAFポリシーにはない機能もありますので、このテスト環境で実際の挙動や差異を確認する用途としてもお役立て頂ければ幸いです。

[脆弱なアプリケーション(DVWA)をOCIにデプロイする](https://qiita.com/western24/items/92bc1b82d164d9be41f6)
[OCI WAFで脆弱なアプリを保護する - WAFポリシーの場合 -](https://qiita.com/western24/items/36862526216d6eb886a8)