Azure SQL Database をプライベート エンドポイントで閉域接続したはずなのに、Azure VM から nslookup するとパブリック IP が返ってしまい、SSMS(SQL Server Management Studio)でも接続できない――この現象は「DNS の問い合わせが Azure Private DNS ゾーンまで届いていない」ことが原因で起きる定番トラブルです。本記事では、仕組みの整理から、カスタム DNS を維持したまま恒久対処する具体策(条件付きフォワーダー/Azure DNS Private Resolver)までを実務目線でまとめます。
起きている現象:Private Endpoint 宛ての名前解決がパブリック IP になる
状況を整理すると、次のような挙動になっているはずです。
| 確認内容 | 期待する結果 | 実際の結果(問題発生時) | 意味すること |
|---|---|---|---|
VM から nslookup <FQDN> | プライベート IP(例:10.x.x.x) | パブリック IP(例:104.40.x.x) | 名前解決がパブリック側へ流れている |
nslookup <FQDN> 168.63.129.16 | プライベート IP | プライベート IP | Azure 側(既定 DNS)では Private DNS が参照できている |
| SSMS で接続(プライベート接続想定) | 接続成功 | 接続失敗 | SSMS が解決した IP がパブリックで、経路/FW/到達性が合わない |
この時点で「Private Endpoint 自体が壊れている」可能性は低く、ほぼ DNS 設計の問題です。なぜなら、同じ FQDN を Azure 既定 DNS(168.63.129.16)で引くと、期待通りプライベート IP を引けているためです。
結論:根本原因は「カスタム DNS が Azure Private DNS ゾーンを参照できていない」
多くの環境では、VM の DNS サーバーとしてカスタム DNS(例:10.81.0.4)が設定されています。VM が FQDN を引くと、基本的には次の流れになります。
VM(クライアント)
↓ DNS問い合わせ
カスタムDNS(10.81.0.4)
↓(通常の再帰解決:社内DNSの上流 or インターネットDNSへ)
パブリックDNS
↓
パブリックIPを応答
一方、Azure SQL Database の Private Endpoint で「正しいプライベート IP を返す」ためには、Azure 側の Private DNS ゾーン(privatelink.database.windows.net)に登録されているレコードを参照できる必要があります。しかし、この Private DNS ゾーンは “社内 DNS が勝手に見に行ける場所” ではありません。
つまり、問題の正体は次の一文に集約できます。
プライベート エンドポイント用の DNS 解決が、社内 DNS で完結してしまい、Azure の Private DNS ゾーンまで届いていない。
前提知識:Azure SQL のプライベート エンドポイントと DNS の「正しい形」
Azure SQL Database(PaaS)で Private Endpoint を作ると、名前解決は概ね次の考え方になります。
- プライベート エンドポイント用に Private DNS ゾーン(
privatelink.database.windows.net)を用意する - そのゾーンに「SQL サーバー名 → プライベート IP」の A レコードが作成される(自動 or 手動)
- VM などのクライアントが、その Private DNS ゾーンを参照できるようにする(VNet リンク/DNS フォワード等)
実務上は、次のどちらかで到達させます。
| 方式 | 特徴 | よくある構成 |
|---|---|---|
| Azure 既定 DNS(168.63.129.16)で解決 | Azure 内の Private DNS を参照できる(条件が揃っていれば) | VNet の DNS を “既定” のまま運用 |
| カスタム DNS → 条件付きフォワードで Azure 側へ | 社内 DNS を維持しつつ、特定ドメインだけ Azure 側へ逃がす | オンプレ AD DNS/Azure 上の DNS で条件付きフォワーダー |
今回の要件は「Azure DNS をメイン DNS にしたくない」なので、狙うべきは後者です。
まず確認:DNS 以外の“詰まり”を最短で潰すチェックリスト
本題は DNS ですが、現場では「DNS と別の原因が重なっている」こともあります。以下を先に確認しておくと、遠回りしません。
Private Endpoint/Private DNS の状態
- Private Endpoint が想定の VNet/サブネットに作成されている
- Private Endpoint の NIC にプライベート IP が付与されている
- Private DNS ゾーン
privatelink.database.windows.netに A レコードがある(サーバー名 → 10.x.x.x) - Private DNS ゾーンが、接続元 VM の VNet にリンクされている(VNet link)
VM 側で「どの DNS を使っているか」
Windows VM なら、次の確認が鉄板です。
ipconfig /all
ここで DNS Servers が 10.81.0.4 のようにカスタム DNS になっている場合、Azure Private DNS を引ける保証はありません。
名前解決の差分を明確にする(同じ FQDN を複数サーバーで引く)
nslookup id-thereforesql.privatelink.database.windows.net
nslookup id-thereforesql.privatelink.database.windows.net 168.63.129.16
nslookup id-thereforesql.privatelink.database.windows.net 10.81.0.4
この 3 点セットで「どこでパブリックに落ちているか」が一発で分かります。さらに Windows なら、Resolve-DnsName の方が情報が濃いです。
Resolve-DnsName id-thereforesql.privatelink.database.windows.net
Resolve-DnsName id-thereforesql.privatelink.database.windows.net -Server 168.63.129.16
接続先 IP がどちらになると “失敗するか” を把握する
SSMS の前に、ネットワーク的な到達性を確認しておくと切り分けが速いです。
Test-NetConnection id-thereforesql.privatelink.database.windows.net -Port 1433
DNS がパブリック IP を返しているなら、ComputerName がパブリック側へ向きます。閉域化している環境では、ここがそもそも到達しない(または SQL 側の FW で拒否)になりやすいです。
恒久対策の基本方針:カスタム DNS は維持し、該当ドメインだけ Azure 側へフォワードする
ここが最重要です。今回の解決策は「DNS サーバーを Azure の既定 DNS に丸ごと置き換える」ではありません。
ポイントは、database.windows.net(必要に応じて privatelink.database.windows.net)への問い合わせだけを Azure 側へ流すことです。
この形にすると、社内ドメイン(例:corp.local)は従来通り 10.81.0.4 で解決しつつ、Azure SQL の Private Endpoint だけ “Azure Private DNS に正しく到達” できます。
パターン別の実装:あなたの DNS がどこにあるかで最適解が変わる
パターン:DNS サーバー(10.81.0.4)が Azure 上にある場合(IaaS DNS)
カスタム DNS(10.81.0.4)が Azure VM 上で動いている(Windows DNS や BIND)なら、最短で安定させられます。理由は、Azure VM から 168.63.129.16 へ到達できるためです。
やることは 1 つ:条件付きフォワーダーを追加する
| 設定項目 | 推奨値 | 意図 |
|---|---|---|
| 条件付きフォワード対象ゾーン | database.windows.net | クライアントが通常使う SQL の FQDN を確実に Azure 側へ流す |
| 条件付きフォワード対象ゾーン(追加推奨) | privatelink.database.windows.net | 直接 privatelink を引くケースや CNAME 追跡の揺れを潰す |
| フォワード先 | 168.63.129.16 | Azure 既定 DNS で Private DNS ゾーンのレコードを参照させる |
Windows DNS なら GUI でもできますが、作業記録に残しやすい PowerShell 例も載せます。
# Windows DNS(管理者 PowerShell)
Add-DnsServerConditionalForwarderZone `
-Name "database.windows.net" `
-MasterServers 168.63.129.16 `
-ReplicationScope "Forest"
Add-DnsServerConditionalForwarderZone `
-Name "privatelink.database.windows.net" `
-MasterServers 168.63.129.16 `
-ReplicationScope "Forest"
設定後はキャッシュの影響を避けるため、クライアント側も DNS キャッシュをクリアして再確認します。
ipconfig /flushdns
この方式のメリット
- VM の DNS 設定は従来通り(10.81.0.4 のまま)でよい
- Azure SQL だけを閉域化し、他の名前解決ポリシーを壊しにくい
- 運用が分かりやすい(“どのゾーンをどこへ流すか” が明確)
よくある落とし穴
database.windows.netだけ設定してprivatelink...を漏らし、ツールや設定次第で揺れる- 条件付きフォワーダーは設定したが、DNS サーバー側が外向き再帰禁止になっていて意図通りに動かない
- DNS サーバーが 2 台以上あり、片方にしか設定していない
パターン:DNS サーバー(10.81.0.4)がオンプレミスにある場合
オンプレの DNS(Active Directory DNS など)から、いきなり 168.63.129.16 へフォワードするのは基本的におすすめしません。理由はシンプルで、168.63.129.16 は Azure 仮想ネットワーク内で機能する “Azure 既定 DNS” であり、オンプレから直接到達できない/到達させる設計ではないためです。
この場合は 2 段構えにします。
やること
- Azure 内に「DNS フォワーダー役」を 1 台用意(Windows Server でも Linux/BIND でも可)
- オンプレ DNS(10.81.0.4)は、SQL 関連ドメインだけ Azure 側フォワーダーへ条件付きフォワード
- Azure 側フォワーダーは、さらに上流として
168.63.129.16を参照(もしくは Azure 内で Private DNS を解決できる構成)
名前解決の流れはこうなります。
VM(Azure) or オンプレ端末
↓
オンプレDNS(10.81.0.4)
↓(条件付きフォワード:database.windows.net 等のみ)
Azure内 DNSフォワーダー(例:10.10.0.10)
↓(上流:168.63.129.16)
Azure既定DNS(168.63.129.16)
↓
Private DNSゾーンからプライベートIP応答
この方式が現場で強い理由
- オンプレ DNS の思想(社内名寄せ/AD 連携)を崩さずに済む
- Azure Private DNS を引くための “橋渡し” を Azure 側に置ける
- VPN/ExpressRoute がある環境では、ネットワーク境界が明確
実装の現実解(運用を軽くするコツ)
- Azure 内フォワーダーは 2 台構成(可用性セット/ゾーン冗長)にして、オンプレ側のフォワード先を複数登録する
- DNS フォワーダー専用に小さめ SKU の VM を使い、パッチ適用日を固定して運用手順化する
- ログ(クエリログ)を取れる DNS 実装を使うと、トラブル時に “どこで public に落ちたか” を追いやすい
パターン:サーバーを立てたくない場合は Azure DNS Private Resolver を使う
「DNS 用の VM を増やしたくない」「運用負荷を下げたい」「可用性をサービス側に寄せたい」という場合は、Azure DNS Private Resolver が有力です。これは、先ほどの “Azure 内 DNS フォワーダー” をマネージドで提供するイメージに近く、オンプレやカスタム DNS と Azure Private DNS の橋渡しをしやすくなります。
典型構成(オンプレ → Azure の名前解決)
- Azure の VNet に Private Resolver を作成
- Inbound endpoint(受け口)を作成し、プライベート IP を持たせる
- オンプレ DNS(10.81.0.4)で、
database.windows.net(必要ならprivatelink.database.windows.net)を Inbound endpoint 宛てに条件付きフォワード - Resolver が VNet にリンクされた Private DNS ゾーン(
privatelink.database.windows.net)を参照して回答
この方式のメリット
- DNS フォワーダー VM の OS 運用(パッチ/障害対応)が不要になりやすい
- “オンプレから Azure の Private DNS を引く” という要件に対して設計が素直
- 今後 Azure の Private Endpoint 対象サービスが増えても、考え方を横展開しやすい
注意点(ここを理解しておくとハマりにくい)
- オンプレ側の条件付きフォワード設定自体は必要(完全自動にはならない)
- Private Resolver を置く VNet と、Private DNS ゾーンのリンク関係を正しく揃える
- ネットワーク(VPN/ER、NSG、ルート)で Inbound endpoint の IP へ到達できる必要がある
どのパターンを選ぶべきか:判断基準を表で整理
| 条件 | おすすめ | 理由 |
|---|---|---|
| DNS(10.81.0.4)が Azure VM 上にある | 条件付きフォワーダー → 168.63.129.16 | 最短・低コストで解決しやすい |
| DNS(10.81.0.4)がオンプレにある/AD と密結合 | Azure 内 DNS フォワーダー VM を中継 | 168.63.129.16 をオンプレから直に使わずに済む |
| DNS 用サーバー運用を増やしたくない | Azure DNS Private Resolver | マネージドで“橋渡し”を作れる |
| 将来的に多数サービス(Storage, Key Vault 等)も Private Endpoint 化する | Private Resolver または中継フォワーダーを標準化 | 同じ設計で横展開しやすい |
具体的にどのゾーンをフォワードすべきか:実務の安全策
本件では、最小セットは次のいずれかですが、現場では「後で別ツールが別名で引いて詰まる」ことを避けるため、2 つとも条件付きフォワード するのが安全です。
| ゾーン | 必要度 | 理由 |
|---|---|---|
database.windows.net | 高 | 多くの接続文字列/ツールがこの名前を使う |
privatelink.database.windows.net | 高(推奨) | 直接引く運用や CNAME 追跡の揺れを吸収しやすい |
また、すでに社内 DNS 側で “同名ゾーン” を持っている場合(例:誤って database.windows.net を社内 DNS で権威ゾーン化している等)は、条件付きフォワードが期待通りに動きません。この場合は、ゾーン設計そのものを見直す必要があります。
「hosts 書き換え」で直るのに推奨しない理由
hosts ファイルで解決できることは多いですが、Private Endpoint の運用としては恒久対処になりにくいです。
- プライベート IP が変わる可能性(再作成/構成変更/DR など)があり、追随が手作業になりがち
- VM 台数が増えるほど運用コストが指数的に増える
- 誰がいつ更新したかの統制が取りにくい(監査・事故対応で困る)
- 別環境(検証/本番)での差分が発生しやすい
DNS レベルで設計を整える方が、将来的なサービス追加や環境増設にも耐えます。
変更後に “まだ直らない” ときの切り分け(DNS の落とし穴集)
DNS キャッシュが残っている
クライアントのキャッシュ、DNS サーバーのキャッシュ、両方が原因になり得ます。
- Windows クライアント:
ipconfig /flushdns - DNS サーバー:サービス再起動やキャッシュクリア(製品により手順が異なる)
VM が想定と違う DNS を見ている
NIC が複数ある、DHCP オプションや VNet 設定が途中で変わった、などで “自分が思っている DNS と違う” を見に行っていることがあります。ipconfig /all で DNS サーバーの優先順位まで確認してください。
Private DNS ゾーンのリンク先 VNet が違う
Azure 既定 DNS で引けるのに、特定のサブネットや VM だけ引けない場合、Private DNS ゾーンの VNet link の紐づき漏れが疑わしいです。複数 VNet を使っていると特に起きがちです。
正しい FQDN を引けていない
環境によっては、接続に使うのは <servername>.database.windows.net であり、運用者がテストで <servername>.privatelink.database.windows.net を直接引いて混乱することがあります。どちらでも最終的にプライベート IP に落ちる設計が理想ですが、検証時は「接続で実際に使っている FQDN」を基準に揃えると判断がブレません。
名前解決は直ったが接続は失敗する
DNS がプライベート IP を返すようになっても、次が詰まると SSMS は失敗します。
- NSG/FW で 1433 が遮断されている
- 経路(UDR)が原因で Private Endpoint のあるサブネットへ到達できない
- SQL 側の設定(許可方式、認証、ポリシー)が別要因で失敗している
この場合は、Test-NetConnection -Port 1433 と、Private Endpoint の NIC 宛ての到達性(ルート・NSG)を順番に確認します。
最終まとめ:やるべきことは「DNS の道を正しく作る」だけ
今回のように nslookup でパブリック IP が返ってしまうケースは、Private Endpoint の不具合というより、DNS の参照経路が設計通りになっていないことが原因です。
- VM がカスタム DNS(10.81.0.4)を見ているなら、Azure Private DNS ゾーンが参照できるとは限らない
- 恒久対策は、
database.windows.net(必要ならprivatelink.database.windows.net)を Azure 側へ条件付きフォワードすること - DNS が Azure 上なら 168.63.129.16 へ直接フォワードで OK
- DNS がオンプレなら Azure 内フォワーダー VM か Azure DNS Private Resolver を橋渡しに使う
この方針で整えると、nslookup の結果がプライベート IP に揃い、SSMS などのクライアントも安定してプライベート エンドポイント経由で接続できるようになります。

コメント