🌐

Private Link Serviceの新機能 Direct Connectを試してみた🚀

に公開

はじめに

2025/10にPrivate Link ServiceのDirect Connect機能がPreview提供されました🎉
実際に試してみながら、今回のアップデートを解説してみます!

Private Link Serviceとは

Private Link Serviceとは、独自のアプリを利用者側のVNetからアクセスできるように公開するための仕組みです。

アプリの提供者(Provider)はPrivate Linkアクセスを有効し、利用者(Consumer)は自分のVNetにPrivate Endpointを設置してアクセスします。
ProviderのVNetとConsumerのVNetをピアリングすることなく、独自のアプリ/サービスへ接続することができます。

AzureのPrivate Link Serviceそのものについては、こちらの記事で分かりやすく解説されています。

https://zenn.dev/microsoft/articles/f3d98d20d6bc9f

今まではアプリの提供者(Provider)は必ずStandard Load Balancer(SLB)を利用してPrivate Link Serviceを構成する必要がありました。

そのため、以下のようなSLBの制約を受けてしまいます。

SLBのバックエンドリソースに指定可能なのはNICのみ

  • 従来のPrivate Linkを構成するときには、SLBのバックエンドにはVMやVMSSのNICを指定する必要がありました。

https://learn.microsoft.com/ja-jp/azure/private-link/private-link-service-overview#limitations

SLBのバックエンドリソースに指定できないものがある

  • 異なるVNetのNICやIPアドレスは指定できません。(LBとバックエンドは同一VNetが前提)
    • オンプレミスのサーバーなども同様です。(ヘルスプローブもAzure内限定)
  • Application GatewayやPrivate Endpointも指定できません。

https://learn.microsoft.com/ja-jp/azure/load-balancer/backend-pool-management#limitations

今回発表されたDirect Connect機能を使用すると、Standard Load Balancerが不要になります!

Private Link Service構成時にVNet内外の宛先IPアドレスを指定可能で、SLBを介さずにそのIPアドレスに直接接続することができます。

そのため、今まではSLBの制約となっていた構成も実現できる他、Private Link Serviceの背後でUDRを使用したトラフィック検査などを行うといったことも可能になります。

https://learn.microsoft.com/ja-jp/azure/private-link/configure-private-link-service-direct-connect?tabs=cli%2Ccli-pe%2Cverify-powershell%2Ccleanup-powershell

試してみる

Public Preview機能の有効化

Private Link ServiceのDirect Connect機能を使用するサブスクリプションでは、予め機能フラグMicrosoft.Network/AllowPrivateLinkserviceUDRを有効にしておく必要があります。

$ az feature register --name AllowPrivateLinkserviceUDR --namespace Microsoft.Network
{
  "id": "/subscriptions/*****/providers/Microsoft.Features/providers/Microsoft.Network/features/AllowPrivateLinkserviceUDR",
  "name": "Microsoft.Network/AllowPrivateLinkserviceUDR",
  "properties": {
    "state": "Registered"
  },
  "type": "Microsoft.Features/providers/features"
}

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/management/preview-features?tabs=azure-portal

PoC構成

まずはDirect ConnectなPrivate Link Serviceを試すために、SLB無しでPrivate Link ServiceからVMに直接接続してみます。

アプリの提供者(Provider)はSLBが不要となり、シンプルな構成になります。

Terraformで構成図のリソースを展開します。コードはこちらのGithubに格納してあります。

https://github.com/mrtryo/terraform-azure-learn/tree/main/azure-privatelink-directconnect/01_server/pls-server-scenario01

azurerm_private_link_serviceでPrivate Link Serviceを作成します。
destination_ip_addressにSLBではなく任意のIPアドレスを指定すればDirect ConnectなPrivate Link Serviceとして動作します。

resource "azurerm_private_link_service" "pls" {
  name                = "Private Link Service名"
  resource_group_name = azurerm_resource_group.rg.name
  location            = "westus"
  destination_ip_address = 192.168.0.132 # Server VMのIPアドレス(NGINXでサービスを提供する)

  auto_approval_subscription_ids = [var.subscription_id]
  visibility_subscription_ids    = [var.subscription_id]

  nat_ip_configuration {
    name               = "primary"
    private_ip_address = "192.168.0.4" # ソースNAT用のIPアドレス
    private_ip_address_version = "IPv4"
    subnet_id                  = azurerm_subnet.pls.id
    primary                    = true
  }

  nat_ip_configuration {
    name               = "secondary"
    private_ip_address = "192.168.0.5" # ソースNAT用のIPアドレス
    private_ip_address_version = "IPv4"
    subnet_id                  = azurerm_subnet.pls.id
    primary                    = false
  }
}

Private Link Serviceを展開するサブネットではprivateLinkServiceNetworkPoliciesプロパティを無効にする必要があります。

resource "azurerm_subnet" "pls" {
  resource_group_name  = azurerm_resource_group.rg.name
  name                 = "サブネット名"
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["192.168.0.0/26"]
  # Private Link Service Direct Connectを使う場合は無効にする必要がある
  private_link_service_network_policies_enabled = false
}

作成したPrivate Link Serviceを確認すると、宛先IPアドレスとSNAT用のIPアドレス設定が確認できます。

接続確認

Client VMからPrivate EndpointのIPアドレスにcurlをすると、Server VMで動いているNGINXのWEBページが取得できました。
NGINXは自分のホスト名をHTTPレスポンスボディで返却するように構成してあります。

azpoc-user@azpoc-client-usw-vm-client-001:~$ curl -v http://10.0.0.5
*   Trying 10.0.0.5:80...
* Connected to 10.0.0.5 (10.0.0.5) port 80
> GET / HTTP/1.1
> Host: 10.0.0.5
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx/1.24.0 (Ubuntu)
< Date: Sun, 19 Oct 2025 12:28:57 GMT
< Content-Type: text/html
< Content-Length: 28
< Last-Modified: Sun, 19 Oct 2025 12:22:02 GMT
< Connection: keep-alive
< ETag: "68f4d7ea-1c"
< Accept-Ranges: bytes
< 
azpoc-pls-usw-vm-server-001
* Connection #0 to host 10.0.0.5 left intact

PoC構成

Private Link Serviceの宛先IPアドレスにApplication Gatewayを指定してみます。
従来はサポートされていなかった構成です。

ちなみに、今回はPoCのためにPrivate Link Serviceの宛先にApplication Gatewayを使ってみましたが、Application Gateway自体はPrivate Endpointに対応しています。

https://learn.microsoft.com/ja-jp/azure/application-gateway/private-link

接続確認

Client VMからPrivate EndpointのIPアドレスにcurlをすると、Server VMで動いているNGINXのWEBページが取得できました。

azpoc-user@azpoc-client-usw-vm-client-001:~$ curl -v http://10.0.0.5
*   Trying 10.0.0.5:80...
* Connected to 10.0.0.5 (10.0.0.5) port 80
> GET / HTTP/1.1
> Host: 10.0.0.5
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Sun, 19 Oct 2025 11:15:58 GMT
< Content-Type: text/html
< Content-Length: 28
< Connection: keep-alive
< Server: nginx/1.24.0 (Ubuntu)
< Last-Modified: Sun, 19 Oct 2025 10:53:24 GMT
< ETag: "68f4c324-1c"
< Accept-Ranges: bytes
< 
azpoc-pls-usw-vm-server-001
* Connection #0 to host 10.0.0.5 left intact

Application Gatewayのログを見ると、Private Link ServiceのSource NAT用のIPアドレスから接続されたことも確認できます。

PoC構成

Private Link Serviceの宛先IPアドレスにAzure Firewallを指定してみます。
こちらも従来はサポートされていなかった構成です。

Azure FirewallにはServer VMを宛先としたDNAT Ruleを設定しておき、Private Link経由でAzure FirewallのDNAT Portに接続してみます。

接続確認

Client VMからPrivate EndpointのIPアドレス(FirewallのDNAT Port指定)にcurlをすると、Server VMで動いているNGINXのWEBページが取得できました。

azpoc-user@azpoc-client-usw-vm-client-001:~$ curl -v http://10.0.0.5:10080
*   Trying 10.0.0.5:10080...
* Connected to 10.0.0.5 (10.0.0.5) port 10080
> GET / HTTP/1.1
> Host: 10.0.0.5:10080
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx/1.24.0 (Ubuntu)
< Date: Sun, 19 Oct 2025 08:24:09 GMT
< Content-Type: text/html
< Content-Length: 28
< Last-Modified: Sun, 19 Oct 2025 08:08:22 GMT
< Connection: keep-alive
< ETag: "68f49c76-1c"
< Accept-Ranges: bytes
< 
azpoc-pls-usw-vm-server-001
* Connection #0 to host 10.0.0.5 left intact

Azure Firewallのログを見ると、DNAT Ruleで接続していることが確認できます。

PoC構成

Azure Firewallの明示的なProxy機能を有効化して、Azure Firewallをフォワードプロキシとして使用してみます。

接続確認

Client VMからPrivate EndpointのIPアドレスを--proxyオプションでプロキシとして指定してインターネット上の接続元パブリックIPアドレスが確認できるWEBサイトにアクセスすると、Azure FirewallにアタッチしているパブリックIPアドレスで接続していることが確認できました!

azpoc-user@azpoc-client-usw-vm-client-001:~$ curl -v https://checkip.amazonaws.com --proxy 10.0.0.5:9002
*   Trying 10.0.0.5:9002...
* Connected to 10.0.0.5 (10.0.0.5) port 9002
* CONNECT tunnel: HTTP/1.1 negotiated
* allocate connect buffer
* Establish HTTP proxy tunnel to checkip.amazonaws.com:443
> CONNECT checkip.amazonaws.com:443 HTTP/1.1
> Host: checkip.amazonaws.com:443
> User-Agent: curl/8.5.0
> Proxy-Connection: Keep-Alive
> 
< HTTP/1.0 200 OK

省略

> GET / HTTP/2
> Host: checkip.amazonaws.com
> User-Agent: curl/8.5.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 200 
< date: Sun, 19 Oct 2025 08:25:48 GMT
< content-type: text/plain;charset=UTF-8
< content-length: 14
< server: nginx
< vary: Origin
< vary: Access-Control-Request-Method
< vary: Access-Control-Request-Headers
< 
20.184.179.18
* Connection #0 to host 10.0.0.5 left intact

Azure Firewallのログを見ると、Application Ruleで接続していることが確認できます。

PoC構成

Client VMを配置しているサブネットに対して、Private EndpointをデフォルトゲートウェイとするUDRを設定し、Azure Firewallを透過的なProxyとして使用してみます。

接続確認

Client VMからインターネット上のWEBサイトにcurlでHTTP接続するとタイムアウトになってしまいます。
どうやら、Private EndpointはUDRのNext Hopの指定には対応していないようです。

https://learn.microsoft.com/en-us/answers/questions/1634323/is-it-possible-to-route-to-a-private-endpoint-to-p

azpoc-user@azpoc-client-usw-vm-client-001:~$ curl -v https://checkip.amazonaws.com
* Host checkip.amazonaws.com:443 was resolved.
* IPv6: (none)
* IPv4: 54.156.48.12, 98.85.245.215, 184.72.253.175, 54.165.16.227, 3.219.189.31, 3.223.241.132, 3.211.246.156, 54.90.154.129
*   Trying 54.156.48.12:443...
* connect to 54.156.48.12 port 443 from 10.0.0.4 port 46364 failed: Connection timed out
*   Trying 98.85.245.215:443...
* ipv4 connect timeout after 81853ms, move on!
*   Trying 184.72.253.175:443...
* ipv4 connect timeout after 40925ms, move on!

UDRを使用せず、Private EndpointのIPアドレスをしていしたAzure FirewallへのTCP接続は成功します。

azpoc-user@azpoc-client-usw-vm-client-001:~$ curl -v telnet://10.0.0.5:80
*   Trying 10.0.0.5:80...
* Connected to 10.0.0.5 (10.0.0.5) port 80

まとめ

Private Link ServiceのDirect Connect機能が提供されたことで、Private Link Serviceから任意のプライベートIPへSLBの制約を受けずに直結できるようになりました!
今回のPoCではPrivate Link Serviceの宛先IPアドレスを同一VNetで構成しましたが、Peeringしている別VNetやオンプレミスのIPアドレスも指定可能です。

VNetピアリングをしたくない・できない場合でもサービスを公開しやすくなるので、まだPublic Previewですが、アーキテクチャの選択肢と自由度を広げる嬉しいアップデートですね🚀

参考

Discussion