こんにちは、ACS 事業部の埜下です。
Terraform を元にした Azure Front Door 解説記事の第 4 弾です。 おそらく最後になるであろう今回は Azure Front Door で WAF (Web Application Firewall) を利用する方法について解説していきます。
以前の記事はこちらになります。
どんなときに WAF を使うの?
Azure Front Door で公開する Web サービスやコンテンツを Web の脆弱性や攻撃、悪意のあるボットから保護するときに WAF を使用します。 その他にも特定の IP アドレスからのみ接続させるような制御も可能です。
Terraform で WAF を構築
WAF の説明もそこそこに、Terraform を使って Azure Front Door で WAF を使うように設定していきましょう。 基礎編で使った Azure Front Door の最小構成リソースに加えて、以下のリソースを使用します。
- WAF ポリシー
azurerm_cdn_frontdoor_firewall_policy
- セキュリティ ポリシー
azurerm_cdn_frontdoor_security_policy
WAF を使う場合の Azure Front Door 各リソースの関係性は以下のようになります。
それでは今回使う 2 つのリソースについて細かく見ていきます。
WAF ポリシー
WAF ポリシーはどのような脆弱性や攻撃から守るかをルールで定義するリソースになります。
Azure Portal 上から WAF ポリシーを作成しようとすると、Azure Front Door と Application Gateway どちらに対するポリシーか選択する必要があります。
また、Azure Portal で WAF ポリシーの一覧を表示しても Azure Front Door / Application Gateway 両方の WAF ポリシーが表示されます。
Azure Portal で操作するだけでは WAF ポリシーは Azure Front Door と Application Gateway で共通のものを使用しているように見えますが、実際には Azure Front Door と Application Gateway でそれぞれリソースが分かれています。
- Azure Front Door: frontdoorWebApplicationFirewallPolicies
- Application Gateway: applicationGatewayWebApplicationFirewallPolicies
また、Terraform の azurerm_cdn_frontdoor_firewall_policy
というリソース名からも分かるように、今回使用する WAF ポリシーは Azure Front Door 専用となっています。
ちなみに、Application Gateway で WAF を実装する場合は azurerm_application_gateway
リソースで WAF に対応した SKU を選択して waf_configuration
ブロックでルールを設定していきます。
WAF ポリシーのルール
WAF ポリシーのルールには「マネージド ルール」と「カスタム ルール」の 2 種類を定義できます。 このうち、「マネージド ルール」は Azure Front Door で Premium SKU を選択している場合のみ使用可能です。 Standard SKU でも WAF を使用できますが、要件に応じたカスタム ルールを自分たちで設定する必要があります。
では、マネージド ルールは何をしてくれるのでしょうか。 Microsoft のドキュメントによると、以下の脅威カテゴリに対して保護してくれるルールとなっています。
- クロスサイト スクリプティング
- Java 攻撃
- ローカル ファイル インクルージョン
- PHP インジェクション攻撃
- リモート コマンド実行
- リモート ファイル インクルージョン
- セッション固定
- SQL インジェクションからの保護
- プロトコル攻撃者
これらは Webアプリケーションのセキュリティに関する最も重大な 10 個のリスクとして OWASP Top 10 という形で公開されています。 このような脅威から Web サービスを保護したい場合は Azure Front Door で Premium SKU を選択して WAF ポリシーを設定してください。
また、マネージド ルールには複数の種類があり、それぞれバージョンもいくつか存在しています。
Terraform では managed_rule
ブロックに使用するルールの種類やバージョンを指定します。
# WAF ポリシー resource "azurerm_cdn_frontdoor_firewall_policy" "demo" { name = "wafpolicydemo" resource_group_name = azurerm_resource_group.demo.name sku_name = "Premium_AzureFrontDoor" mode = "Detection" # マネージド ルール # Premium SKU のみ使用可能 managed_rule { action = "Block" type = "Microsoft_DefaultRuleSet" version = "2.1" } }
現在選択できるマネージド ルールの種類は以下になります。
- DefaultRuleSet
- Microsoft_DefaultRuleSet
- BotProtection
- Microsoft_BotManagerRuleSet.
マネージド ルールの細かい仕様については以下の公式ドキュメントを参照ください。
一方、カスタム ルールもある程度リクエストの内容を見てブロックするかどうかを定義することができます。
例えば、以下の例では送信元 IP アドレスが 203.0.113.1
に一致しない場合、アクセスをブロックします。
引数 operator
で検証対象の値と指定値の比較方法を選択しますが、「一致しない場合」といった比較方法はありません。
NOT 演算子は引数 negation_condition
で用意されているため、以下のように実装します。
# WAF ポリシー resource "azurerm_cdn_frontdoor_firewall_policy" "demo" { name = "wafpolicydemo" resource_group_name = azurerm_resource_group.demo.name sku_name = "Premium_AzureFrontDoor" mode = "Detection" # カスタム ルール custom_rule { name = "AllowSpecificGlobalIP" action = "Block" type = "MatchRule" match_condition { match_variable = "RemoteAddr" match_values = ["203.0.113.1"] operator = "IPMatch" negation_condition = true } } }
検出モード / 防止モード
WAF ポリシーはルールに該当するリクエストに対して 2 通りの処理ができます。
1 つは「検出モード」で、脅威のあるリクエストが検出されたことがログに記録されるだけで、実際のリクエストはブロックされません。
もう 1 つは「防止モード」で、ルールに該当したリクエストをルールで指定された動作に従って処理され、ログにも記録されます。 注意すべき点として、「防止」という用語が使われているのでリクエストがブロックされそうな印象を受けますが、実際はルールの指定内容によってリクエストが許可されたり、リダイレクトされたりといった挙動をすることです。
また Azure Front Door で WAF を使用する際は、最初に「検出モード」でどのようなリクエストが検出対象となったかをログで確認し、本来処理すべきリクエストがブロックされる対象となっていないか確認したうえで「防止モード」に変更することをオススメします。
セキュリティ ポリシー
つぎにセキュリティ ポリシーですが、こちらは WAF ポリシーと Azure Front Door を関連付けるリソースとなります。
WAF ポリシーは上述したリソースが使われますが、Azure Front Door はプロファイルを指定するほか、各エンドポイントで使われるドメインを指定する必要があります。 エンドポイントが「既定のドメイン」または「カスタムドメイン」を使っている場合、それぞれに対して WAF ポリシーによる保護をするか選択できます。
# セキュリティポリシー resource "azurerm_cdn_frontdoor_security_policy" "demo" { name = "security-policy-demo" cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.demo.id security_policies { firewall { cdn_frontdoor_firewall_policy_id = azurerm_cdn_frontdoor_firewall_policy.demo.id association { domain { cdn_frontdoor_domain_id = azurerm_cdn_frontdoor_endpoint.demo.id } patterns_to_match = ["/*"] } } } }
ちなみに、association
ブロックに patterns_to_match
という引数がありますが、現状 /*
というパスしか設定できませんのであまり意識しなくても大丈夫です。
おわりに
Azure Front Door で WAF (Web Application Firewall) を利用する方法について Terraform をベースに紹介させていただきました。 基本的には、WAF ポリシーで細かいルールを定義してセキュリティ ポリシーで Azure Front Door と関連付ける、という流れで構築できます。
また、WAF を使用する場合は Azure Front Door の SKU によってマネージド ルールの使用可否が変わります。 高いセキュリティレベルを求められる場合は Premium SKU を選択して、Web サービスをより安全に保護するようにしてください。
そして、「WAF を設定したけど本当に守れられているか分からない」と思われる方もいらっしゃるのではないでしょうか。 そのような場合は「Go Test WAF」という Wallarm 社が開発している WAF 用テストツールがありますので、ぜひお試しください。
ちなみに、弊社は Wallarm 社が提供する「Wallarm クラウドネイティブ WAAP・API セキュリティプラットフォーム」の導入支援サービスもおこなっています。 Web アプリケーションだけでなく API も保護したい場合はぜひ弊社にお声がけください。