Google Cloud(GCP)でWAF導入 ~ Cloud Armorを使ったWAF構築方法
構築の流れ
Google Cloudでは、WAFは Google Cloud Armor (以下 Cloud Armorと呼びます)に含まれています。
Cloud Armorは複数の料金がありますが、初めから使える スタンダードでWAFを使うことができます。
まず、Cloud Armorで通信のルール(ポリシー)にWAFを設定します。
次に、Cloud Armorをロード バランシングに設定することで通信にWAFルールを適用することができます。
余談ですが、Cloud ArmorはWAF以外に特定のパスに通信できるIPを制限するなど様々なルールを適用することができます。
Cloud Armorに設定を変更すると、1分くらい(?)で通信に設定が反映されます。
Cloud ArmorでWAF設定
それは、Cloud ArmorでWAFのポリシーを作っていきましょう。
コンソール画面でCloud Armorのポリシーを開いてください
通信を制限するポリシーとして、WAFを設定します。
それ以外の、IP制限などもまとめて設定することが可能です。
ポリシーを作る
「ポリシー生成」を開きます
適当な名前でポリシーを作成します。
ここでは、「デフォルトのルール アクション」を通過できるようにしています。
これで、一旦ポリシーを作成します。
WAFルールを追加する
適用できるWAFルールはここに書かれています。
用意されたWAFルール
- SQL インジェクション
- クロスサイト スクリプティング
- ローカル ファイル インクルード
- リモートコード実行
- メソッドの適用
- スキャナ検出
- プロトコル攻撃
- PHP インジェクション攻撃
- セッション修正攻撃
- Java 攻撃
- NodeJS 攻撃
- CVE とその他の脆弱性
- JSON 形式のコンテンツの SQLi の脆弱性
13個のルールが存在します。
この中から、必要なものだけを設定することができます。
例えば、NodeJSを使っていなのに「NodeJS 攻撃」から防御するルール入れたりする必要はありません。
そして、この項目はルールの「大項目」で実際のルールは、もう少し細かく分かれています。
詳細ルールと感度レベル
一例として、「Java 攻撃」のルールを見ます。
表のように「Java 攻撃」のルールは複数のルールがセットになっています。
また、通信をどこまで攻撃とみなすかの感度レベルも記載されています。
感度レベルが高いほどセキュリティは高まりますが、通常の通信を攻撃だと誤検知するリスクも高まります。
状況に応じて適当なレベルを選択します。
ルールとしては、式
で記載されている箇所を記載します。
例えば、「Java 攻撃」の感度レベル3だと
evaluatePreconfiguredWaf('java-v33-stable', {'sensitivity': 3})
感度レベルは指定された値以下のレベルが適用対象になります。
つまり、
- 感度レベル3指定だと、3・2・1のルールを適用
- 感度レベル2指定だと、2・1のルールを適用
- 感度レベル1指定だと、1のルールを適用
「Java 攻撃」は感度レベル3にすることで、表にある全部のルールが適用さます。
また、感度レベルを指定し、特定ルールのみ除外することも可能です。
ポリシーにWAFルールを追加する
設定すべきWAFが決まったら、ポリシーに追加していきます。
さきほど追加したポリシーを開き
「ルールを追加」を開きます
- 「詳細に変更」
- 先ほどのWAFルールを入れます
- 通信を「拒否」していることを確認
- (普通は)優先度は小さめの数値にします(ここでは、千番台をWAFに振っています)
※優先度について:ルールは複数設定でき、優先度の数値が低いものから先にチェックされます。
設定したルールや優先度は後から変更できます。
「追加」ボタンを押すことで、ルールが追加されます。
ルールは複数追加できるので、同じ要領で他の攻撃への対策も追加していきます。
いくつかのWAFルールを追加した例です。
(何を追加するかは状況次第ですが)個人的には、よくある設定ファイル(例 .env)などをスキャンする攻撃を防ぐ「ローカル ファイル インクルード」は基本的にいれた方が良いと思います。
通信を見る限り、「ローカル ファイル インクルード」の攻撃頻度は高いです。
Cloud Armorをロード バランシングに追加
Cloud Armorをロード バランシングに追加することで、ポリシーに従って通信がフィルタリングされます。
ポリシーに追加されたWAFも適用されます。
ロード バランシングを開きます
Cloud Armorを導入したいロード バランシングを「編集」します。
「バックエンドの構成」からバックエンドを変更します
用意したCloud Armorのポリシーを選択します。
合わせて、しばらくの間は通信を監視できるように、通信ログの取得も行います。
↓
設定を反映させることで、WAFを含むCloud Armorのポリシーが適用されます。
(反映には少し時間がかかります)
お疲れ様でした。
Cloud Armorのポリシーを調整する
実際に運用にするとWAFが必要な通信までブロックしてしまうことがあります。
通信のログを確認し、WAFがブロックを行ったか、ブロックしている場合は、どのルールがブロックしているかを確認しましょう。
ログを確認する
ログが集まっている「Logging」を開きます。
ログを絞り込む
Cloud Armorがブロックしたログを絞り込みましょう。
jsonPayload.enforcedSecurityPolicy.outcome="DENY
の項目で、絞り込みをかけてください。
絞り込まれた項目の中から、時間やURLをヒントに該当の通信を探してください。
通信をブロックしたルール
通信をブロックをしたルールは、
jsonPayload.enforcedSecurityPolicy.preconfiguredExprIds
の中にあります。
この例では、owasp-crs-v030301-id942100-sqli
のルールにより通信をブロックしています。
ルールを除外する
ポリシーのルールが正常な通信を妨害していた場合、ポリシーからそのルールを除外しましょう。
上の例、owasp-crs-v030301-id942100-sqli
をルールから除外してみましょう。
ルールの大項目を探す
owasp-crs-v030301-id942100-sqli
の末尾が、sqli
なので、「SQL インジェクション」用のsqli-v33-stable
だとわかります。
念のため、ドキュメントを開いて確認してみましょう
項目を絞り込むと、「SQL インジェクション」のルールがヒットしました
ポリシーの変更
それでは、ポリシーを変更します。
Cloud Armorのポリシーを開きます。
ルールから、今回変更を行いたいsqli-v33-stable
を探します。
ルールの記載は、ドキュメントに従います。
opt_out_rule_ids
に除外したいルールを記載します。
今回だと元の記載
evaluatePreconfiguredWaf(
'sqli-v33-stable',
{
'sensitivity': 1
}
)
↓
evaluatePreconfiguredWaf(
'sqli-v33-stable',
{
'sensitivity': 1,
'opt_out_rule_ids': ['owasp-crs-v030301-id942100-sqli']
}
)
実際に変更するとこの画像のようになります↓
この変更で、owasp-crs-v030301-id942100-sqli
のみ除外されました。
変更後、1分くらい(?)で設定が反映されます。
なお、opt_out_rule_ids
複数いれることで複数のルールを除外することができます。
evaluatePreconfiguredWaf(
'sqli-v33-stable',
{
'sensitivity': 1,
'opt_out_rule_ids': ['owasp-crs-v030301-id942100-sqli', 'owasp-crs-v030301-id942140-sqli', 'owasp-crs-v030301-id942160-sqli']
}
)
これで、WAF関係の基本的な運用は行えるかと思います。
お疲れ様でした!!
おまけ
WAF以外でCloud Armorがブロックしたとき
WAF以外のルールでCloud Armorがブロックしている場合、
jsonPayload.enforcedSecurityPolicy.priority
に優先度の番号が表示されます。
この例だと、Cloud Armorで「優先度」が9999で設定されているルールが通信をブロックしています。
そのようなログの見方は、こちらのドキュメントにまとめられています
Discussion