システムエンジニアXの「プログラミング以外」の話 50代会社員SEのお仕事・副業・システム運用の経験談

【Azure VM】アクセス数をLog Analytics(KQL)で可視化する実践手法

公開:

※本記事には広告を含みます。

はじめに

Azure上で稼働している社内Webサーバーや業務アプリケーション用の仮想マシン(Azure VM)について、上司やセキュリティ担当から「このVMに日々どれくらいアクセスがあるのか、どこから接続されているのか数字を出してほしい」と求められて困ったことはないでしょうか。

私も過去に、老朽化したAzure VMの統廃合プロジェクトで「本当に誰も使っていないサーバーか」を証明する必要に迫られ、最初はAzure標準メトリックの「Network In(受信バイト数)」だけを見て判断しようとして、バックアップ通信や監視死活監視のトラフィックと区別がつかずに苦労した経験があります。

Azure VMへの「アクセス数」を正確に把握するには、単なる通信量(バイト数)ではなく、目的に応じたログテーブルを Log Analytics ワークスペース に集約し、KQL(Kusto Query Language) で集計するのが最も確実です。

この記事では、知りたい「アクセス数」の定義に応じた3つのログ収集アプローチの選び方と、コピペですぐに使える実践KQLクエリ、そしてログ肥大化による課金爆発を防ぐ設計ポイントを解説します。

読み終えるころには、Webリクエスト数からTCPポート単位の接続元IPランキングまで、自在に抽出・グラフ化できるようになります。

この記事の要点

  • Azure標準メトリック(Network In/Out)では「通信量」しか分からず、「アクセス回数」や「接続元IP」を知るにはLog Analyticsでのログ集計が必要
  • 把握したい粒度に応じて ①IISログ(W3CIISLog)、②VM Insights(VMConnection)、③ネットワークフローログ(AzureNetworkAnalytics_CL) の3つを使い分ける
  • KQLの summarize count() by bin(TimeGenerated, 1h) と render timechart を使えば、時間帯別のアクセス推移を数秒でグラフ化できる
項目 動作確認・検証環境
検証年月 2026年9月
対象環境 Microsoft Azure (Azure Virtual Machines / Azure Monitor)
対象エージェント Azure Monitor Agent (AMA) + データ収集ルール (DCR)
クエリ言語 KQL (Kusto Query Language)

結論:知りたい「アクセス数」の目的別・3つの収集アプローチ比較

結論からお伝えすると、一口に「VMへのアクセス数」といっても、「Webページが何回開かれたか(L7)」「OSの特定ポートに何セッション繋がっているか(L4)」「NSGを通過した通信がどれだけあるか(NW)」 によって見るべきテーブルが異なります。

まずは、3つの可視化アプローチの特徴とコスト感を以下の表で比較します。

比較項目 ① Webアクセス数(IISログ) ② OSプロセス・TCP接続数(VM Insights) ③ NWレベルの通信数(NSG / VNetフローログ)
Log Analyticsテーブル W3CIISLog VMConnection AzureNetworkAnalytics_CL (NTAIpDetails 等)
わかること URL別アクセス数、HTTPステータス、クライアントIP、UserAgent 送受信ポート番号、通信先/元IP、プロセス名、同時リンク数 許可・拒否(Allow/Deny)された全フロー数、送信元IP、国別通信
必要な事前設定 AMA導入 + データ収集ルール(DCR)で「IISログ」を有効化 AMA導入 + VM Insightsで「プロセスと依存関係(Map)」を有効化 Network Watcherでフローログ+Traffic Analyticsを有効化
VM内への導入要否 必要(エージェント経由) 必要(エージェント経由) 不要(Azure基盤側で取得可能)
ログ容量(コスト) 小〜中(アクセス頻度に比例) 中〜大(全TCP通信を記録するため多め) 中(ストレージ保存+集約ログ課金)
向いている用途 社内ポータルやWebアプリのPV・利用者数集計 RDP/SMB/DB等のポート別接続元・依存関係調査 不審な外部アクセス検知・FWルール棚卸し

「Webシステムの利用状況を調べたい」なら ① W3CIISLog、「ファイルサーバーやDBサーバーにどの端末が繋ぎに来ているか調べたい」なら ② VMConnection または ③ フローログ を選ぶのが正解です。


【実践KQL】Log Analyticsでアクセス数を集計・可視化するクエリ集

Log Analyticsワークスペースの「ログ」画面でそのまま実行できる、現場でよく使うKQLクエリを3つのパターン別に紹介します。

1. Webサーバー(IIS)の時間帯別アクセス数と接続元IPを集計する(W3CIISLog)

データ収集ルール(DCR)で「IIS ログ」の収集を有効にすると、W3CIISLog テーブルにレコードが蓄積されます。

▼ 時間帯(1時間ごと)のWebアクセス数推移を折れ線グラフにするクエリ

W3CIISLog
| where TimeGenerated > ago(7d)
| where Computer == "WEB-SRV01" // 対象のVM名を指定
| where csUriStem !endswith ".css" and csUriStem !endswith ".js" and csUriStem !endswith ".png" and csUriStem !endswith ".ico" // 静的ファイルを除外
| summarize RequestCount = count() by bin(TimeGenerated, 1h)
| render timechart
  • where csUriStem !endswith ...: 画像やCSSなどのサブリソース読み込みを除外することで、「人間がページを開いた純粋なリクエスト数」に近い数値を算出できます。
  • bin(TimeGenerated, 1h): 1時間単位(日別なら 1d)でバケット化して件数を集計し、render timechart でそのままポータル上に時系列グラフを描画します。

▼ アクセス数が多い接続元IPアドレスTop 20を出すクエリ

W3CIISLog
| where TimeGenerated > ago(7d)
| summarize AccessCount = count(), LastAccess = max(TimeGenerated) by cIP, Computer
| top 20 by AccessCount desc

2. VMの特定ポート(RDP/HTTPS/SMB等)への接続元を集計する(VMConnection)

Webサーバー以外のVM(APサーバー、DBサーバー、管理用踏み台など)への接続状況を調べるには、VM Insightsのマップ機能が出力する VMConnection テーブルを使用します。

▼ 宛先ポート別・接続元IP別のインバウンド接続回数と通信量を集計するクエリ

VMConnection
| where TimeGenerated > ago(24h)
| where Direction == "inbound"
| where Computer == "APP-SRV01"
| summarize 
    ConnectionCount = sum(LinksEstablished),
    TotalMBReceived = round(sum(BytesReceived) / 1024.0 / 1024.0, 2),
    LastSeen = max(TimeGenerated)
    by DestinationPort, SourceIp, ProcessName
| order by ConnectionCount desc
  • Direction == "inbound": 外部や他サーバーからこのVMへ向かって入ってきた通信のみに絞り込みます。
  • DestinationPort / ProcessName: 「ポート 3389(RDP)や 445(SMB)、1433(SQL Server)に対して、どの SourceIp から何回リンクが張られたか」がプロセス名付きで一目で分かります。サーバー移行前の「まだこの古いサーバーを掴んでいるクライアントは誰か?」という棚卸し調査に絶大な威力を発揮します。

3. Windowsセキュリティログからログオン(RDP等)の回数を集計する(SecurityEvent)

「ネットワーク通信ではなく、実際にそのVMへ何回リモートデスクトップ(RDP)やネットワーク経由でサインインされたか」を知りたい場合は、SecurityEvent テーブルの イベントID 4624(ログオン成功) を集計します。

SecurityEvent
| where TimeGenerated > ago(30d)
| where EventID == 4624
| where AccountType == "User" // マシンアカウントを除外
| where LogonType in (3, 10)  // 3:ネットワーク(共有フォルダ等), 10:リモート対話型(RDP)
| summarize LogonCount = count(), LastLogon = max(TimeGenerated) by Account, IpAddress, LogonTypeName, Computer
| order by LogonCount desc

これにより、「過去30日間で誰がどのIPから何回RDP接続したか」を正確にリストアップできます。


現場でハマる「Azure VMアクセスログ収集」3つの落とし穴

Log Analyticsを使ったアクセス可視化を本番導入する際、必ず押さえておくべき3つの落とし穴と対策を解説します。

落とし穴1:リバースプロキシ(Application Gateway等)配下で接続元IPがすべて同じになる

Azure VMの前に Application Gateway や Azure Front Door、ロードバランサー(プロキシ型)を配置している場合、W3CIISLog の cIP(クライアントIP)列を見ると、すべてのアクセス元がApplication GatewayのプライベートIP(例:10.0.1.4)になってしまう という現象が起きます。

本来のクライアントIPはHTTPヘッダーの X-Forwarded-For に入っていますが、IISの初期設定ではこのヘッダーをログに出力しないため、Log Analytics側でも集計できません。

【回避策】:
ロードバランサー配下のIISで正確な接続元IPを集計したい場合は、IISマネージャーの「ログ記録」設定でカスタムフィールドとして X-Forwarded-For を追加するか、Application Gateway側の診断ログ(AzureDiagnostics または AGWAccessLogs テーブルの clientIp_s 列)でアクセス数を集計するように設計してください。

落とし穴2:VMConnection(マップ機能)の全台有効化によるLog Analytics課金爆発

VM Insightsを有効化する際、「パフォーマンス」だけでなく「プロセスと依存関係(VMConnection 等)」の収集チェックボックスを全VMに対して無制限にオンにすると、1分ごとに全プロセスの全TCP/UDP通信レコードが大量に送信され、Log Analyticsのデータ取り込み量(GB単価)が跳ね上がる ケースがあります。

特に通信セッション数が多いプロキシサーバーやDBサーバーでは、1台あたり月間数十GBのログを生成することもあります。

【回避策】:
VMConnection(依存関係エージェント/AMAマップ機能)は、常時全サーバーで有効にするのではなく、「移行前の依存関係調査期間(2週間だけ)」や「特に通信監査が必要な重要サーバー」に対象を絞ったデータ収集ルール(DCR)を作成して割り当てるのがコスト最適化の鉄則です。

落とし穴3:従来の「NSGフローログ」廃止スケジュールと「VNetフローログ」への移行

ネットワークレベルでアクセス数を可視化する際、これまで定番だった「NSGフローログ(Network Security Group Flow Logs)」は、Microsoftより 2025年6月以降の段階的廃止(2027年9月完全リタイア) が発表されており、後継の 「仮想ネットワーク フロー ログ(VNet Flow Logs)」 への移行が進んでいます。

これから新規にTraffic Analytics(フローログ可視化)を構成する場合は、古いNSGフローログではなく、必ず後継の「VNetフローログ」を選択してLog Analyticsワークスペースへ連携させてください。


よくある質問(FAQ)

Q: エージェント(AMA)をインストールせずに、今すぐ過去1週間のVMへのWebアクセス数を見る方法はありますか?

A: 残念ながら、事前にLog Analyticsへのログ転送設定やTraffic Analyticsの有効化を行っていなかった場合、Azureポータル上から後から過去に遡って「リクエスト回数」や「接続元IP」を見ることはできません。ただし、VM内部のローカルディスク(IISなら C:\inetpub\logs\LogFiles\W3SVC1\、Linuxなら /var/log/nginx/ 等)には標準で生ログファイルが残っているため、VMにログインしてPowerShell等で直接ローカルログを集計することは可能です。

Q: Azure VMの「概要」画面にある「ネットワーク(Network In / Out)」のグラフではアクセス数は分からないのですか?

A: はい、標準メトリックの Network In Total / Network Out Total は、ネットワークインターフェースを通過した「データ量(バイト数)」の合計値です。例えば「1人が1GBの巨大ファイルを1回ダウンロードしたケース」と「1万人が100KBのWebページを閲覧したケース」が同じ「1GB」として表示されるため、アクセス回数や利用者数の把握には使えません。

Q: KQLで集計した時刻(TimeGenerated)が9時間ズレているのですが、日本時間(JST)で集計するにはどうすればいいですか?

A: Log Analyticsの TimeGenerated はすべてUTC(世界協定時)で格納されています。クエリ結果画面の上部にある「表示タイムゾーン」を UTC+09:00 に切り替えるか、日次集計(bin())の区切りを日本時間の0時基準にしたい場合は、クエリの先頭に | extend TimeJST = datetime_add('hour', 9, TimeGenerated) を追加し、summarize count() by bin(TimeJST, 1d) と記述してください。


まとめ

Azure VMへのアクセス数をLog Analytics(KQL)で把握するための重要ポイントは以下の通りです。

  • 標準メトリックは通信量(バイト数)のみのため、アクセス回数や接続元IPの把握には Log Analyticsへのログ集約 を行う
  • WebサイトのPV・リクエスト数なら W3CIISLog、サーバー間のポート別接続・棚卸しなら VMConnection、NW全体の通信監査なら VNetフローログ(Traffic Analytics) を使い分ける
  • VMConnection はログ量が多いため、調査対象のVMに絞ってDCR(データ収集ルール)を適用し、コストを最適化する
  • ロードバランサー配下のVMでは、接続元IPがプロキシのIPに書き換わる点に注意し、必要に応じて前段のApplication Gateway側のログを集計する

目的に合ったテーブルとKQLクエリを用意しておけば、定例レポートの作成やインフラ棚卸し、不審通信の調査を圧倒的に効率化できます。

関連記事

免責規定

この記事で提供される情報は、一般的なガイダンスを目的としており、すべての環境やシステムでの動作を保証するものではありません。

OSのバージョンやリリースによっては、記載されている事が実行できない、または異なる結果をもたらす可能性があります。 また、会社所有のパソコン、スマホ、タブレットなどでは、ポリシーや権限によって実行できない場合があります。

この記事の情報を使用することによって生じる問題や結果について、筆者およびサイト管理者は責任を負いません。 すべての操作は自己責任で行ってください。

最後までお読みいただきありがとうございました。
またお会いしましょう!