プライベート Route 53 ゾーンは、パブリックレコードと統合するのではなく、名前の回答そのものを置き換えます。そのため、最悪のタイミングで人が驚くことになります。内部レコードを一件追加します。対象は api.example.net で、これを格納するプライベートゾーンは example.net です。そのゾーンを VPC に関連付けると、この親の配下にある他のすべての名前はプライベートゾーンだけから応答されます。昨日まで www.example.net に到達できていたクライアントは、今日は否定応答を受け取ります。以下の手順はその失敗したクエリから始まり、応答したゾーンへと外側に向かって進みます。

コンソールではなくクエリから始める

報告されたクライアントで障害を再現し、正確な名前とレコード種別を記録します。 A では失敗しても、AAAA では解決できる場合があります。さらに、キャッシュされた名前を再試行するブラウザは、どちらが壊れたのかを隠します。クエリは二回実行します。一回はクライアントが実際に使うリゾルバ経由で、もう一回はそれを迂回するトレース付きです。

dig +short api.example.net
dig www.example.net +noall +comments +authority
resolvectl query www.example.net

重要なのは二番目のコマンドです。そのステータス行と authority セクションには、回答を生成したゾーンが示されます。したがって、プライベートゾーンからの否定応答を、タイムアウト、ブロックされたポート、クエリを一度も受け取らなかったリゾルバと区別できます。 resolvectl は、どの上位サーバーに問い合わせたかを示します。これは多くの場合、VPN が配布したと想定していたリゾルバではありません。

トレース付きのクエリがパブリックアドレスを返し、通常のクエリが返さないなら、パブリックレコードは無傷で、プライベートビューが応答しています。この一つの比較が、このページの残りのどちらの半分が当てはまるかを決めます。

どのゾーンが応答したかを読む

次の応答は NXDOMAIN を含み、authority セクションにプライベートゾーンの SOA を持つ場合、そのゾーンからの確定応答であり、検索失敗ではありません。Route 53 Resolver は名前が一致したためにプライベートホストゾーンを選択し、次に要求された種別のレコードを見つけられませんでした。文書化された動作は、質問をパブリック DNS に転送するのではなく、否定応答を返すことです。

選択は具体性に従います。複数のプライベート名前空間が重なる場合、最も具体的に一致するゾーンが優先され、より広いプライベート親が、選択された子ゾーンにない名前について二度目の機会を得ることはありません。転送ルールはさらに層を追加します。ドメイン固有の Resolver ルールが、プライベートホストゾーンの関連付けに優先することがあるからです。ゾーンが空だと結論する前に、関連付けとルールを列挙してください。

aws route53 list-hosted-zones-by-name --dns-name example.net.
aws route53 list-resource-record-sets --hosted-zone-id Z0EXAMPLEID --query "ResourceRecordSets[?Type=='A'].[Name,ResourceRecords[0].Value]"

どちらのコマンドもゾーンを所有するアカウントの認証情報が必要で、二番目は一番目から得たゾーン ID が必要です。ご自身の ID に置き換えてください。上のプレースホルダーは意図的に実在しません。

プライベートゾーンが優先される理由

ゾーンを VPC から見えるようにするのは関連付けであり、その VPC 内のリゾルバがそれを適用します。クライアントのトラフィックが届く VPC に関連付けられていないプライベートゾーンはまったく効果がなく、誤った VPC への関連付けは誤った利用者層にプライベートな回答を返します。レコードを編集する前に関連付けの一覧を確認してください。ゾーンが正しくても見えないことがあります。

重なる名前空間は混乱の二つ目の源です。 example.net のプライベートゾーンと、api.example.net のプライベートゾーンは、どちらも API クエリに一致し、より具体的な方が応答します。狭い内部名前空間が必要なときには便利で、狭いゾーンにより広いゾーンにあるレコードが欠けているときには危険です。プライベートホストゾーンに関する考慮事項は Route 53 のドキュメント に、下位ゾーンへ落ちる動作とルールの優先順位の両方が説明されており、重なるゾーンを二つ目に追加する前に読む価値があります。

これらいずれもパブリックゾーンを変えません。パブリックリゾルバは今もパブリックレコードに正しく応答しており、だからこそ VPC の外にいる人にはこの障害がクライアントの問題に見えます。

レコードを追加する前に名前空間を選ぶ

内部サービスの新しい一群だけがプライベート名を必要とするなら、専用のプライベートサブドメインを与え、パブリック親には手を付けません。次のような名前は internal.example.net を覆い隠すことはできず、www.example.net、レコードが欠けたときの影響範囲は、その目的のために作った名前に限られます。代償は、既存の URL と証明書が新しい名前と一致しない可能性があることです。

パブリックとプライベートの利用者が同じホスト名を維持しなければならない場合、分割ビュー DNS がサポートされる設計であり、各ビューでレコードを明示的に維持する必要があります。レコードが一つだけの広いプライベートゾーンは、そのゾーン配下のパブリックな依存関係を保ちません。依存関係を、レコードが一つだけのゾーンに置き換えてしまうからです。

クライアント層をプライベートビューに向ける前に、アプリケーションが実際に呼び出す名前を棚卸ししてください。ログインホスト、静的アセットのホスト、リダイレクト先、API エンドポイントが最初に壊れ、それらは通常、複数チームのレコードに散らばっています。

リゾルバの経路をたどり、次にルートをたどる

ノート PC がプライベートビューを見るのは、そのクエリが関連付けを持つリゾルバに届く場合だけです。VPN サーバーの hosts ファイルを編集しても接続中のクライアントには何も公開されず、パブリックリゾルバを設定したクライアントはトンネルが上がっている間ずっとパブリックな回答を受け取り続けます。クライアントが受け取ったリゾルバのアドレスを確認し、サーバーではなくクライアントからクエリを再実行してください。

名前が解決したら、返されたアドレスへの経路を別の手順として試します。たとえば ip route get を、クエリが返したアドレスに対して実行します。アドレスへの経路がない正しいプライベート応答はルーティングの問題であり、レコードがないという応答は DNS ビューの問題です。両者を一つの問題として扱うと、定着しない修正になります。サービスの TLS ホスト名と証明書の確認は変えないでください。プライベートアドレスは接続先を変えるだけで、どの証明書が有効かは変えないからです。

最後に、ゾーン、関連付け、リゾルバ、確認した名前を変更ノートに記録します。そうすれば、次にレコードを追加する人が、そのクライアント層にとってどの名前空間が権威なのかを知ることができます。

関連記事