Azure VNet フローログ

:::note info
2024/06/28 ER Gateway のフローログの有無の詳細を追記
:::

Virtual Netowrk フローログが 2024/04/25 に一般提供となりました。今までは NSG フローログが利用可能でしたが、この機能を利用することで NSG に限らないより広い範囲 (対応シナリオが多い) で通信ログを取得できるようになります。
Azure のネットワーク機能で取得可能な通信ログについては以前、[こちら](https://qiita.com/Isato-Hiyama/items/7014580cb565f7f636dc)にまとめていますが、この記事では Virtual Network フローログの詳細や実際に検証した内容をまとめております。
VNet flow log にてログ出力されたかといった確認のみとなり、各プロダクトの正式なサポート状況は確認できておりません。

https://azure.microsoft.com/en-us/updates/general-availability-virtual-network-flow-logs/

## [NSG フローログとの違い](#nsg-フローログとの違い)
[こちら](https://learn.microsoft.com/ja-jp/azure/network-watcher/vnet-flow-logs-overview#virtual-network-flow-logs-compared-to-network-security-group-flow-logs)に違いがまとまっていますが、主な違いは以下があると思います。

- Azure Virtual Network Manager セキュリティ規則に対応
- [仮想ネットワーク暗号化](https://learn.microsoft.com/ja-jp/azure/virtual-network/virtual-network-encryption-overview)にも対応
- NSG フローログは NIC/サブネットの両方に NSG があった場合、どちらか一方の NSG しか記録されない
- VNet フローログは取得範囲を VNet/Subnet/NIC から選択できる (※ NIC は VM のみのため、プライベートエンドポイント等は選べない)
- 仮想ネットワーク内でサポートされているワークロードをサポート (ER 経由の通信や Hub 部分の通信の可視化が可能)

:::note info
トラフィックの重複記録や追加コストを避けるために、基になるワークロードで仮想ネットワーク フロー ログを有効にする前に、ネットワーク セキュリティ グループ フロー ログを無効にすることをお勧めします。 
:::

## [利用シナリオ](#利用シナリオ)
[MS Tech Community ブログ](https://techcommunity.microsoft.com/t5/azure-networking-blog/network-traffic-observability-with-virtual-network-flow-logs/ba-p/4112907)に詳細がまとまっていますが、以下のようなシナリオで利用できます。

- Azure Virtual Network Manager セキュリティ規則のトラブルシューティング
- Hub & Spoke 構成における Hub 部分のネットワークトラフィックの可視化
- ER/VPN Gateway 経由のトラフィックの可視化 (5タプル、方向、通信量等を取得可能) ※ER の場合、Azure からオンプレへの Egress はログがでないようなので注意

## [ログ取得することでトラフィックの影響はないのか？](#ログ取得することでトラフィックの影響はないのか)

https://learn.microsoft.com/ja-jp/azure/network-watcher/vnet-flow-logs-overview#how-logging-works

:::note info
ログは、Azure プラットフォームを通して 1 分間隔で収集されます。 お使いの Azure リソースやネットワーク トラフィックに影響はありません。
:::

## [VNet フローログ設定手順](#vnet-フローログ設定手順)
事前に Log Aanalytics ワークスペース、ストレージアカウントを作成済みであれば、以下の手順で簡単に設定可能です。**NIC 単位で取る場合は VM しか選択できません。**

https://learn.microsoft.com/ja-jp/azure/network-watcher/vnet-flow-logs-portal

## [動作確認](#動作確認)

以下のような構成にて疑似オンプレ (OCI) - Azure 間の通信、Spoke VNet 間の通信のログを取得し、Traffic 分析を使って各リソースでログが記録されるかを確認してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/f91f97eb-cce0-9954-e887-3a161a133d60.png)

### [Private Endpoint](#private-endpoint)

Private Endpoint 宛の通信ですが、以下のように Hub VNet のフローログにて記録されており、データサイズ等も記録されておりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/3bea37b4-a1f6-e905-9f2d-cec9bd5fa95b.png)

:::note info
ただし、Spoke VNet の方のフローログとしては記録されておりませんでしたので、プライベートエンドポイント単体ではなく Express Route Gateway や Azure Firewall を経由したところでログが記録されるようです。
:::

#### [Private Endpoint 用サブネットの NSG で拒否された通信が記録されるか](#private-endpoint-用サブネットの-nsg-で拒否された通信が記録されるか)

NSG で拒否されている状態で OCI から BLOB Storage の Private Endpoint へ通信を試してみたところ、一応通信としては記録されておりましたが、**Flow State は Allowed となっておりました。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/ba81ab37-0225-fefa-42cd-03eef1f4c53b.png)

### [Application Gateway](#application-gateway)
以下のような構成で Public IP のリスナーとプライベート IP のリスナーそれぞれにアクセスしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/06f3d6d5-6316-40ae-2a44-a5d02b0af09c.png)

#### [Private IP リスナー](#private-ip-リスナー)
Privete IP リスナー宛の通信も記録されておりました。また、Application Gateway 用のサブネット内の IP アドレス宛の通信が Spoke-B の方のフローログで記録されておりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/57e63e18-160f-e430-17b2-dbbd0b7f5156.png)

#### [Public IP リスナー](#public-ip-リスナー)
Public IP 宛の通信も Spoke-B の方のフローログで記録されておりました。DestIP は Application Gateway 用のサブネットの IP になっていますが、Azure の NSG は PublicIP ではなく VM の Private IP アドレスで評価するためそれと同様の動作と考えられます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/5c030095-167e-d6ec-1373-03c90060f3dc.png)

NSG で拒否した通信も記録されていたため、NSG で評価された結果は VNet フローログの FlowStatus に反映されるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/3e3d2204-3ed1-a2bf-3b89-325ed9a81d45.png)

### [Bastion](#bastion)
Bastion から Windows VM に接続した際のログも記録されておりました。
Bastion インスタンスへの接続と、Bastion から Target VM へ双方のログが記録されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/f4bbf1ae-6fd0-1420-0643-359209bd7794.png)

### [DNS Private Resolver](#dns-private-resolver)
DNS Private Resolver 宛の通信も Hub VNet のフローログに記録されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/0fede9dd-06c6-bc9b-2603-a55c760afb17.png)

:::note info
ただし、Spoke VNet の方のフローログとしては記録されておりませんでしたので、DNS Private Resolver ではなく Express Route Gateway や Azure Firewall を経由したところでログが記録されるようです。
:::

**また、転送ルールを使った送信エンドポイントからの通信は検証しておりません。**

### [オンプレ向け通信](#オンプレ向け通信)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/1cdd5147-11b5-0dc9-bcd1-26784a749fef.png)

OCI の VM に Azure VM から SSH した際のログですが、送信元の VM の IP とあて先 IP アドレスが記録されております。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/0e34c258-d3ae-ab65-c54d-d58538ae36ba.png)

:::note info
ただし、OCI あての通信で ER Gateway の MacAddress と思われるログは記録されておりませんでした。 
:::

### [MAC アドレスの判別](#mac-アドレスの判別)
こちらのログは Application Gateway に OCI からアクセスしたときのフローログですが、MacAddress が複数あり、どこを通過したときのログかはわかりにくい状態です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/66f85030-e67d-7e52-49fe-8fec9d6a958c.png)

通信経路としては以下であるため、ER Gateway か Azure Firewall の MacAddress の可能性が高そうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/f8ebb191-a94d-2c54-e471-6d18b24700ac.png)

そこで Hub の VNet フローログに対して以下のようなクエリを使って GatewaySubnet 関連の通信で利用されている MacAddress を調べてみます。"10.10.4" は GatewaySubnet のものです。
```
NTANetAnalytics
| where SrcIp contains "10.10.4"
| project FlowStartTime, SrcIp, DestIp, DestPort, FlowDirection, FlowStatus, MacAddress, TargetResourceType, TargetResourceId
| summarize count() by MacAddress
```

ER Gateway のものと思われる MacAddress がでてきました。ログからの推測にはなりますが、何らかの内部的な通信のために ER Gateway の通信もログが出てると考えられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/27247cea-a59f-24a6-169f-ed899bc05b75.png)

:::note warn
リソースによっては VMSS のようにスケールアウト・イン等があり、タイミングにより MacAddress が異なる可能性があるため、該当時間帯の情報を都度確認することをお勧めします。
:::

この方法にて以下の感じで、 ExpressRoute, Azure Firewall を経由していると推測できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/551011fd-5180-47cd-06cb-2b89d26c1aaf.png)

プライベートエンドポイントの通信で、ルーティングの設定が誤っていたために Azure Firewall を経由できてなかった時間帯があったのですが、その際は ER Gateway 用の MacAddress しか出力がありませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/ad043129-7990-edf5-b287-9c1c0b05f944.png)

### [ExpressRoute 経由のトラフィック可視化](#expressroute-経由のトラフィック可視化)
Tech community のブログを参考に ER Gateway のトラフィックの割合を可視化してみました。
私の環境では SrcExpressRouteCircuit, DestExpressRouteCircuit が記録されていなかったため、以下の表示に絞っています。
- ER Gateway の MacAddress の MacAddress が含まれる
- SrcIp が GatewaySubnet、空ではないもの
- DestIp にあて先 VNet のアドレス空間 ("10.12.") を含むもの
- DestIp を基準にパイチャートを作成する

```
NTANetAnalytics
| where SubType == 'FlowLog'
    and FaSchemaVersion == '3'
    and FlowStartTime  > ago(2d)
| where SrcIp !contains "10.10.4" and isnotempty(SrcIp) and DestIp contains "10.12."
| where MacAddress == "00-22-48-E6-54-32" or MacAddress == "60-45-BD-66-1C-8F"
| summarize TotalBytesSrcToDest=sum(BytesSrcToDest), TotalBytesDestToSrc=sum(BytesDestToSrc) by tostring(DestIp)
| render piechart
```

こんな感じで Azure の Spoke VNet への通信でどこ宛の通信がどの程度多いのかがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/e00a8dfb-553f-4772-2f0a-ef8e1aae9a66.png)

### [Azure Firewall 経由のトラフィック可視化](#azure-firewall-経由のトラフィック可視化)
Azure Firewall のトラフィックも可視化してみます。以下の表示に絞っています。Azure Firewall ではアプリケーションルール、ネットワークルール両方使っています。

- Azure Firewall の MacAddress が含まれる
- SrcIp が AzureFirewallSubnet、空ではないもの
- DestIp にあて先 VNet のアドレス空間 ("10.12.") を含むもの
- SrcIp を基準にパイチャートを作成する

```
NTANetAnalytics
| where SubType == 'FlowLog'
    and FaSchemaVersion == '3'
    and FlowStartTime  > ago(3d)
| where SrcIp !contains "10.10.1" and isnotempty(SrcIp) and DestIp contains "10.12."
| where MacAddress == "00-22-48-EA-53-4B" or MacAddress == "00-22-48-EA-5E-D7"
| summarize TotalBytesSrcToDest=sum(BytesSrcToDest), TotalBytesDestToSrc=sum(BytesDestToSrc) by tostring(SrcIp)
| render piechart
```

こんな感じで特定の Spoke VNet への通信でどこからの通信がどの程度多いのかがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/67e2697a-848b-107d-0c7d-c79e34bda314.png)

### [サブネット委任、Global VNet Peering](#サブネット委任global-vnet-peering)
こんな構成で VNet 統合した AppService から BLOB のプライベートエンドポイントへの接続が記録されるかを確認してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/78be30ba-58eb-596a-0208-6a425887e43b.png)

以下のように Hub VNet のフローログに記録されておりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/05c2681b-481f-25ca-6948-e082f97932a8.png)

:::note info
ただし、Spoke VNet の方のフローログとしては記録されておりませんでした。そのため Azure Firewall 等を経由させる必要がありそうです。
:::

念のため、Global VNet Peering も使ってみましたが、ログは出力されました。

### [ログ量、課金について](#ログ量課金について)
ログ量は構成、要件により大幅に変動しますが、検証した構成で常時通信がない状態で 12MB/日 程度のログが記録されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/e8d677cc-5f8c-f494-01be-174653e36f29.png)

大規模環境やパブリックの Web サイトでログを取得する場合は、不測の事態でログおよび課金が増大する可能性もあります。また、NSG フローログと比較しても取得できるログが増えるため、ログ量が増える可能性が高いです。トラフィック分析を使う場合は通常の Usage をふまえたうえで Log Analytics に日次上限を設定しておくとよいと思います。

https://learn.microsoft.com/ja-jp/azure/azure-monitor/logs/daily-cap

https://azure.microsoft.com/ja-jp/pricing/details/network-watcher/

### [ExpressRoute Gateway 経由のトラフィックについて](#expressroute-gateway-経由のトラフィックについて)
以下のブログにもわかりやすく書かれていますが、Azure からオンプレ方向のパケットは ExpressRoute の Gateway 非経由となります。そのため、オンプレ方向の通信についてはフローログの記録がなかったと考えられます。

https://techcommunity.microsoft.com/t5/azure-networking-blog/expressroute-fastpath-for-udrs-and-vnet-peering/ba-p/4171115

# [まとめ](#まとめ)

まとめると以下のような検証結果となりました。

| サービス | 確認結果 | 備考 |
|:-----------|:------------|:------------|
| オンプレへの通信 | 〇 | Firewall 経由で取得 |
| Private Endpoint | 〇 | Gateway や Firewall 経由で取得 |
| Application Gateway | 〇 |  |
| Bastion | 〇 |  |
| DNS Private Resolver | 〇 | Gateway や Firewall 経由で取得 |
| サブネット委任 | 〇 | Firewall 経由で取得 |
| VNet ピアリング (Global 含む) | 〇 |  |

少量のトラフィックでもログの項目が多く、量も膨大であるため、詳細を細かく確認するのは非常に労力がいるなと感じましたが、トラブルシューティング時やトラフィックの内訳を大まかに確認したいときは有用なツールであると感じました。
すべてのシナリオを検証しているわけではないので、ご利用の環境で事前に検証いただくことをお勧めします。