ポイント対サイト トンネルに接続し、プライベート アドレスに ping を打ち、アプリを開くと、代わりに 403 か証明書エラーが返ります。どちらの症状も DNS を指しますが、別々の障害です。一方はクライアントがパブリック アドレスを解決したという意味で、もう一方はプライベート アドレスを解決したうえで証明書がカバーしない名前を提示したという意味です。以下の確認は順番に行い、最初の失敗で止めてください。hosts エントリやキャッシュされた応答があると、以降の確認が誤った理由で通ってしまうからです。私はこの順序を VPN プロファイルの隣のテキスト ファイルに残しています。修正はトンネル側を何も変えず、クライアントが知っていることをすべて変えるからです。

クライアントが実際に受け取るアドレスから始める

アプリケーションを信じるのではなく、リゾルバーに直接問い合わせます。Windows では nslookup adminuidev-fedqcubyd9bfb2bq.canadacentral-01.azurewebsites.net で、クライアントがどちらのビューを受け取ったかが分かります。パブリックな応答なら、その先のどこもエンドポイントに届きません。エンドポイントのプライベート アドレスなら DNS は済んでおり、次の確認は接続そのものです。

プライベート エンドポイントはサービス名を変えません。アカウントやアプリは通常の完全修飾名を保ち、エンドポイントは仮想ネットワーク内のクライアントに対してその名前が解決されるアドレスだけを変えます。だから同じホスト名が、ネットワーク内の VM からはプライベートに、プライベート ビューを渡されていないノート PC からはパブリックに解決されます。

トンネルの前に、ゾーン、そのリンク、レコードを確認する

三つの条件が同時に成り立つ必要があります。プライベート ゾーンが存在し、VPN ゲートウェイとクライアントが Azure に入る仮想ネットワークにリンクされ、エンドポイントの A レコードがプライベート アドレスを指していることです。ゾーンを無関係なネットワークにリンクすると、ゲートウェイはパブリック レコードを解決し続け、トンネル側は健全に見えたままになります。

ゾーン名はサービスに属し、私設リンク全般に属するわけではありません。App Service は通常 privatelink.azurewebsites.net を使い、ストレージと SQL には独自の名前空間があります。別のサービスのゾーンを借りると、存在するだけで役に立つ応答を返さないゾーンができます。

クライアントが実際に到達できるリゾルバーを与える

168.63.129.16 は Azure の仮想マシンから応答するもので、ポイント対サイト トンネルの向こう側にあるノート PC にとっての DNS サーバーではありません。クライアントにはトンネル経由で到達できるリゾルバーが必要です。Azure DNS Private Resolver の受信エンドポイント、仮想ネットワーク内のフォワーダー、または VPN クライアント プロファイルに載せる DNS サーバー エントリで、クライアントが仮想ネットワークに直接問い合わせるようにします。

構成済みでも到達できないリゾルバーは、リゾルバーがない場合とまったく同じに振る舞います。症状は誤った応答ではなくタイムアウトなので、ファイアウォールの問題と読み違えられます。トンネルが運ぶはずのクエリで試し、ローカル リンクでも成功するパブリック名では試さないでください。

設定をプッシュするのではなく転送する場合は、プライベート ゾーンが持つ名前空間だけを転送します。azurewebsites.net 全体ではなく privatelink.azurewebsites.net です。親サフィックス全体を飲み込む条件付きフォワーダーは、ローカルに残すべきものを含め、そのサービスのすべての検索を Azure に送ります。

証明書が発行された名前を使う

アドレスが正しくなると、二つ目の障害が表に出ます。ストレージと App Service は privatelink エイリアスを公開しますが、そのエイリアスが証明書の名前とは限りません。privatelink.blob.core.windows.net 宛ての AzCopy アップロードは検証に失敗しました。同じアップロードを <account>.blob.core.windows.net/<container> 宛てにするとプライベート アドレスに解決されて通り、回避策なしでプライベート経路に留まりました。

この規則はブラウザーでも App Service でも同じです。証明書がカバーするホスト名で接続し、プライベート アドレスは DNS に任せます。検証の回避に手を伸ばしてはいけません。命名の誤りがセキュリティの後退に変わるだけです。ping の成功は経路を示すもので、ハンドシェイク内の名前については何も語りません。だからこれらは別々の確認のままです。

各層を切り分ける四つの手順

  1. VPN クライアントがポイント対サイト プールのアドレスを持ち、エンドポイントのプライベート アドレスへのルートがあることを確認します。
  2. アプリケーションが使う正確な名前を解決し、その応答をエンドポイントのアドレスと比べます。
  3. サービスのポートでエンドポイントに TCP 接続を開き、その接続で提示された証明書の名前を読みます。
  4. 認可を試すのはその後です。経路が通って証明書が有効でも、リソースへのアクセスはまだ得られません。

アドレスが正しいのに接続が拒否される場合は、DNS ではなくネットワーク セキュリティ グループかプライベート エンドポイント接続の状態を示します。リゾルバーの設定を再び編集する前に、そこを確認してください。TLS 名の不一致は、URL のホスト名と証明書の subject に戻ります。解決の出力、証明書の名前、正確な URL を一緒に保管してください。この三つの値で、ゲートウェイに触れずにほとんどの事例を説明できます。

仮想ネットワーク内の VM を対照として使います。そこでプライベートに、トンネルからはパブリックに解決されるなら、ゾーンとレコードは正しく、違いはクライアントのリゾルバー経路だけです。エンドポイント構成をもう一度見直すより速く確認できます。

クライアントもキャッシュします。十分前にパブリックに応答したレコードは、ゾーンを直した後も応答し続けるので、再試験の前にフラッシュしてください。Windows では ipconfig /flushdns がクライアント キャッシュを消します。名前解決ポリシーの規則は残り、どのサフィックスをどのサーバーに送るかを決め、置き換えたばかりのリゾルバーへ名前空間を送り続けることがあります。

hosts エントリを置くべき場所

エンドポイントのアドレスを hosts ファイルに足すのは、良い診断であり、悪い設計です。名前とアドレスの対応が欠けている部分だと証明でき、その後のすべてを試せますが、利用者には見えず、エンドポイントのアドレスが変わると壊れ、応答すべきゾーンを隠してしまいます。

残ったテスト用エントリは古いキャッシュより厄介です。誤りの向きによって、直した経路が壊れて見えたり、壊れた経路が直って見えたりするからです。最終確認の前に削除し、本番のリゾルバーだけで解決してください。

短い名前には検索サフィックスが必要で、完全修飾名には不要です。まず完全修飾名を試し、そのうえでワークフローにクライアント プロファイル経由のサフィックスが必要かを決めます。Microsoft はプライベート エンドポイントの DNS ガイダンスでサービスごとのゾーン名とレコードの形を文書化しています。他のサービスからゾーンを写すのではなく、自分のサービスの項目を読んでください。

関連記事