🌲

AWS WAFとサードパーティWAFを併用する

2023/02/28に公開

はじめに

AWS WAFv2のAWS WAFマネージドルールと、サードパーティのWAFを一つのWeb ACLで共存させ、ALBやAPI Gatewayの保護に活用したときのメモです。
一般的に両方同時に活用しようとすると管理面・運用面で課題があり、どのような解決を試みたかを書いています。

※具体的なサードパーティWAFの設定方法について、またWAFの費用などについては、この記事ではほとんど触れていません。

それぞれの特性

AWS WAFマネージドルールを利用する

まず、純粋にAWS WAFのみを利用する、つまり純正AWS WAFマネージドルールのみを利用する場合を考えてみます。

2023年2月時点では、AWSのマネージドルールとして以下のようなルールグループが提供されています。これらルールグループの中にさらにそれぞれWAFルールが包含されています。

これら全てを有効にすることは不可能ですし、環境によって導入する意味合いが薄いものもありますが、これだけあると相当のパターンのリクエストに対応することが可能に見えます。
ここで改めてWAFマネージドルールのメリットを考えてみると、ルールグループの種類が多い点に加え、例えば以下のような側面があります。

  • AWSによって随時アップデートされ、新規の脆弱性や最新の攻撃元IPアドレスをブロックできる
  • サードパーティのWAFと比較して、低コストで利用できる
  • Web上での情報が比較的多い

サードパーティWAFをAWS環境で利用する

一方、サードパーティで提供されているWAFについてです。
実は「サードパーティWAF」と一口に言っても、サードパーティによっては2つまたはどちらか1つの利用方法・アプローチがあり、どの方法を採用するかをまず検討する必要があります。

  • 別途サードパーティWAFを契約・設定してWeb ACLと紐付ける
  • サードパーティが提供しているマネージドルールをAWS WAFのルールの一つとして導入する

後者は、AWSマネージドルールと同様にAWSマネージメントコンソール上で選択することになり、比較的廉価で導入の敷居が低く、支払いもAWSの利用料金にまとめることができます。しかしながら、不正なリクエストから防御する効果やルールの選択肢、得られる副次的なメリットが前者に比べて限られる場合も考えられ、慎重に検討する必要があります。

以降、本記事では、前者の別契約のWAF活用方法を指してサードパーティWAFという言葉を使います。

それでは同じようにメリットを書き出してみます。

  • サードパーティのより迅速な更新によって最新の脆弱性への対応が期待できる
  • プラン・契約によってはカスタマイズや誤検知対応を最適化できる。あるいは運用を一部任せられる
  • 専用のポータルなど設定が容易であったり、レポート機能など付随的な機能を利用できる場合がある
  • メールや電話などサポートを受けることができる

併用した際の課題

AWSマネージドルールとサードパーティWAF併用の課題点を議論する前に、WCUの概念を理解する必要がありそうです。馴染みがない場合は以下のリンクをご一読下さい。(とりたてて難しい話では無いのですが、独自の概念のように思われたため紹介したいと思いました。)

https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/how-aws-waf-works.html#aws-waf-capacity-units

このWCUですが、サードパーティWAF導入時に「余る」ことがあります。つまり、サードパーティWAFだけでは(キャパシティ面で)まだ余裕があり、余ったキャパシティで他のルールや、AWSマネージドルールを追加する事が可能です。サードパーティWAFの性質によっては不要であるかもしれませんが、どちらかというと”もったいない”という思考になり、是非併用したいと考えるようになりました。

しかしここで問題があります。サードパーティが管理するWAFと、TerraformなどIaCで管理されたAWS WAFの相性は悪く、同一のWeb ACLで共存させる(=どちらかによる変更のみを優先させず両立する)には工夫が必要になります。具体的には設定項目やルールの一部をIaC管理から外す、ignore_changesを設定するといった追加的な配慮が必要となるはずです。
当初このignore_changes設定を試みたのですが、現状のTerraformの仕組みだとスマートな記述は難しいことがわかりました。WAFに限らず、あまりignore_changesが増えてしまうとTerraformでそのリソースを管理する意味がなくなってしまうため、どのリソースを、あるいはどの粒度でIaCにするかという点は悩ましい問題ですね。

さらに、(サードパーティの仕様によりますが)ルールグループの優先度をサードパーティ側で制御する仕組みが入っていた場合、仮にルールだけをignore_changesするといった設定をしても結局terraform plan実行時に差分が出てしまいます。そのため、サービス運用者とWAFサードパーティベンダーによる二重管理ともいえる状況となり、運用していくことは、事実上難しいと思われます。

なお、このWAFルールのIaC問題については、Web ACL側の制約、ロードバランサーやAPI Gatewayなどのリソースは 1つのWeb ACLのみに紐付けられる という制約が厳しい、という見方もあるかもしれません。別途Web ACLを用意し、それぞれ分けて運用できれば解決する問題ではあるからです。一応回避策として、CloudFrontをALBの前段に配置すれば、この方法を実践できるかもしれません。

どうしたか?

前置きが長くなりましたが、それではどうしたのか、結論を書くと...
「サードパーティWAFを併用したことでWAFに関してはIaCはあきらめて、代わりにAWS CLIを活用してゆるくルールをJSONファイルとして管理」 しました。

個人的には「ゆるいIaC」と勝手に呼んでいます。そもそも動的な変更をする機会があるWAFはIaCで管理しないほうが都合良い場合もありそうだと考え直しました。

具体的には、ルール設定部分だけをAWS CLIのコマンドで取得してJSONファイルにし、Git/GitHubで管理します。

  1. マネージメントコンソールでルールを変更する
  2. 現在のWAF設定・ルールを取得し、JSONファイルとして保存する
  3. (必要があれば手元で修正する)
  4. (修正した場合には、設定をupdate-web-aclで反映する)

ルール情報取得のためのbashスクリプト例

get-rules.sh
#!/bin/bash

ENV="prd"
WEB_ACL_ID="1111aaaa...2222bbbb"
WEB_ACL_NAME="hoge_web_acl"

WEB_ACL_ALL_CONFIG=$(aws wafv2 get-web-acl \
    --id "${WEB_ACL_ID}" \
    --name "${WEB_ACL_NAME}" \
    --scope REGIONAL
)
# get-web-aclでは、idとnameの両方の指定が必要な点にご注意下さい。
# scopeに関してはCloudFrontを利用している場合は CLOUDFRONT となります。

echo "${WEB_ACL_ALL_CONFIG}" | jq '.WebACL.Rules' > "${ENV}-rules.json"

上のスクリプトを実行して生成されたルールファイルの例

prd-rules.json
[
  {
    "Name": "Third-Party",
    "Priority": 0,
    "Statement": {
      "RuleGroupReferenceStatement": {
        "ARN": "arn:aws:wafv2:ap-northeast-1: - snip -"
      }
    },
    "OverrideAction": {
      "None": {}
    },
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "Third-Party"
    }
  },
  {
    "Name": "AWS-AWSManagedRulesKnownBadInputsRuleSet",
    "Priority": 1,
    "Statement": {
      "ManagedRuleGroupStatement": {
        "VendorName": "AWS",
        "Name": "AWSManagedRulesKnownBadInputsRuleSet"
      }
    },
    "OverrideAction": {
      "None": {}
    },
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "AWS-AWSManagedRulesKnownBadInputsRuleSet"
    }
  }
]

この方法ですと、以下のようなメリットが享受できるはずです。

  • マネージメントコンソールからの設定変更を柔軟に許容できる
  • コードベースの修正もできる(例えばサンプリング有効化/無効化など)
  • Git管理下とすることで変更履歴を追うことができ、差分も表示しやすい
  • GitHub等でチームメンバーと共有できる

一方でこれは折衷案に近く、当初の問題が完全に解消したわけではありません。

  • 他の設定や、紐付けるリソース(例えばALBなど)の情報は扱われない
  • アドホックに、あるいは定期的にスナップショットを取る(設定をJSONに落とす)必要があり、作業を怠ると現在のルール設定とファイルの記述に乖離が生じた状態になる

などを認識の上で扱う必要があります。

おわりに

WAF導入を検討する際の現実的な解として、AWSマネージドルールとサードパーティWAFの併用という選択肢はWCUの効率的な使用という観点から推奨されるべきですし、それぞれのメリットを補完的に活かせるのではないかと考えています。言わば、いいとこ取りですね。
もちろん予算次第であったり、WCUの余裕幅であったり、何がしたいかに依る部分は大きいです。
しかし、WAFを導入される際には様々なサードパーティWAFの特性を比べつつ、一度は併用も検討してみても良いのではないでしょうか。

これから検討をされるどなたかに届けば幸いです。

Discussion