Azure Blob Storage プライベート エンドポイントでSSL証明書ホスト名不一致(RemoteCertificateNameMismatch)を解決する方法

Azure Blob Storage をプライベート エンドポイントで閉域化したのに、アプリから HTTPS 接続すると証明書のホスト名不一致で失敗する…この原因は URL の選び方と DNS の仕組みにあります。本記事では最短で直す方法と、DNS の裏側を具体例付きで整理します。

目次

起きている症状:RemoteCertificateNameMismatch の正体

ストレージ アカウントに対してプライベート エンドポイントを作成し、パブリック アクセス(Public network access)を無効化した環境で、アプリやツールが次のような URL を使ってアクセスしているとします。

アクセスに使っている URL(例)結果
https://<account>.privatelink.blob.core.windows.net/...SSL/TLS でホスト名不一致(RemoteCertificateNameMismatch)になりやすい

エラーメッセージの典型例は次のとおりです(表現はランタイムやライブラリで多少変わります)。

  • SSL policy errors: RemoteCertificateNameMismatch
  • 要求ホスト名:<account>.privatelink.blob.core.windows.net
  • 証明書のサブジェクト:CN=*.blob.core.windows.net

これは「暗号化(HTTPS)はできているが、相手が本当に目的のサービスかを確認するためのホスト名検証に失敗している」状態です。つまり、アプリ側が指定したホスト名と、サーバが提示する証明書の対象ホスト名が一致していないことが原因です。

結論:アプリが使うべきホスト名は public 側の FQDN

プライベート エンドポイントを使う場合でも、アプリがアクセスに使うべき URL は次の形式です。

https://<account>.blob.core.windows.net/…

ポイントは「privatelink を URL に書かない」ことです。Azure Storage が提示するサーバ証明書は通常 *.blob.core.windows.net に対して有効なワイルドカード証明書であり、*.privatelink.blob.core.windows.net 用の証明書を返す設計にはなっていません。したがって、クライアントが <account>.blob.core.windows.net に対して接続すれば、証明書のホスト名が一致してエラーは解消します。

やること具体例ねらい
アプリの接続先 URL を修正https://<account>.blob.core.windows.net証明書の対象(*.blob.core.windows.net)と一致させる
DNS を正しく設定プライベート DNS ゾーンを VNet にリンク同じ FQDN のまま、VNet 内ではプライベート IP に到達させる

なぜ privatelink を直接使うと証明書が合わないのか(TLS の基本)

HTTPS の通信では、単に暗号化するだけでなく「接続先が本当に意図した相手か」を確認します。その確認の一つが ホスト名検証です。具体的には、クライアントがアクセスした FQDN(例:<account>.privatelink.blob.core.windows.net)が、サーバ証明書の SAN(Subject Alternative Name)または CN(Common Name)に含まれているかをチェックします。

今回のケースでは、サーバが提示する証明書が CN=*.blob.core.windows.net です。ワイルドカードは「同一階層の 1 ラベルだけ」を代表するため、次のような関係になります。

接続先ホスト名CN=*.blob.core.windows.net に一致する?理由
mystorage.blob.core.windows.net一致* が mystorage に該当する
mystorage.privatelink.blob.core.windows.net一致しない* で吸収できるのは 1 ラベルだけで、mystorage.privatelink は対象外

そのため、URL に privatelink を入れてしまうと、暗号化そのものは成功しても「証明書がそのホスト名を保証していない」と判断され、RemoteCertificateNameMismatch になります。これはセキュリティ上とても重要なチェックなので、基本的に回避(無効化)すべきではありません。

プライベート エンドポイント時の DNS:裏側で何が起きているか

「じゃあ、なぜプライベート DNS ゾーン privatelink.blob.core.windows.net を作るのか?」という疑問が出やすいのですが、ここは DNS の流れを押さえると腑に落ちます。プライベート エンドポイントを作成したときの基本的な名前解決は、次の二段構えでできています。

public 側:CNAME が privatelink 側へ誘導する

まず public の名前解決では、次のような CNAME が存在する(または同等の誘導が行われる)イメージです。

&lt;account&gt;.blob.core.windows.net
  CNAME  &lt;account&gt;.privatelink.blob.core.windows.net

ここで重要なのは、クライアントは最初に <account>.blob.core.windows.net を引くという点です。クライアントが最初から privatelink を指定する必要はありません。

VNet 内:privatelink 側をプライベート IP に解決する

次に、VNet にリンクされたプライベート DNS ゾーン(privatelink.blob.core.windows.net)が、CNAME の行き先である FQDN をプライベート IP に解決します。

&lt;account&gt;.privatelink.blob.core.windows.net
  A  10.x.x.x(プライベート エンドポイントの IP)

これにより、アプリが URL を変えなくても、VNet 内からはプライベート エンドポイントの IP に到達できるようになります。通信経路がプライベートに切り替わっても、TLS のホスト名検証は「<account>.blob.core.windows.net」で行われるため、証明書エラーも起きません。

流れを図で整理

文章だけだと混乱しやすいので、名前解決と接続先の関係を簡易図で整理します。

(アプリが指定する URL)
https://&lt;account&gt;.blob.core.windows.net/...

        │ ① 名前解決(VNet 内)
        ▼
&lt;account&gt;.blob.core.windows.net
        │ ② CNAME
        ▼
&lt;account&gt;.privatelink.blob.core.windows.net
        │ ③ Private DNS Zone の A レコード
        ▼
10.x.x.x(Private Endpoint の NIC)
        │ ④ HTTPS 接続(SNI/Host は &lt;account&gt;.blob.core.windows.net)
        ▼
Azure Storage(証明書: *.blob.core.windows.net)

結果として、アプリは常に public の FQDN を使い続けるのが正解で、DNS が「public ルートか private ルートか」を切り替えてくれます。これが Azure Private Link の狙いどころです。

「結局 .blob.core.windows.net を使うのはなぜ?」への答え

疑問の核心はここです。

  • プライベート DNS ゾーンの名前は privatelink.blob.core.windows.net
  • でもアプリは <account>.blob.core.windows.net を使う

一見すると矛盾しているように見えますが、実際は役割分担が違うだけです。

要素何のためにある?誰が直接使う?
<account>.blob.core.windows.netアプリ/SDK/ツールが「いつもの Azure Storage」として扱うための正規のエンドポイントアプリ(開発者が設定する)
<account>.privatelink.blob.core.windows.netPrivate Link による名前解決の“受け皿”(CNAME の行き先)DNS(裏側で参照される)
プライベート DNS ゾーンVNet 内で privatelink 側 FQDN をプライベート IP に解決するネットワーク管理(運用が設定する)

要するに、アプリは API の表側(public FQDN)だけを見ていればよく、閉域化は DNS とネットワーク側で吸収するという設計です。URL を変えずに「public → private」へ切り替えられるため、移行や運用が圧倒的に楽になります。

設定の確認ポイント:これだけ押さえれば迷いにくい

実務では「URL は直したのに、まだつながらない」というケースが多いです。原因の多くは DNS です。以下のチェックリストで切り分けると、復旧が速くなります。

チェック項目期待する状態よくある失敗
アプリの URL<account>.blob.core.windows.net を使用privatelink を直書きしてしまう
プライベート DNS ゾーンprivatelink.blob.core.windows.net が存在ゾーン未作成、名前を誤る、別サブスクリプションに作る
VNet リンク対象 VNet にゾーンがリンクされている別 VNet にリンク、リンク漏れ
A レコード<account>.privatelink.blob.core.windows.net がプライベート IP を指す自動登録されていない、手動作成ミス
クライアントの DNSVNet の DNS(Azure 提供または正しいフォワーダ)を参照オンプレ DNS のままで privatelink ゾーンに到達しない
ストレージ側のネットワーク設定public 無効でも、Private Endpoint 経由で到達できるサブリソース(blob/file 等)を間違えて PE 作成

社内 DNS(カスタム DNS)を使っている場合は特に注意

VNet の DNS サーバを独自(オンプレや IaaS 上の DNS)にしている環境では、privatelink.blob.core.windows.net の名前解決ができず、結果として public 側に向かってしまうことがあります。public を無効化していると、ここでタイムアウトや 403、名前解決の揺れが発生しやすくなります。

典型的な対処は次のいずれかです。

  • 社内 DNS に 条件付きフォワーダを設定し、privatelink.blob.core.windows.net(必要なら他の privatelink ゾーンも)を Azure 側へ転送する
  • Azure 側に Azure DNS Private Resolver を立て、オンプレから privatelink ゾーンを引けるようにする
  • 簡易的には、VNet 内のリソースだけ Azure 提供 DNS を参照する構成へ戻す(要件次第)

運用現場では「アプリの URL を直したのに直らない」よりも「DNS フローが想定と違う」ほうが圧倒的に多いので、まずは名前解決の結果を目で確認するのが近道です。

実際の確認方法:nslookup だけで切り分けできる

VNet 内の VM や App Service(VNet 統合)など、実際にアクセスする場所から名前解決を確認します。目的は単純で、<account>.blob.core.windows.net がプライベート IP に解決されることです。

Windows(PowerShell)

Resolve-DnsName <account>.blob.core.windows.net

# 参考:CNAME の先も確認したい場合

Resolve-DnsName .privatelink.blob.core.windows.net 

Linux(nslookup / dig)

nslookup &lt;account&gt;.blob.core.windows.net
dig +short &lt;account&gt;.blob.core.windows.net

期待する結果は、10.* や 172.16.*、192.168.* といった プライベート IP が返ることです。もし public IP 側に解決されるなら、プライベート DNS ゾーンのリンクやフォワーディングが効いていません。

証明書の確認(OpenSSL)

「今つながっている先が本当に Storage か」「提示される証明書は何か」を確認したいときは、OpenSSL の SNI を明示すると分かりやすいです。

openssl s_client -connect &lt;account&gt;.blob.core.windows.net:443 -servername &lt;account&gt;.blob.core.windows.net

出力の中で subject が CN=*.blob.core.windows.net のようになっていれば、証明書は期待どおりです。ここで -servername を省略すると SNI が省かれ、環境によっては別の証明書が見えることがあるので、検証時は明示するのが安全です。

よくある落とし穴:証明書の問題に見えて DNS の問題

最後に、現場でよく遭遇する「似た症状」をまとめます。エラーメッセージが SSL でも、原因が DNS・プロキシ・接続先の作法にあることが珍しくありません。

症状ありがちな原因対処
RemoteCertificateNameMismatchprivatelink を URL に直書き、または IP 直指定URL を <account>.blob.core.windows.net に戻す
タイムアウト/接続不可名前解決が public 側へ行っている(public 無効化のため到達できない)Private DNS ゾーン・VNet リンク・DNS フォワーダを見直す
環境によってつながったりつながらなかったりするDNS キャッシュ、複数 DNS サーバの応答差、VPN 経由の分岐クライアントの DNS 設定を統一し、キャッシュをクリアして再検証
SDK だけ失敗する/ツールは成功するプロキシが Host ヘッダを書き換える、SDK のカスタムエンドポイント設定が誤りプロキシ設定と SDK の endpoint を点検(Host が変わっていないか)

「IP アドレスで直接叩けば速い」は危険

プライベート IP を引けると、つい https://10.x.x.x/ のように IP 直指定で試したくなります。しかしこれは高確率で証明書エラーになります(証明書は IP を保証していないため)。トラブルシュートでも、基本は FQDN を使ったまま確認しましょう。

どうしても privatelink の FQDN を使いたい場合の現実解

結論から言うと、Azure Storage に「*.privatelink.blob.core.windows.net の証明書を返して」と要求して切り替えられる仕組みは基本的にありません。ですので、アプリ側で privatelink を直書きし続けたい場合は、別のコンポーネントで “証明書を合わせる” ことになります。ただし構成が複雑になり、運用コストも上がるため、強い理由がない限り推奨はしません。

選択肢概要向いているケース注意点
推奨:URL を public FQDN に戻すDNS に任せて private に誘導ほとんどのケースDNS 設計が正しく必要
リバースプロキシで TLS 終端社内向け FQDN の証明書をプロキシに設定し、背後で Storage に接続どうしても独自ドメイン/独自証明書を使いたいプロキシ運用が必要、性能・可用性設計が増える
ホスト名検証を無効化証明書のホスト名チェックをスキップ原則おすすめしない中間者攻撃リスクが跳ね上がる

Private Link のメリットは「アプリの URL を変えずに閉域化できる」点にあります。無理に privatelink を URL に露出させるほど、設計の利点を削ってしまうため、基本方針としては public FQDN を維持するのが最も堅牢です。

SDK・ツールでの実践メモ(URL を迷わないために)

最後に、開発者が迷いやすいポイントを整理します。特に SDK を使う場合、設定項目の名前が “endpoint” だったり “URL” だったりして、誤って privatelink を指定してしまうことがあります。

対象基本の指定避けたい指定
Azure SDK(BlobServiceClient など)https://<account>.blob.core.windows.nethttps://<account>.privatelink.blob.core.windows.net
接続文字列AccountName / AccountKey(または MSI)中心EndpointSuffix を独自にいじって privatelink に寄せる
AzCopy / CLIhttps://<account>.blob.core.windows.net の URL を入力privatelink を URL に含める

閉域化の実装はネットワーク(Private Endpoint)と DNS(Private DNS zone)で実現し、アプリコードは “いつもの Azure Storage” として扱う。ここを徹底すると、環境差分(開発・検証・本番)に強い構成になります。

まとめ:解決の最短ルート

  • アプリの接続先 URL は <account>.blob.core.windows.net を使う(privatelink を直書きしない)
  • VNet 内で同じ FQDN が プライベート IP に解決されるよう、Private DNS ゾーンと DNS 連携を整える
  • nslookup / Resolve-DnsName で「どこに解決されているか」を最初に確認すると、原因切り分けが速い

プライベート エンドポイントは “接続先 URL を変える仕組み” ではなく、“同じ URL を安全にプライベート経路へ切り替える仕組み” です。URL と DNS の役割分担を理解しておくと、証明書エラーだけでなく、閉域化後の接続トラブル全般を短時間で解決できるようになります。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次