normalian blog

Let's talk about Microsoft Azure, ASP.NET and Java!

Azure Network Watcher の Troubleshoot connections を使って Azure Application Gateway -> Azure Firewall -> Azure VM の接続性を確認する

今回は掲題の Troubleshoot connections を触ってみたいと思います。概要は以下のサイトに詳細はありますが、VM 間等の通信を試してどこに問題があるか等を確認することができます。太古の昔は ping や traceroute に始まり、色んな方法でトラブルシュートしたものですが、まずはの疎通でこちらを試すのは悪くないと思っています。
learn.microsoft.com
アレコレ触った結果で、ちょっと癖もあるなと思ったので今回は Troubleshoot connections の動作を見てみたいと思います。

疎通を取る環境のアーキテクチャ

以下に今回のアーキテクチャ図を記載しています。同一リージョンに二つの VNET を作成していますが、VNET Peering や VPN 等で接続しているわけではないので、互いに独立した VNET になっています。

Public IP アドレスを Azure Application Gateway に付与し、Azure Application Gateway -> Azure Firewall -> Azure VM のリクエストフローを想定しています。Troubleshoot connections は接続元の VM/VMSS/Azure Bastion/Azure Application Gateway のどれかを指定する必要があるので、今回はそもそもの接続元として Client 相当の VM を別 VNET に作成したという想定です。

クライアント VMアーキテクチャ図 ClientCent01)から宛先 VMアーキテクチャ図 CentVM01 or 02)を直接指定する場合

掲題通り、Troubleshoot connections に始端・終端の VM を直接指定するとどの様な結果になるかを確認したいと思います。図に答えが書いてありますが、これは上手くいきません。

実際にどのようなエラーが出るか確認しましょう。具体的にはポータルで Network Watcher を開いて以下の様に指定してください。

結果としては以下の様になり、接続に失敗しています。

更に詳しく見ると始端である ClientCent01 側の Outbound 規則に弾かれていることが分かります。実は NSG にはデフォルトで「VNET内 or インターネット側の outbound は許可する」という設定があるのですが、今回は接続されていない VNET となるのでどちらのルールにも適用されずにパケットが破棄されていることが分かります。

これをコマンドで実行すると以下の様になります。終端側の VM に対して、Public IP ベースで直接アクセスしようとして失敗していることが分かると思います。

$ az network watcher test-connectivity --resource-group YOUR-RESOURCE-GROUP-NAME --source-resource ClientCent01 --dest-resource CentVM01 --dest-port 80
az : WARNING: This command is in preview and under development. Reference and support levels: https://aka.ms/CLI_refstatus
At line:1 char:1
+ az network watcher test-connectivity --resource-group RG-Network-Test ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (WARNING: This c...s/CLI_refstatus:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
{
  "connectionStatus": "Unreachable",
  "hops": [
    {
      "address": "10.1.0.4",
      "id": "b4db2e0c-f996-473f-a703-3c014d0987bb",
      "issues": [],
      "links": [
        {
          "context": {},
          "issues": [],
          "linkType": "Internet",
          "nextHopId": "67baece5-b655-46ba-b149-2655eb251aaa",
          "resourceId": ""
        }
      ],
      "nextHopIds": [
        "67baece5-b655-46ba-b149-2655eb251aaa"
      ],
      "previousHopIds": [],
      "previousLinks": [],
      "resourceId": "/subscriptions/YOUR-SUBSCRIPTION-ID/resourceGroups/YOUR-RESOURCE-GROUP-NAME/providers/Microsoft.Compute/virtualMachines/ClientCent01",
      "type": "Source"
    },
    {
      "address": "20.163.24.1",
      "id": "67baece5-b655-46ba-b149-2655eb251aaa",
      "issues": [
        {
          "context": [],
          "origin": "Outbound",
          "severity": "Error",
          "type": "VMNotAllocated"
        }
      ],
      "links": [],
      "nextHopIds": [],
      "previousHopIds": [
        "b4db2e0c-f996-473f-a703-3c014d0987bb"
      ],
      "previousLinks": [
        {
          "context": {},
          "issues": [],
          "linkType": "Internet",
          "nextHopId": "b4db2e0c-f996-473f-a703-3c014d0987bb",
          "resourceId": ""
        }
      ],
      "resourceId": "/subscriptions/YOUR-SUBSCRIPTION-ID/resourceGroups/YOUR-RESOURCE-GROUP-NAME/providers/Microsoft.Compute/virtualMachines/CentVM01",
      "type": "VirtualMachine"
    }
  ],
  "probesFailed": 30,
  "probesSent": 30
}

クライアント VMアーキテクチャ図 ClientCent01)から宛先 Azure Application Gateway にアクセスする(※リソース名指定

直接終端 VM を指定するのは無理だと分かったので、次は始端 VM から Azure Application Gateway を指定してみましょう。以下のコマンドを実施します(ポータルで行っても構いません)。

$ az network watcher test-connectivity --resource-group YOUR-RESOURCE-GROUP-NAME --source-resource ClientCent01 --dest-address AppGw-Network-Test01-TestUS3 --dest-port 80
az : WARNING: This command is in preview and under development. Reference and support levels: https://aka.ms/CLI_refstatus
At line:1 char:1
+ az network watcher test-connectivity --resource-group RG-Network-Test ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (WARNING: This c...s/CLI_refstatus:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
{
  "connectionStatus": "Unreachable",
  "hops": [
    {
      "address": "20.169.48.200",
      "id": "a94a2aa0-07a7-4c32-abdc-3cd139d064a6",
      "issues": [
        {
          "context": [],
          "origin": "Local",
          "severity": "Error",
          "type": "DNSResolution"
        }
      ],
      "links": [
        {
          "context": {},
          "issues": [],
          "nextHopId": "d996b6e0-dee4-49a8-ba70-f0b7a1c55e03",
          "resourceId": ""
        }
      ],
      "nextHopIds": [
        "d996b6e0-dee4-49a8-ba70-f0b7a1c55e03"
      ],
      "previousHopIds": [],
      "previousLinks": [],
      "resourceId": "/subscriptions/YOUR-SUBSCRIPTION-ID/resourceGroups/YOUR-RESOURCE-GROUP-NAME/providers/Microsoft.Compute/virtualMachines/ClientCent01",
      "type": "Source"
    },
    {
      "address": "AppGw-Network-Test01-TestUS3",
      "id": "d996b6e0-dee4-49a8-ba70-f0b7a1c55e03",
      "issues": [],
      "links": [],
      "nextHopIds": [],
      "previousHopIds": [
        "a94a2aa0-07a7-4c32-abdc-3cd139d064a6"
      ],
      "previousLinks": [
        {
          "context": {},
          "issues": [],
          "nextHopId": "a94a2aa0-07a7-4c32-abdc-3cd139d064a6",
          "resourceId": ""
        }
      ],
      "type": "Destination"
    }
  ],
  "probesFailed": 0,
  "probesSent": 0
}

上記は失敗していますが 20.169.48.200 は ClientCent01 の Public IP であり、始端 VM から Azure Application Gateway でアクセスしようとした結果で、名前解決で失敗(DNSResolution)していることが分かります。リソースタイプ側でコマンド実行すればよいのか、念のためコマンド自体を確認してみると、以下の様に現時点でコマンドラインでは VM しかサポートされていないことが分かりました。

$ az network watcher test-connectivity -h

...

Arguments
    --source-resource [Required] : Name or ID of the resource from which to originate traffic.
                                   Currently only Virtual Machines are supported.
    --no-wait                    : Do not wait for the long-running operation to finish.  Allowed
                                   values: 0, 1, f, false, n, no, t, true, y, yes.
    --protocol                   : Protocol to test on.  Allowed values: Http, Https, Icmp, Tcp.
    --resource-group -g          : Name of the resource group the target resource is in.
    --source-port                : Port number from which to originate traffic.

Destination Arguments
    --dest-address               : IP address or URI at which to receive traffic.
    --dest-port                  : Port number on which to receive traffic.
    --dest-resource              : Name or ID of the resource to receive traffic. Currently only
                                   Virtual Machines are supported.

クライアント VMアーキテクチャ図 ClientCent01)から宛先 Azure Application Gateway にアクセスする(※ IP アドレス指定

Azure Application Gateway 側できちんと名前解決できるように設定してあげれば問題ないと思いますが、検証環境ではそんな設定をしたくないということが多いでしょう。その場合は直接 Azure Application Gateway のグローバル IP を指定すればアクセス可能です。本節では以下の部分の疎通を取ります。

ポータルで以下の様に Destination type を Specify manually を選択し、Azure Application Gateway のグローバル IP を入力してください。

正常に設定されていれば以下の様にアクセスが可能なはずです。

詳細を確認すると 10.0.0.4 や 10.0.0.6 といった IP がありますが、こちらは終端側の VM のプライベート IP でなく、Azure Application Gateway 側のサブネットの範囲なので、Azure Application Gatewayインスタンス(という表現が適切か分かりませんが)までしか届かないことが分かります。

これをコマンドで実行すると以下の様になります。

$ az network watcher test-connectivity --resource-group YOUR-RESOURCE-GROUP-NAME --source-resource ClientCent01 --dest-address 20.150.136.xxx --dest-port 80
az : WARNING: This command is in preview and under development. Reference and support levels: https://aka.ms/CLI_refstatus
At line:1 char:1
+ az network watcher test-connectivity --resource-group RG-Network-Test ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (WARNING: This c...s/CLI_refstatus:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
{
  "avgLatencyInMs": 1,
  "connectionStatus": "Reachable",
  "hops": [
    {
      "address": "10.1.0.4",
      "id": "ea04f6fb-fb7e-4aad-9cc8-6c19106dd861",
      "issues": [],
      "links": [
        {
          "context": {},
          "issues": [],
          "linkType": "Internet",
          "nextHopId": "72256fb6-35ce-4442-80ba-0453f63f3b0f",
          "resourceId": ""
        }
      ],
      "nextHopIds": [
        "72256fb6-35ce-4442-80ba-0453f63f3b0f"
      ],
      "previousHopIds": [],
      "previousLinks": [],
      "resourceId": "/subscriptions/YOUR-SUBSCRIPTION-ID/resourceGroups/YOUR-RESOURCE-GROUP-NAME/providers/Microsoft.Compute/virtualMachines/ClientCent01",
      "type": "Source"
    },
    {
      "address": "20.150.136.xxx",
      "id": "72256fb6-35ce-4442-80ba-0453f63f3b0f",
      "issues": [],
      "links": [
        {
          "context": {},
          "issues": [],
          "linkType": "VirtualNetwork",
          "nextHopId": "f3308930-64a5-4657-a70c-ba5d7aa719c0",
          "resourceId": ""
        },
        {
          "context": {},
          "issues": [],
          "linkType": "VirtualNetwork",
          "nextHopId": "8f8d04fa-5c91-4b0d-9e5c-b1d96fb912a8",
          "resourceId": ""
        }
      ],
      "nextHopIds": [
        "f3308930-64a5-4657-a70c-ba5d7aa719c0",
        "8f8d04fa-5c91-4b0d-9e5c-b1d96fb912a8"
      ],
      "previousHopIds": [
        "ea04f6fb-fb7e-4aad-9cc8-6c19106dd861"
      ],
      "previousLinks": [
        {
          "context": {},
          "issues": [],
          "linkType": "Internet",
          "nextHopId": "ea04f6fb-fb7e-4aad-9cc8-6c19106dd861",
          "resourceId": ""
        }
      ],
      "type": "PublicLoadBalancer"
    },
    {
      "address": "10.0.0.4",
      "id": "f3308930-64a5-4657-a70c-ba5d7aa719c0",
      "issues": [],
      "links": [],
      "nextHopIds": [],
      "previousHopIds": [
        "72256fb6-35ce-4442-80ba-0453f63f3b0f"
      ],
      "previousLinks": [
        {
          "context": {},
          "issues": [],
          "linkType": "VirtualNetwork",
          "nextHopId": "72256fb6-35ce-4442-80ba-0453f63f3b0f",
          "resourceId": ""
        }
      ],
      "type": "VirtualNetwork"
    },
    {
      "address": "10.0.0.6",
      "id": "8f8d04fa-5c91-4b0d-9e5c-b1d96fb912a8",
      "issues": [],
      "links": [],
      "nextHopIds": [],
      "previousHopIds": [
        "72256fb6-35ce-4442-80ba-0453f63f3b0f"
      ],
      "previousLinks": [
        {
          "context": {},
          "issues": [],
          "linkType": "VirtualNetwork",
          "nextHopId": "72256fb6-35ce-4442-80ba-0453f63f3b0f",
          "resourceId": ""
        }
      ],
      "type": "VirtualNetwork"
    }
  ],
  "maxLatencyInMs": 4,
  "minLatencyInMs": 1,
  "probesFailed": 0,
  "probesSent": 66
}

Azure Application Gateway から終端 VMアーキテクチャ図 CentVM01)にアクセスする(※リソース名指定

先ほどまでの検証だと始端 VM -> Azure Application Gateway までの疎通しか取れていないので、Azure Application Gateway -> Azure Firewall -> Azure VM 部分の疎通を通したいと思います。アーキテクチャ図でいうと以下の部分になります。

こちらの疎通を通すには以下の様にポータルで入力してください。Source type で Application Gateway を選択し、当該リソースを選択してください。

設定に問題が無ければ以下の様に疎通が通るはずです。

詳細を確認すると Azure Firewall (10.0.200.5)のアドレスを経由しており、ネットワークが適切に経由されていることが分かります。

こちらをコマンドで実行してみたかったのですが、コマンドの場合は --source-resource の指定が必須であり、VM 以外は受け付けていません。コマンド実行は REST API を直接叩く等の処理が必要になると思います。