AzureのWAFポリシーとアプリケーション ゲートウェイについてまとめてみた

"AzureのWAFポリシーとアプリケーション ゲートウェイについてまとめてみた"

はじめに

法人のお客さま向けAzure案件に参加している井上です。今回初登場となります。
このブログではAzureで提供されている「アプリケーション ゲートウェイ」(以下APGW)と「Web Application Firewallポリシー (WAF)」 (以下WAFポリシー)について、「クセが強い」と感じた部分をピックアップしつつ、以下の内容を説明します。

  1. 用語の定義
  2. AzureのWAFポリシーとは・・・ WAFポリシーについて、ざっくりと説明します。
  3. 機能や設定の確認・・・ WAFポリシーを構成するコンポーネントを確認します。
  4. 不正アクセスによる検証・・・ 不正アクセスログを確認して、誤検知の場合の対応を説明します。
  5. 検証環境の構築・・・ 今回のブログで使用した簡単な検証環境を構築します。

1. 用語の定義

このブログにおける、”WAF”に関連する用語の定義について

今回説明する「リージョンのWAF (Application Gateway)」には2つのWAFがあります。
※「リージョンのWAF」とは、東日本や西日本などのリージョン単位で、一つのリージョン内に設置するAPGWと連携して動作するWAFポリシーを意味しています。(ちなみに、複数リージョンに設置された複数のAPGWを背後に配置できる「Front Door」というグローバルWAFもありますが、今回は対象外です)

1つ目は、カテゴリ→ネットワーキングにある、「Web Application Firewall ポリシー(WAF)」で、Azure Portalでは以下のアイコンで表示されています。

このブログでは「WAFポリシー」と表記します。

2つ目は、カテゴリ→ネットワーキングにある、「アプリケーション ゲートウェイ」のWAFで、以下のアイコンで表示されています。

このブログでは「APGW WAF」と表記します。
※「WAFポリシー」と「APGW WAF」の違いについては後述します。

また、単に「アプリケーション ゲートウェイ」を意味する場合は、「APGW」と表記します。
さらに、Azure以外も含めて、一般的な意味での「Web Application Firewall」を、「WAF」と表記します。

2. AzureのWAFポリシーとは

WAFポリシーの利用目的について

AzureのWAFポリシーを利用する目的としては、SQLインジェクションアタックやクロスサイトスクリプティングなど、L3/L4のFirewallでは判断できないWebの脆弱性からサーバを保護するために使います。なお、カスタムルールを使用すれば、L3/L4 Firewallのように特定のIPアドレスに対する制御も行うことができます。

AzureのWAFポリシーを構成するCore Rule Set (CRS)について

AzureのWAFポリシーでは、OWASP ModSecurity Core Rule Set(CRS)を使用したオープンなWAFが採用されています。
OWASPのリンク→https://owasp.org/www-project-modsecurity-core-rule-set/

CRSはWebサイトに対してリスクとみなされる攻撃パターンを定義したもので、それぞれのルールの詳細は以下のリンクで確認できます。(v3.1) https://github.com/coreruleset/coreruleset/tree/v3.1/master/rules

現在(2021/7)サポートされているAzureのルールセットは「v3.1」、「v3.0」、「v2.2.9」で、「v3.2」がプレビューとして選択できます。

ちなみに、OWASPのサイト(https://coreruleset.org/)では現時点(2021/7)において、「3.3.2」が最新となっています。
(あと、一番下に見える”Microsoft_BotManagerRuleSet_0.1”は、既知の悪意のあるIPアドレスを使用したbotからのアクセスをブロック、またはログに記録するもので、OWASPルールセットと併用して使うことが出来ますが、今回は対象外です)

WAFポリシーの2つのモード

ポリシーモードには、「検出」と「防止」の2つがあり、WAFポリシー→「概要」で、設定を行います。
「検出」モードはポリシーがルールにマッチした時のログ記録のみを行い、アクセスのブロックは行いませんが、「防止」モードは一定の条件を満たした場合に、アクセスのブロックを行います。(後述)以下の画面の例では、ポリシーモードは「検出」モードになっており、画面上側にある「防止モードに切り替える」をクリックすることで、防止モードで動作するようになります。

3. 機能や設定の確認

WAFポリシーとAPGWの動作に必要なコンポーネント

APGWのセットアップ時には、「フロントエンドIP」、「ルール」、「リスナー」、「HTTP設定」、および「バックエンドプール」の設定を行います。関連するコンポーネントとして、「Network Security Group 」(NSG)と「Virtual Machine」の設定も必要となります。なお、NSGのアクセス評価については、WAFポリシーの評価よりも先に行われるため、事前にNSG側でInboundアクセスに対して、APGWのフロントエンド IPへのアクセスを許可しておく必要があります。

WAFポリシーとAPGW WAFの違いについて

少しややこしいのですが、WAFポリシー以外に、APGWの設定にも「Web アプリケーション ファイアウォール」があります。このWAF(APGW WAF) は、「WAFポリシー」とは独立して動作し、WAFポリシーと同様にOWASPのルールを使用したWAFを構築することができます。

以下にAPGW WAFの設定画面を示します。

ちなみに、以下はWAFポリシーの設定画面になります。

WAFポリシーとAPGWとの関連付けに「HTTP リスナー」を選択した場合はWAFポリシーとAPGW WAFの両方を有効化することが出来ます。ただし、ホストへのアクセスに割り当てられるWAFはWAFポリシーかAPGW WAFのどちらか一つになり、評価の優先度などをつけて併用することは出来ません。

このとき、WAFポリシーでリスナーの関連付けがあるアクセスは、WAFポリシーで評価され、関連付けがないものはAPGW WAFで評価されるという動作になり、WAFポリシーとは違うポリシーを使いたいアクセスがある場合に有効です。(例えばWAFポリシーでOWASP_3.1、APGW WAFでOWASP_3.2を利用するなど)

例えば以下のように、APGWに2つの「リスナー」(labo01-listener01とlabo01-listener02)がある場合、それぞれが「関連付けられているルール」によって、それぞれの「ホスト名」にルーティングされ、ホストへのアクセスはWAFポリシーで評価されます。

APGWの2つの「HTTPリスナー」に対してWAFポリシーの関連付け(赤い線)がある場合、イメージ的には以下のような感じになります。

WAFポリシーとAPGWとの関連付けが「labo01-listener01」のみとなっていて、「labo01-listener02」の関連付けが無い場合。

この場合は、ホスト名“multisite01.ddns.net”へのアクセス(赤い線)はWAFポリシーで評価され、WAFポリシーとの関連付けが無い「multisite02.ddns.net」へのアクセス(緑の線)はAPGW WAFで評価されることになります。

イメージ的には以下のような感じになります。

なお、APGW WAFではカスタムルールがサポートされないため、ホワイトリスト対応などができません。そのためカスタムルールを使用して特定のIPアドレスを許可したり拒否したりといった運用を予定している場合は、「WAFポリシー」を選択する必要があります。カスタムルールが必要ない場合、追加のコンポーネントとしてWAFポリシーを作成して関連付ける必要もないため、「APGW WAF」を選択した方がシンプルな構成にできます。

マルチサイトのリスナーとルールについて

WAFポリシーとAPGWとの関連付けで使用するAPGWの「リスナー」には、「Basic」と「マルチサイト」があり、この「マルチサイト」を選択すると、1台のAPGWで複数のURIをホストすることが出来ます。これは従来からWebサーバなどにある、HTTP/1.1のホストヘッダを利用したバーチャルホストと同様の機能です。APGWのリスナーの設定画面は以下の通りです。

上図のように、「リスナーの種類」が「マルチサイト」の場合、「ホスト名」で指定されたURIへのアクセスは、「関連付けられているルール」に指定されたバックエンドターゲットにルーティングされます。

以下にあるのが、「ルール」の設定画面で、「バックエンドターゲット」で、アクセス先となるホストが所属する「バックエンドプール」を指定します。

4. 不正アクセスの検証

不正アクセスログの確認

実際に不正アクセスとして検出されるアクセスを行い、検出されたログを確認します。
今回利用するOWASP3.1では、以下の4段階でレベルが定義され、同じ攻撃者からの累積した重大レベルの合計スコアが5を超えると、アクセスがブロックされます。

不正アクセスの検証では、以下の環境を利用します。

検証環境に対して、“WAF Testing Tool”を使って、WAFで保護されたホストに攻撃をして、以下のログを取得しました。(攻撃の方法については、”WAF Testing Tool”をウェブ検索すると、いろいろ出てくるので、それらをお試しください。自己責任かつ、ご自身が管理しているホストに対してのみテストしてください)

上図の赤枠部分から以下のことが確認できます。

このログでマッチしたのは、ルールIDが”920300”で、その詳細情報は「details_file_s」にあるルール名「REQUEST-920-PROTOCOL-ENFORCEMENT.conf」を以下のサイトで調べると確認することができます。
https://github.com/coreruleset/coreruleset/tree/v3.1/master/rules

このルールの「msg:」から始まる部分を確認すると、「Request Missing an Accept Header」というのがルールにマッチした内容として確認できます。(ここで検出された、『リクエストにAccept Headerがない』というルールは、開発者がブラウザ以外の開発ツールなどを使用してアクセスした場合などに検出されることがあります。あわせてログの「clientIp_s」が開発者が使用しているなど、既知のIPアドレスであれば、このアクセスは安全であると判断できます)

また、「Severity:」が「NOTICE」とあるので、このルールID「920300」は、重大レベルの累積スコアとして「2」が加算されるルールであることが確認できます。

管理されているルールの無効化対応

誤検出されたアクセスを許可するためのルールの無効化を行います。
今回検出された「920300」を許可する場合、WAFポリシーの「管理されているルール」で、全て展開をクリックします。

展開されたルールから、「920300」のチェックボックスをクリックします。

画面左上にある「無効化」をクリックします。

「920300」が無効化されたことを確認したら、「保存」をクリックします。

カスタムルールでのホワイトリスト対応

カスタムルールで特定のIPアドレスを許可する手順を説明します。
WAFポリシーの「カスタムルール」で、「+カスタムルールの追加」をクリックします。

「カスタムルール名」、「優先度」、条件で、「IPアドレス」、「次の値を含まない」、IPアドレス(CIDRで範囲指定可能)を指定し、結果で、「トラフィックを拒否する」を指定します。「追加」をクリックして、「保存」をクリックすれば設定は完了です。

この場合、指定したIPアドレスに一致しないクライアントからのアクセスを全て拒否するアクションを実行します。なお、このカスタムルールは即時アクションとして評価され、「管理されているルール」(OWASP CRS)よりも先に評価されます。また、カスタムルールの優先度は1~100まで指定でき、小さい数字の優先度の方が先に評価されます。

まとめ

今回のWAFポリシーとAPGWのまとめブログは以上です。ここまで読んでいただき、ありがとうございました。

なお、ご自分でも検証環境でいろいろ試したいという行動派の方は、引き続き、「5. 検証環境の構築」もご参照ください。

5. 検証環境の構築

今回のブログで利用した、「WAFで保護された負荷分散Webサーバの検証環境」をAzureで構築する手順を説明します。

この手順で構築する検証環境を以下に示します。
(本来、DBと連携しているWebサーバでないとWAFを設置する意味はほとんど無いですが、今回、DBの部分は省略します)

リソースグループの作成

1. カテゴリの全般→「リソースグループ」を開き、「+作成」をクリックします。

2. サブスクリプション、リソースグループ、リージョンを指定して「確認および作成」、さらに「作成」をクリックします。※指定する値については、ご自分の環境に合わせたものに置き換えてください。

アプリケーションゲートウェイの作成

3. カテゴリのネットワーキング→「アプリケーションゲートウェイ」を開き、「+作成」をクリックします。

4. サブスクリプション、リソースグループ、ゲートウェイ名、地域、レベルを下図のように指定して、新規作成をクリックします。

5. 仮想ネットワークの名前を指定してから、サブネット名のチェックボックスをクリックし、「OK」をクリックして仮想ネットワークを作成します。さらに、「次:フロントエンドの数 >」をクリックします。

6. パブリックIPアドレスで新規追加をクリックし、名前を指定して「OK」をクリックします。さらに、「次:バックエンド >」をクリックします。

7. バックエンドプールの追加をクリックして名前を指定し、「ターゲットを持たないバックエンドプールを追加します」で、「はい」をクリックして「追加」をクリックします。さらに、「次:構成 >」をクリックします。※ターゲットは後ほど追加します。

8. ルーティング規則の追加をクリックします。

9. ルール名、リスナー名、フロントエンドIPプロトコルを下図のように指定してから、「バックエンドターゲット」をクリックします。

10. 「ターゲットの種類」のバックエンドプールとして先ほど作成したものを指定して、「HTTP設定」で新規追加をクリックします。

11. 「HTTP設定名」を指定して「追加」をクリックします。※その他の設定はデフォルト値を使用します。

12. 「HTTP設定」に値が入ったのを確認し、「追加」をクリックします。

13. 「ルーティング規則」に値が入ったのを確認して「次:タグ >」をクリックします。さらに「次:確認および作成」をクリックします。

14. 「検証に成功しました」と表示されたのを確認し、「作成」をクリックします。※この後デプロイが完了するまで約10分くらい待ちます・・・。

WAFポリシーの作成

15. カテゴリのネットワーキング→「Web Application Firewall ポリシー(WAF)」を開き、「+作成」をクリックします。

16. 「次に対するポリシー」で、「リージョンのWAF (Application Gateway)」を選択し、サブスクリプション、リソースグループ、ポリシー名、場所を指定します。さらに「次:管理されているルール >」をクリックします。

17. 「管理されているルールセット」として「OWASP_3.1」を選択し、「次:ポリシー設定 >」をクリックします。

18. 「ポリシー設定」はデフォルト値のまま「次:カスタムルール >」をクリックします。

19. 「カスタムルール」はここではルールなしのままで「次:関連付け >」をクリックします。

20. 「関連付けの追加」で「HTTPリスナー」を選択します。

21. すでに作成したアプリケーションゲートウェイとリスナーを指定して「追加」をクリックします。

22. HTTP Listenerの設定値を確認したら、「確認および作成」をクリックします。

23. 「検証に成功しました」と表示されたのを確認し、「作成」をクリックします。

VMの作成とバックエンドプールへの追加

24. カテゴリのコンピューティング→「Virtual Machines」を開き、「+作成」をクリックしてから「+仮想マシン」をクリックします。

25. サブスクリプション、リソースグループ、仮想マシン名、地域、イメージ、サイズを指定します。※今回は、イメージが「CentOS 7.9」で、サイズが「Standard_B1s」を選択します。さらに、「次:ディスク >」をクリックします。

26. 「新しいディスクを作成し接続する」をクリックします。

27. 「サイズを変更します」をクリックします。

28. 「ディスクSKU」と「サイズ」を選択して「OK」をクリックします。※ここでは、ディスクSKUが「Standard SSD」で、サイズが「32GiB」を選択しました。

29. OSディスクの種類を「Standard SSD」に変更し、データディスクとして先ほど設定したディスクが表示されているのを確認してから、「次:ネットワーク」をクリックします。

30. 「サブネット構成の管理」をクリックします。

31. 「+サブネット」をクリックします。

32. 「名前」と、「サブネット アドレス範囲」の値を設定して「保存」をクリックします。

33. サブネットの画面に戻ったら、画面右上の×または、下のスライドバーを左に移動して仮想マシンの作成画面に戻ります。

34. 「サブネット」に先ほど作成したものが指定されていることを確認し、「負荷分散のオプション」で「アプリケーションゲートウェイ」を選択し、「アプリケーションゲートウェイを選択します」と、「バックエンドプールの選択」ですでに作成済みのものを指定します。さらに、「確認および作成」をクリックします。

35. 「検証に成功しました」と表示されたことと、各設定値を確認したら「作成」をクリックします。

36. 新しいキーの組の生成の画面で、「秘密キーのダウンロードとリソースの作成」をクリックします。
ダウンロード後、「仮想マシンの作成に戻る」をクリックしてデプロイを続行します。

37. このVMの作成とバックエンドプールへの追加の作業を必要なだけ繰り返します。※今回は3台で負荷分散するので、あと2台のVMを作成します。

38. アプリケーションゲートウェイのIPアドレス(xxx.xxx.xxx.47)に対してブラウザでアクセスし、更新を行うと、バックエンドプール内のVMに対して順番にラウンドロビンでアクセスしていることが確認できます。

※ここでは省略しますが、VMにはApacheをインストールして、それぞれのVMの/var/www/htmlに“VM01”, “VM02”, “VM03”と追記したindex.htmlを配置してあります。

Log Analystics ワークスペースの設定

39. カテゴリの分析→「Log Analystics ワークスペース」を開き、「+作成」をクリックしてから「サブスクリプション」、「リソースグループ」、「名前」、「地域」を指定します。

40. 「確認および作成」をクリックし、「作成」をクリックします。

APGWの診断設定

41. カテゴリのネットワーキング→「アプリケーションゲートウェイ」を開き、作成済みのアプリケーションゲートウェイをクリックしてから「診断設定」をクリックします。

42. 「診断設定を追加する+」をクリックします。

43. 「診断設定の名前」を指定し、「log」でApplicationGatewayFirewallLogのチェックボックスをクリックし、「Log Analystics ワークスペースへの送信」のチェックボックスをクリックして、「サブスクリプション」と、先ほど作成した「Log Analystics ワークスペース」を指定し、「保存」をクリックします。

以上で構築作業は完了です。

あわせて読みたい記事

Azure上に作成した仮想マシンのディスク拡張方法

Azure API Managementを触ってみた!

Azure Synapse Analyticsはじめの一歩