[Azure] Application Gateway WAFを使ってみる

Application Gateway Standard/Smallは確かに安いのだが・・

Azureの中でも、Application GatewayのStandard/Small SKUはとってもお安い。月額3,000円弱ぐらいで使えてしまう。が、これだと使えない機能がある。それが「WAF(Web Application Gateway)」と言うやつ。

WAF機能を使うには、まずSKUをMedium以上にしなければならない。その上でStandard->WAFにするわけなんだけど、こうなった瞬間に月額は一気に15,000円程度に跳ね上がる。個人で本格稼動するにはちょいと無理がある。

Application Gatewayで使用されるルールエンジンはOWASP 2.9.2/3.0のいずれかが選択できるのだけど、2.9.2だと「単なるmod_securityとかわらんじゃないかー」ってなりかねないのだけど、果たして3.0だとどうなんだろう?と思って触ってみることにした。

WAFの設定方法

WAF機能はあくまでApplication Gatewayの一機能なので、大前提としてApplication Gatewayを作らなければならない。その上で、WAF機能を有効にし、ルールセットを設定する必要がある。

なお、当記事ではApplication Gatewayとしての基本機能である、リスナー・バックエンドプール・HTTP設定などについては割愛する。

WAFの設定概要

WAF機能はいきなり「防止(ブロック)」ではなく、大抵誤検知を避けるために「検出」に設定を行う。また、ルールセットの定義は「ルール」で行う。

ルールタブでOWASPのどっちのバージョンを採用するか決めるのだけど、さらに詳細を定義することも可能だったりする。

WAFのルールセット(OWASP3.0)

ここで、何のルールをONにし、何のルールをOFFにするのかが設定可能となる。基本的には上記記載されているルールは大抵が有効になっている。

また、さらに必要となるのが診断ログ設定で、診断ログ設定をやっておかないと、「検出」モードでは通知すべきログがどこにも保存・転送できずに、そもそも検出モードにする意味がない、転じてWAFを有効にする意味がない。

今回は、ログのアーカイブとLog Analyticsへの転送を有効にしている。

なお、ログ保存設定は別にすべてのあて先を設定する必要はなく、ひとつはログアーカイブ用、ひとつはLogAnalytics転送用としても良い。確かによくよく考えたらそれができて当たり前かと言う気もするけど。

さて、これで様子を見てみるんだけど・・AccessLogとPerformanceLogは転送されてるっぽいのだけど、Firewallのログがまったく生成されてないことに気づく。なぜだろうと考えてみた。

Azure CDN越しだとそもそもひっかからない

今回、実験体に使ったのはまさにこのブログなんだけど、元々Azure CDNを通すように構成してた。ところが、AzureCDNのルールエンジンで管理用サイトにアクセスできないようにしたり、いろいろ規制をかけていたことにふと気づいた。

そのため、OWASPに引っかかるようなアクセスがそもそも来ないッス・・・というわけで、それじゃぁ意味ねぇじゃないのと言う話で、この経路を変更することに。

そこで、外部からのアクセスを直受けするために一時的に CDNをはずし、アクセス直受けが可能な構成に持っていくことにした。

DNS権威サーバのレコード設定で、wwwサーバのCNAMEを一時的にこのApplication Gatwayへ変更して、名前解決が変更されたところで、とりあえずCDNの加護がなくなったことを確認すべく、Mastodonで我がブログのトップページのURLをペタリ。

CDNの加護がなくなり、いっきに要求数が跳ね上がった。

はい、これでいろいろ試せる。と思ったんだけど、やっぱりちょっとアタックが怖いので、結局は内部アクセス限定でApplication Gatewayへアクセス経路を直結させることに(普段は内部に構築してるNginxを経由させるようにしている)

LogAnalyticsでログを引っ掛けてみる

Log Analyticsにてログを引っ掛けてみた。なお、LogAnalyticsで生ログを引っ掛けるにはクエリーを作成する必要があり、これを書くのが何気にめんどくさい。

おそらくは、慣れが必要なんだろうなーとは思っているんだけどこれがまた・・・記述例として以下のとおり挙げておく。

なお、ログに記録されるJSONデータの項目情報はMicrosoft社の以下の情報が参考になる。

https://docs.microsoft.com/ja-jp/azure/application-gateway/application-gateway-diagnostics

■トップページに対するブロック検知
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| where requestUri_s == "/" and action_s == "Blocked"
| summarize count() by ruleId_s
■参照URLの集計
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayAccessLog"
| where userAgent_s != "Azure+Traffic+Manager+Endpoint+Monitor"
| summarize count() by requestUri_s
■検知メッセージ(パターン)の取得
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| where action_s == "Detected"
| summarize count() by details_message_s

上記のうち、使用したのは3番目。action_sにおいて、検知モードを設定した場合は「Blocked」と記録されず、「Detected」として記録される。そのため、メッセージをそのとおり指定してあげる必要がある。

実際誤検知ルールを除外するときは最後のサマライズ文については「ruleId_s」を使用したほうがいいのだけど、今回は見易さ重視で「details_message_s」で並べることにした。その結果がこちら

実は、Mastodonからアクセスしてもらっただけでは、最上位にある「Warning: Match of “pm AppleWebKit Android” against “REQUEST_HEADERS: User-Agent” required 」しか検出されなかった。

その他のメッセージはどのような操作で検出されているかと言うと、ずばり「今ここで記事を書いてる瞬間」だったりする。

なお、パターン一覧が書かれてる画面の上にある「CHART」と言うところをクリックすると、グラフで表現させることが可能になっている。

ストレージに保存されるログ

ストレージに対しては、以下のBLOBコンテナが作成され、その中に各種ログが格納される。

  • insights-logs-applicationgatewayfirewalllog:WAFログ
  • insights-logs-applicationgatewayaccesslog:アクセスログ
  • insights-logs-applicationgatewayperformancelog:パフォーマンスログ

同じストレージに格納する限り、対象となるApplication Gatewayのログは上記3つのコンテナへまとめて送り込まれる(下位層フォルダでリソースごとに分岐する)。時間単位でフォルダは分割されており、ぶっちゃけ普段のサーバログを見る感覚で運用しようとするとかなり厳しいことになるので、あくまでログをざっと眺める目的であるならば、LogAnalyticsに送り込んだほうが絶対よいと思う。

参考までに、階層はこんな感じ

insights-logs-applicationgatewayfirewalllog / resourceId= / SUBSCRIPTIONS / (サブスクリプションID) / RESOURCEGROUPS / (リソースグループ名) / PROVIDERS / MICROSOFT.NETWORK / APPLICATIONGATEWAYS / (リソース名) / y=YYYY / m=MM / d=DD / h=HH / m=00

カスタムログ監視はあくまでメトリック監視

LogAnalytics側でアラート設定を行うと、ログパターンに基づいて検知した場合に通知をさせることが可能になる。ただ、少々条件があり、「必ず設定したクエリの最後に「|count()」」がついてくる。

要は、指定時間内に該当するパターンのログが何回でたら通知するか?と言う設定になる。つまりはログ監視も一種のメトリック監視として扱われると言うことになる。逆に言えば、持続的に大量に出るような場合にエラー発報とすることも可能だし、1回でも出たらエラー発報とすると言うようなことも可能なようだ。

おわりに

まーなんだかんだいっても、OWASP3.0に関してもやっぱり正当な操作を行っても結構な誤検知が出ますね。というわけで結構しっかりとルールは精査する必要がありそうです。今回Wordpressのオートセーブ機能が実行されたときに検知が多く行われたようです。コード読める人とかは、この際処理の流れを見てみるとよいのかもしれません。

これからこの記事をアップして寝て、目が覚めたら選挙投票&MS試験が待っております・・・。土曜日は通院やら候補人の情報確認やらいろいろあった上、体力が足りなさ過ぎて夕方ごろにギブアップしたこともあり、今回は試験対策マジで何もできておらず・・・落ちるのいやだなーと思いつつ、でも勉強できてないしなーと思いつつ。何はともあれ華々しく玉砕してきます。