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関係の基本的な運用は行えるかと思います。
お疲れ様でした!!
おまけ その1
WAF以外でCloud Armorがブロックしたとき
WAF以外のルールでCloud Armorがブロックしている場合、
jsonPayload.enforcedSecurityPolicy.priority
に優先度の番号が表示されます。
この例だと、Cloud Armorで「優先度」が9999で設定されているルールが通信をブロックしています。
そのようなログの見方は、こちらのドキュメントにまとめられています
おまけ その2
DDos攻撃ブロック
同一IPからのDDos攻撃ブロック例
レート制限のドキュメント
Discussion