🌊

Cloud Armor 事前構成 WAF ルールの適用手順

2023/04/07に公開

こんにちは、クラウドエース SRE ディビジョンの松島です。
今回は Cloud Armor の事前構成 WAF ルールの機能紹介と、実際にサービスに適用する際のルールの調整に関する記事を投稿します。

Cloud Armorとは

Cloud Armor は Google Cloud が提供するマネージド WAF です。
保護ルールをセキュリティポリシーとして定義し、ロードバランサの背後のアプリケーションに紐づけることで DDoS や XSS などの各種攻撃から Web アプリケーションを保護することができます。

Cloud Armor 事前構成 WAF ルールとは

概要

オープンソースの業界標準から集められた多数のシグネチャを持つ、事前定義されたアプリケーション保護ルールです。
指定された記法で Cloud Armor にルールを定義することで、簡易な設定でアプリケーションを SQL インジェクションなどの有名な攻撃から保護することができます。

使い方

Cloud Armor 設定時に「条件」を「詳細設定」にし、含めたい事前構成 WAF ルールを入力すれば保護が有効になります。

enable_preconfigured_rule.png

# 単純に保護する場合
evaluatePreconfiguredExpr('ルール名')

# 特定ルールを除外する場合
evaluatePreconfiguredExpr('ルール名', ['除外するルール名1', '除外するルール名2',...])

# ||で一つのルールに最大5つまで事前構成 WAF ルールセットを含めることが可能
evaluatePreconfiguredExpr('ルール1')||evaluatePreconfiguredExpr('ルール2')|| ...

使用可能な事前構成 WAF ルールの一覧は公式ドキュメントをご参照ください。

また、各ルールには感度レベルが定義されており、数値が低いほど信頼度が高く、数値が高いほどセキュリティは強化されるものの、誤検出が生じるリスクが高まります。
特定の感度レベルより信頼性の高いルールだけを適用することも可能となっています。

事前構成 WAF ルールを環境に適用する

よくある攻撃への対策を効率的に実現できる事前構成 WAF ルールですが、そのまま使うと必要な通信までブロックされてしまうことが多々あります。
そのため、実際に使う場合は

  1. 動作確認用環境で不要ルールを除外
  2. 本番環境にプレビューモードで実装
  3. 本番環境で有効化

のようにある程度段階を踏んで適用していく必要があります。
以下、順にポイントを見ていきます。

1. 動作確認用環境で不要ルールを除外

まずは開発環境やステージング環境などで不要なルールの除外作業を行います。
SI でよく行われるようなウォーターフォールでの開発の場合、開発環境などで結合試験や総合試験を実施することが多いと思いますので、これらの試験が実施される前に事前定義 WAF ルールセットを仕込んでおくことで、ある程度網羅的なトラフィックパターンに対して不要なルールを炙り出す作業を行うことができます。
また、ウォーターフォール以外の場合でも、E2Eテストや、負荷試験用の業務シナリオなどがある場合は、これらのシナリオを流すことでもある程度網羅的に不要なルールを炙り出すことができるのではないかと思います。

不要なルールの除外は以下のような手順で行います。

1-1. Cloud Armor を有効化するとともに、LB のバックエンドサービスのロギングを有効化

下のキャプチャのように、Cloud Armor を有効化するとともにLBのバックエンドサービスのロギングを有効化します。
これにより Cloud Armor がリクエストを攻撃と評価した場合、どのルールによりブロックされたかが Cloud Logging で確認できるようになります。

enable_armor_and_logging.png

1-2. 検知されたルールの確認

Cloud Logging で下記のクエリを実行し、トラフィックがブロックされていないかどうか確認します。

httpRequest.status=403
jsonPayload.enforcedSecurityPolicy.name="{Cloud Armor セキュリティポリシー名}"
jsonPayload.enforcedSecurityPolicy.outcome="DENY"

上記のクエリ結果、必要なトラフィックがブロックされているのであれば、ログエントリを選択し、jsonPayLoad.enforcedSecurityPolicy.preconfiguredExprIdsに引っかかったルールをメモしておきます。
下記の画像の場合はowasp-crs-v030001-id942190-sqliです。

example_log.png

なお、本手順では最初からルールを有効化した状況を想定していますが、もし他の試験の邪魔になるようであれば、ルールをプレビューモードにし、同じように Cloud Logging で状態を確認して順次ルールを除外していけばよいです。
この場合は、クエリのjsonPayload.enforcedSecurityPolicyの部分をjsonPayload.previewedSecurityPolicyとする必要がある点にご注意ください。

1-3. 検知されたルールの除外

メモしておいたルールを事前構成 WAF ルールの除外対象として、下記のように2つ目の引数の除外リストに記載します。

evaluatePreconfiguredExpr('sqli-stable', ['owasp-crs-v030001-id942190-sqli'])

1-4. 1〜3を繰り返す

上記の手順を必要なトラフィックがブロックされなくなるまで繰り返します。
いちいち手動でログを確認するのが大変であれば、ログベースアラートなどを利用して通知するようにしておくと、少し楽になると思います。

2. 本番環境にプレビューモードで実装

すでに本番稼働済みのサービスに対して適用したい場合はプレビューモードで本番環境にルールを設定し、トラフィックに影響を与えないようにした状態でしばらく様子を見るのが良いかと思います。
ここで必要なトラフィックがルールに引っかかった場合は、前の手順と同じくルールの除外作業を行います。

example_log.png

もしサービスイン前の本番環境を使って試験を実施できるような場合は、この手順を飛ばして最初から有効にした状態でルールを設定しても良いと思います。

3. 本番環境に適用

プレビューモードを解除し、実際に事前構成 WAF ルールを適用します。

補足

事前構成 WAF ルールの記法について

evaluatePreconfiguredExpr()に代わるevaluatePreconfiguredWaf()が4/12にGAし、利用可能となりました。
evaluatePreconfiguredExpr()と比べ、感度の調整が楽に行えるようになっています。
詳細は公式ドキュメントをご参照ください

事前構成 WAF ルールの注意が必要な挙動

公式ドキュメントによると、事前構成 WAF ルールの拒否より優先度の低いその他の許可ルールがある場合、リクエスト自体はステータス403で返却されるのにヘッダのみがバックエンドサービスに転送される、という挙動を示すことがあります。

ブロックされたはずのリクエストがバックエンドサービスに転送されているような状況が観測された場合はこちらが原因である可能性がありますので、ご注意ください。

おわりに

最後まで読んでいただきありがとうございました。

Discussion