IPv6オンリー環境で「IPv4の壁」をどう越えるか?NAT64/DNS64の現場的実装ガイド
クラウドネイティブなインフラを構築していると、最近は「IPv6 Only」という要件に直面することが増えてきました。AWSのVPCやGCPのVPCでも、IPv6はもはや標準機能です。しかし、世の中のすべてのWeb APIがIPv6に対応しているわけではありません。
「社内のプライベートサブネットにあるIPv6専用サーバーから、どうしてもIPv4限定の外部レガシーAPIを叩かなければならない」。
そんな時、我々SREが頼るのが NAT64 と DNS64 です。今回は、教科書を閉じて、実際のパケットがどのように変換され、地雷を踏まずに通信を確立するか、現場の視点で深掘りします。
—
なぜNAT64とDNS64が必要なのか?
IPv4とIPv6は、いわば「日本語しか話せない人」と「英語しか話せない人」のような関係です。通信するには「通訳」が必要です。
- DNS64: IPv4しか持たないドメイン(例:
api.example.com)に対して、IPv6アドレスしか持たないクライアントから問い合わせが来た際、そのIPv4アドレスを「IPv6で表現可能な擬似アドレス(合成アドレス)」に変換して返すサーバーです。 - NAT64: DNS64が生成したその「擬似アドレス」宛てに送られてきたパケットを、IPv4パケットに変換してインターネットへ送り出し、戻ってきたパケットを再度IPv6に戻すルーターです。
この二つが揃って初めて、IPv6インスタンスは「世界がIPv6化された」と錯覚しながら通信を行えるのです。
—
通信の裏側:パケットの冒険
クライアントから api.example.com へリクエストを投げる際のシーケンスは、以下のようになります。
1. DNSクエリ: クライアントがDNS64サーバーに AAAA レコード(IPv6アドレス)を問い合わせる。
2. DNS64の魔法: サーバーは該当ドメインの A レコード(IPv4)を引く。その後、自身のプレフィックス(例: 64:ff9b::/96)を使ってIPv4アドレスを埋め込み、合成されたIPv6アドレスをクライアントに返す。
3. パケット送信: クライアントは、受け取った 64:ff9b::1.2.3.4(実際のアドレス)宛てにIPv6パケットを送出。
4. NAT64の変換: NAT64ゲートウェイがこれを受け取り、末尾の 1.2.3.4 を抽出して、送信元を自身のIPv4アドレスに書き換え、IPv4インターネットへ送出。
この「プレフィックス」の設計こそが、ネットワーク設計の肝です。
—
実務的な実装のポイント
1. DNSサーバーの設定(例: BIND9)
BINDをDNS64サーバーとして使う場合、named.conf に以下のような設定を入れます。
options {
// IPv4のみのサイトをIPv6で見せるための設定
dns64 64:ff9b::/96 {
clients { localhost; 10.0.0.0/16; }; // 許可するクライアント
exclude { 64:ff9b::/96; };
};
};
ここで指定している 64:ff9b::/96 は「Well-Known Prefix」と呼ばれ、RFC 6052で定義された標準値です。特別な理由がない限り、これを使うのがトラブルを避ける鉄則です。
2. Pythonでの疎通確認コード
クライアント側での実装は、基本的に意識する必要はありません。ただし、デバッグ時には「IPv6で接続できているか」を明示的に確認しましょう。
import socket
import urllib.request
# DNS64経由であれば、IPv4アドレスもIPv6形式で解決される
url = "http://api.example.com"
try:
# 接続を試みる
with urllib.request.urlopen(url, timeout=5) as response:
print(f"ステータスコード: {response.getcode()}")
# 接続先の詳細を表示
print(f"ローカルアドレス: {response.fp._sock.getsockname()}")
except Exception as e:
# 接続失敗時はここを叩く
# DNS64が効いていないと、そもそも名前解決でエラーになることが多い
print(f"通信エラー: {e}")
—
現場のトラブルシューティングTips
ここからは、実際に私が現場で遭遇した「ハマりどころ」を共有します。
- MTU問題: IPv6ヘッダーはIPv4より大きいため、カプセル化や変換を繰り返すとMTUオーバーが発生しがちです。経路上のMTUを意識し、
MSS Clampingの設定を確認してください。 - DNS64の「空振り」:
Aレコードが存在するのにAAAAレコードが返ってこない場合、DNSサーバーの設定ミスか、アップストリームDNSがIPv4アドレスを隠蔽している可能性があります。dig @dns64-server api.example.com AAAAを叩いて、合成アドレスが返ってくるか確認しましょう。 - セキュリティグループ(SG): AWSなどでNAT64を利用する場合、SGは「IPv6の宛先」としてNAT64ゲートウェイを許可する必要があります。IPv4の宛先で許可を出していても、通信は通りません。 ここが最も多いミスです。
まとめ
NAT64/DNS64は、レガシーなIPv4資産と未来のIPv6インフラを繋ぐ「架け橋」です。一見複雑そうに見えますが、RFC 6052のプレフィックスルールと、DNS64の合成ロジックさえ理解していれば、恐れることはありません。
皆さんの環境でも、まずはテスト環境で 64:ff9b::/96 を使った疎通確認から始めてみてください。パケットがNAT64を通り抜け、無事に外部APIのレスポンスが返ってきた時の感動は、何度経験しても良いものです。
質問や、「うちはこんな変な構成でハマった!」というエピソードがあれば、ぜひコメントで教えてください。現場の知見を共有し合いましょう。
コメント