1. はじめに
IPv6 への移行における主な課題の 1 つは、IPv4 専用のエンドポイントとネットワークへの到達可能性を維持することです。この課題に対処する主要なテクノロジーは、DNS64(RFC6147 で定義)を使用してクライアントの A レコードを AAAA レコードに変換し、NAT64(RFC6146 で定義)を使用して特別な形式の IPv6 アドレスを IPv4 に変換することです。この場合、IPv4 アドレスは特別な IPv6 アドレスに埋め込まれます。この Codelab では、Google Cloud Platform(GCP)Virtual Private Cloud(VPC)で両方の機能を構成する方法について説明します。両方を構成すると、GCP NAT64 と DNS64 により、IPv6 のみのインスタンスがインターネット上の IPv4 専用サーバーと通信できるようになります。
このラボでは、さまざまなタイプの IPv6 サブネットとインスタンス(IPv6 のみの GUA(グローバル ユニキャスト アドレス)、IPv6 のみの ULA(一意のローカル アドレス)、デュアルスタック ULA)を使用して VPC を設定します。次に、Google Cloud のマネージド DNS64 サービスと NAT64 サービスを構成してテストし、それらから IPv4 専用ウェブサイトにアクセスします。
2. 学習内容
- IPv6 のみのサブネットとインスタンスを作成する方法
- VPC で Google Cloud のマネージド DNS64 サービスを有効にする方法。
- NAT64 用に構成された Google Cloud NAT ゲートウェイを作成する方法。
- IPv6 のみのインスタンスから IPv4 専用の宛先への DNS64 解決をテストする方法。
- シングルスタック インスタンスとデュアルスタック インスタンスで DNS64 と NAT64 の動作がどのように異なるか。
- NAT64 用に NAT ゲートウェイを構成する方法。
- IPv6 のみのインスタンスから IPv4 専用の宛先への NAT64 接続をテストする方法。
3. 始める前に
Codelab をサポートするようにプロジェクトを更新する
この Codelab では、$variables を使用して、Cloud Shell で gcloud 構成の実装を支援します。
Cloud Shell で、次の操作を行います。
gcloud config list project
gcloud config set project [YOUR-PROJECT-ID]
export projectname=$(gcloud config list --format="value(core.project)")
export zonename=[COMPUTE ZONE NAME]
export regionname=[REGION NAME]
ラボの全体的なアーキテクチャ

NAT64 と DNS64 がさまざまな IPv6 サブネット タイプとどのように連携するかを示すために、GUA と ULA の両方のフレーバーで IPv6 サブネットを持つ単一の VPC を作成します。また、デュアルスタック VM に DNS64 と NAT64 が適用されないことを示すために、デュアルスタック サブネット(ULA アドレス指定を使用)も作成します。
次に、DNS64 と NAT64 を構成し、インターネット上の IPv6 宛先と IPv4 宛先への接続をテストします。
4. 準備手順
まず、Google Cloud プロジェクトに必要なサービス アカウント、IAM、ネットワーク インフラストラクチャ、インスタンスを設定します。
サービス アカウントと IAM バインディングを作成する
まず、gcloud を使用してインスタンスが相互に SSH 接続できるように、新しいサービス アカウントを作成します。GUA IPv6 のみのインスタンスにアクセスするために IAP を使用できず、cloudshell ではまだ IPv6 への直接アクセスが許可されていないため、この機能が必要になります。cloudshell で次のコマンドを実行します。
gcloud iam service-accounts create ipv6-codelab \
--description="temporary service account for a codelab" \
--display-name="ipv6codelabSA" \
--project $projectname
gcloud projects add-iam-policy-binding $projectname \
--member=serviceAccount:ipv6-codelab@$projectname.iam.gserviceaccount.com \
--role=roles/compute.instanceAdmin.v1
gcloud iam service-accounts add-iam-policy-binding \
ipv6-codelab@$projectname.iam.gserviceaccount.com \
--member=serviceAccount:ipv6-codelab@$projectname.iam.gserviceaccount.com \
--role=roles/iam.serviceAccountUser
VPC を作成して ULA を有効にする
cloudshell で次のコマンドを実行して、カスタム サブネット モードと ULA 内部 IPv6 が有効になっている VPC ネットワークを作成します。
gcloud compute networks create ipv6-only-vpc \
--project=$projectname \
--subnet-mode=custom \
--mtu=1500 --bgp-routing-mode=global \
--enable-ula-internal-ipv6
ファイアウォール ルールの作成
SSH アクセスを許可するファイアウォール ルールを作成します。1 つのルールでは、ULA 範囲全体(fd20::/20)からの SSH が許可されます。さらに 2 つのルールでは、IAP の事前定義された IPv6 範囲と IPv4 範囲(それぞれ 2600:2d00:1:7::/64、35.235.240.0/20)からのトラフィックが許可されます。
cloudshell で次のコマンドを実行します。
gcloud compute firewall-rules create allow-v6-ssh-ula \
--direction=INGRESS --priority=200 \
--network=ipv6-only-vpc --action=ALLOW \
--rules=tcp:22 --source-ranges=fd20::/20 \
--project=$projectname
gcloud compute firewall-rules create allow-v6-iap \
--direction=INGRESS --priority=300 \
--network=ipv6-only-vpc --action=ALLOW \
--rules=tcp --source-ranges=2600:2d00:1:7::/64 \
--project=$projectname
gcloud compute firewall-rules create allow-v4-iap \
--direction=INGRESS --priority=300 \
--network=ipv6-only-vpc --action=ALLOW \
--rules=tcp --source-ranges=35.235.240.0/20 \
--project=$projectname
サブネットを作成する
GUA v6 のみのサブネット、ULA v6 のみのサブネット、デュアルスタック ULA サブネットを作成します。cloudshell で次のコマンドを実行します。
gcloud compute networks subnets create gua-v6only-subnet \
--network=ipv6-only-vpc \
--project=$projectname \
--stack-type=IPV6_ONLY \
--ipv6-access-type=external \
--region=$regionname
gcloud compute networks subnets create ula-v6only-subnet \
--network=ipv6-only-vpc \
--project=$projectname \
--stack-type=IPV6_ONLY \
--ipv6-access-type=internal \
--enable-private-ip-google-access \
--region=$regionname
gcloud compute networks subnets create ula-dualstack-subnet \
--network=ipv6-only-vpc \
--project=$projectname \
--stack-type=IPV4_IPV6 \
--range=10.120.0.0/16 \
--ipv6-access-type=internal \
--region=$regionname
インスタンスの作成
作成した各サブネットにインスタンスを作成します。IPv6 のみの ULA インスタンスは cloud-platform で指定されています。これにより、GUA IPv6 のみのインスタンスへのジャンプボックスとして使用できます。cloudshell で次のコマンドを実行します。
gcloud compute instances create gua-instance \
--subnet gua-v6only-subnet \
--stack-type IPV6_ONLY \
--zone $zonename \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--service-account=ipv6-codelab@$projectname.iam.gserviceaccount.com \
--project=$projectname
gcloud compute instances create ula-instance \
--subnet ula-v6only-subnet \
--stack-type IPV6_ONLY \
--zone $zonename \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--service-account=ipv6-codelab@$projectname.iam.gserviceaccount.com \
--project=$projectname
gcloud compute instances create dualstack-ula-instance \
--subnet ula-dualstack-subnet \
--stack-type IPV4_IPV6 \
--zone $zonename \
--project=$projectname
初期インスタンスのアクセスと設定
デフォルトで IAP を使用する ULA インスタンスに SSH 接続します。cloudshell で次のコマンドを使用して、ULA インスタンスに SSH 接続します。
gcloud compute ssh ula-instance --project $projectname --zone $zonename
<username>@ula-instance:~$
また、ULA インスタンスを GUA インスタンスのジャンプボックスとして使用します(IAP は GUA インスタンスでは機能せず、Cloudshell VM は IPv6 宛先にアクセスできないため)。
ULA インスタンス シェル内で、次の gcloud コマンドを使用して GUA インスタンスに SSH 接続を試みます。
インスタンス内で SSH コマンドを初めて実行すると、SSH 鍵ペアの設定を求めるプロンプトが表示されます。鍵が作成されて SSH コマンドが実行されるまで Enter キーを押し続けます。これにより、パスフレーズなしで新しい鍵ペアが作成されます。
ula-instance:~$ gcloud compute ssh gua-instance
WARNING: The private SSH key file for gcloud does not exist.
WARNING: The public SSH key file for gcloud does not exist.
WARNING: You do not have an SSH key for gcloud.
WARNING: SSH keygen will be executed to generate a key.
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/galhabian/.ssh/google_compute_engine
Your public key has been saved in /home/galhabian/.ssh/google_compute_engine.pub
The key fingerprint is:
SHA256:5PYzydjcpWYiFtzetYCBI6vmy9dqyLsxgDORkB9ynqY galhabian@ula-instance
The key's randomart image is:
+---[RSA 3072]----+
|.. |
|+.o . |
|o= o . + . |
| o= * o o |
|+o. . S o . o |
|Eo . . . O + = . |
| .=. .+ @ * . |
| +ooo... * |
| **.. |
+----[SHA256]-----+
成功すると、SSH コマンドが成功し、GUA インスタンスに SSH 接続されます。
Updating instance ssh metadata...done.
Waiting for SSH key to propagate.
Warning: Permanently added 'compute.3639038240056074485' (ED25519) to the list of known hosts.
Linux gua-instance 6.1.0-34-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.135-1 (2025-04-25) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
<username>@gua-instance:~$
5. IPv6 のみのインスタンスを確認する。
両方の IPv6 のみのインスタンスに SSH 接続してルーティング テーブルを確認し、両方のインスタンスを調べます。
GUA インスタンスを確認する
まず「ula-instance」インスタンスを介してジャンプし、「gua-instance」に SSH 接続します。
gcloud compute ssh ula-instance --project $projectname --zone $zonename
<username>@ula-instance:~$ gcloud compute ssh gua-instance
次のコマンドを使用して、インスタンスの IPv6 ルーティング テーブルを確認します。
<username>@gua-instance:~$ ip -6 route
2600:1900:4041:461::/65 via fe80::56:11ff:fef9:88c1 dev ens4 proto ra metric 100 expires 81sec pref medium
fe80::/64 dev ens4 proto kernel metric 256 pref medium
default via fe80::56:11ff:fef9:88c1 dev ens4 proto ra metric 100 expires 81sec mtu 1500 pref medium
ルーティング テーブルに 3 つのエントリがあります。
- インスタンスが属する GUA サブネットの /65 ルート。デフォルト ゲートウェイのリンクローカル アドレスを使用して派生したネクストホップを使用します。上位の /65 は IPv6 パススルー ネットワーク ロードバランサ用に予約されています。
- リンクローカル ユニキャスト プレフィックス fe80::/64 の組み込み /64 ルート
- サブネットのデフォルト ゲートウェイのリンクローカル アドレスを指すデフォルト ルート。
次のコマンドを実行して、IPv4 ルーティング テーブルを確認します。
<username>@gua-instance:~$ ip -4 route
default via 169.254.1.1 dev ens4 proto dhcp src 169.254.1.2 metric 100
169.254.1.1 dev ens4 proto dhcp scope link src 169.254.1.2 metric 100
169.254.169.254 via 169.254.1.1 dev ens4 proto dhcp src 169.254.1.2 metric 100
驚きましたか?実際には、IPv6 のみのインスタンスで IPv4 ルーティング テーブルを維持し、Compute Metadata サーバー (169.254.169.154)へのアクセスを厳密に許可しています。これは、Compute Metadata サーバーがまだ IPv4 専用のエンドポイントであるためです。
インスタンスは IPv6 のみのインスタンスの場合、IP 169.254.1.2 を使用します。この IP は Compute Metadata サーバー以外にはルーティングできないため、インスタンスはすべての IPv4 ネットワークから効果的に分離されます。
curl テスト
curl を使用して、v4 のみと v6 のみのウェブサイトへの実際の接続をテストします。
<username>@gua-instance:~$ curl -vv --connect-timeout 10 v6.ipv6test.app
<username>@gua-instance:~$ curl -vv --connect-timeout 10 v4.ipv6test.app
以下は出力例です。
<username>@gua-instance:~$ curl -vv --connect-timeout 10 v6.ipv6test.app
* Trying [2600:9000:20be:cc00:9:ec55:a1c0:93a1]:80...
* Connected to v6.ipv6test.app (2600:9000:20be:cc00:9:ec55:a1c0:93a1) port 80 (#0)
> GET / HTTP/1.1
> Host: v6.ipv6test.app
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
!! Rest of output truncated
<username>@gua-instance:~$ curl -vv --connect-timeout 10 v4.ipv6test.app
* Trying 3.163.165.4:80...
* ipv4 connect timeout after 4985ms, move on!
* Trying 3.163.165.50:80...
* ipv4 connect timeout after 2492ms, move on!
* Trying 3.163.165.127:80...
* ipv4 connect timeout after 1246ms, move on!
* Trying 3.163.165.37:80...
* ipv4 connect timeout after 1245ms, move on!
* Failed to connect to v4.ipv6test.app port 80 after 10000 ms: Timeout was reached
* Closing connection 0
curl: (28) Failed to connect to v4.ipv6test.app port 80 after 10000 ms: Timeout was reached
予想どおり、IPv6 のみのインスタンスから IPv4 インターネット エンドポイントへのネットワーク到達性はありません。DNS64 と NAT64 をプロビジョニングしないと、IPv6 のみのインスタンスには IPv4 宛先へのパスがありません。インスタンスに GUA IPv6 アドレスがあるため、IPv6 宛先へのネットワーク到達性は正常に機能します。
ULA インスタンスを確認する
「ula-instance」インスタンスに SSH 接続します(デフォルトで IAP を使用します)。
gcloud compute ssh ula-instance --project $projectname --zone $zonename
次のコマンドを使用して、インスタンスの IPv6 ルーティング テーブルを確認します。
<username>@ula-instance:~$ ip -6 route
fd20:f06:2e5e:2000::/64 via fe80::55:82ff:fe6b:1d7 dev ens4 proto ra metric 100 expires 84sec pref medium
fe80::/64 dev ens4 proto kernel metric 256 pref medium
default via fe80::55:82ff:fe6b:1d7 dev ens4 proto ra metric 100 expires 84sec mtu 1500 pref medium
ルーティング テーブルに 3 つのエントリがあります。GUA インスタンスと同様ですが、マスクが /65 ではなく /64 である点が異なります。また、サブネット ルートは ULA 範囲に属します。(fd20::/20 集約の下)
次のコマンドを実行して、IPv4 ルーティング テーブルを確認します。
<username>@ula-instance:~$ ip -4 route
default via 169.254.1.1 dev ens4 proto dhcp src 169.254.1.2 metric 100
169.254.1.1 dev ens4 proto dhcp scope link src 169.254.1.2 metric 100
169.254.169.254 via 169.254.1.1 dev ens4 proto dhcp src 169.254.1.2 metric 100
GUA インスタンスと同様の状況を示しています。
curl テスト
curl を使用して、v4 のみと v6 のみのウェブサイトへの接続テストを繰り返します。
<username>@ula-instance:~$ curl -vv --connect-timeout 10 v6.ipv6test.app
<username>@ula-instance:~$ curl -vv --connect-timeout 10 v4.ipv6test.app
以下は出力例です。
<username>@ula-instance:~$ curl -vv --connect-timeout 10 v6.ipv6test.app
* Trying [2600:9000:20be:8400:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 4986ms, move on!
* Trying [2600:9000:20be:9000:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 2493ms, move on!
* Trying [2600:9000:20be:d600:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 1246ms, move on!
* Trying [2600:9000:20be:b000:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 622ms, move on!
* Trying [2600:9000:20be:7200:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 312ms, move on!
* Trying [2600:9000:20be:8600:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 155ms, move on!
* Trying [2600:9000:20be:7a00:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 77ms, move on!
* Trying [2600:9000:20be:ce00:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 77ms, move on!
* Failed to connect to v6.ipv6test.app port 80 after 10000 ms: Timeout was reached
* Closing connection 0
<username>@ula-instance:~$ curl -vv --connect-timeout 10 v4.ipv6test.app
* Trying 3.163.165.4:80...
* ipv4 connect timeout after 4985ms, move on!
* Trying 3.163.165.50:80...
* ipv4 connect timeout after 2492ms, move on!
* Trying 3.163.165.127:80...
* ipv4 connect timeout after 1246ms, move on!
* Trying 3.163.165.37:80...
* ipv4 connect timeout after 1245ms, move on!
* Failed to connect to v4.ipv6test.app port 80 after 10000 ms: Timeout was reached
* Closing connection 0
curl: (28) Failed to connect to v4.ipv6test.app port 80 after 10000 ms: Timeout was reached
ULA インスタンスの場合、IPv6 エンドポイントでは ULA アドレスを使用して通信できないため、両方のインターネット エンドポイントにネットワーク到達性がありません。また、インスタンスは IPv6 のみのインスタンスであるため、IPv4 にネットワーク到達性がありません。
6. NAT64 と DNS64 を有効にする
VPC のマネージド DNS64 サービスと NAT64 サービスを構成します。
DNS64
VPC の DNS64 サーバー ポリシーを有効にします。これにより、VPC の DNS リゾルバは A のみのレスポンスに対して AAAA レコードを合成します。cloudshell で次のコマンドを実行します。
gcloud beta dns policies create allow-dns64 \
--description="Enable DNS64 Policy" \
--networks=ipv6-only-vpc \
--enable-dns64-all-queries \
--project $projectname
NAT64
Cloud Router を作成します。これは Cloud NAT に必要です。次に、NAT64 用に構成された Cloud NAT ゲートウェイを作成し、すべての IPv6 のみのサブネット IP 範囲で有効にして、外部 IP を自動的に割り振ります。cloudshell で次のコマンドを実行します。
gcloud compute routers create nat64-router \
--network=ipv6-only-vpc \
--region=$regionname \
--project=$projectname
gcloud beta compute routers nats create nat64-natgw \
--router=nat64-router \
--region=$regionname \
--auto-allocate-nat-external-ips \
--nat64-all-v6-subnet-ip-ranges \
--project=$projectname
7. NAT64 と DNS64 をテストする
次に、IPv6 のみのインスタンスから NAT64 と DNS64 の構成をテストします。まず GUA インスタンスから、次に ULA インスタンスからテストします。
GUA インスタンスから DNS64/NAT64 をテストする
まず「ula-instance」インスタンスを介してジャンプし、「gua-instance」に SSH 接続します。
gcloud compute ssh ula-instance --project $projectname --zone $zonename
<username>@ula-instance:~$ gcloud compute ssh gua-instance
DNS テスト
<username>@gua-instance:~$ host -t AAAA v6.ipv6test.app
<username>@gua-instance:~$ host -t A v6.ipv6test.app
IPv6 AAAA の回答のみが返されることが予想されます。
出力例
<username>@gua-instance:~$ host -t AAAA v6.ipv6test.app
v6.ipv6test.app has IPv6 address 2600:9000:269f:1000:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:6600:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:b600:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:3e00:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:9c00:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:b200:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:a600:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:1400:9:ec55:a1c0:93a1
<username>@gua-instance:~$ host -t A v6.ipv6test.app
v6.ipv6test.app has no A record
IPv4 のみのウェブサイト(v4.ipv6test.app など)の DNS の解決をテストします。A レコード(元の IPv4)と、ウェルノウン プレフィックス 64:ff9b::/96 を使用して DNS64 によって合成された AAAA レコードの両方が返されることが予想されます。
<username>@gua-instance:~$ host -t AAAA v4.ipv6test.app
<username>@gua-instance:~$ host -t A v4.ipv6test.app
出力例
<username>@gua-instance:~$ host -t AAAA v4.ipv6test.app
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:3318
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:3344
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:333c
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:3326
<username>@gua-instance:~$ host -t A v4.ipv6test.app
v4.ipv6test.app has address 54.192.51.68
v4.ipv6test.app has address 54.192.51.24
v4.ipv6test.app has address 54.192.51.60
v4.ipv6test.app has address 54.192.51.38
上記の例では、IPv4 アドレス(54.192.51.38)を 10 進数から 16 進数に変換すると(36 c0 33 26)になります。したがって、AAAA レコードの回答は(64:ff9b::36c0:3326)になることが予想されます。これは、受信した AAAA 回答の 1 つと一致します。
curl テスト
IPv6 経由で curl を使用して、同じ v4 のみと v6 のみのエンドポイントへの実際の接続をテストします。
<username>@gua-instance:~$ curl -vv -6 v6.ipv6test.app
<username>@gua-instance:~$ curl -vv -6 v4.ipv6test.app
以下は出力例です。
<username>@gua-instance:~$ curl -vv -6 v6.ipv6test.app
* Trying [2600:9000:269f:1000:9:ec55:a1c0:93a1]:80...
* Connected to v6.ipv6test.app (2600:9000:269f:1000:9:ec55:a1c0:93a1) port 80 (#0)
> GET / HTTP/1.1
##
## <Output truncated for brevity>
##
<username>@gua-instance:~$ curl -vv -6 v4.ipv6test.app
* Trying [64:ff9b::36c0:333c]:80...
* Connected to v4.ipv6test.app (64:ff9b::36c0:333c) port 80 (#0)
> GET / HTTP/1.1
##
## <Output truncated for brevity>
##
両方の curl コマンドが成功します。NAT64 と DNS64 が連携して接続を正常に有効にしたため、IPv6 経由で IPv4 のみのウェブサイトに接続できました。
送信元 IP を確認する
IP リフレクション サービスを使用して、宛先 で確認された送信元 IP を確認します。
<username>@gua-instance:~$ curl -6 v4.ipv6test.app
<username>@gua-instance:~$ curl -6 v6.ipv6test.app
出力例
<username>@gua-instance:~$ curl -6 v4.ipv6test.app
34.47.60.91
<username>@gua-instance:~$ curl -6 v6.ipv6test.app
2600:1900:40e0:6f:0:1::
報告された IPv6 アドレスは、インスタンスの IPv6 アドレス と一致する必要があります。このアドレスは、インスタンスの「ip -6 address」コマンドの出力と一致する必要があります。例
<username>@gua-instance:~$ ip -6 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 2600:1900:40e0:6f:0:1::/128 scope global dynamic noprefixroute
valid_lft 79912sec preferred_lft 79912sec
inet6 fe80::86:d9ff:fe34:27ed/64 scope link
valid_lft forever preferred_lft forever
報告された IPv4 アドレスは、インターネットに送信する前に NAT64 関数を実行するため、Cloud NAT ゲートウェイの外部 IP アドレスと一致する必要があります。これは、cloudshell で次の gcloud コマンドを実行して確認できます。
gcloud compute routers get-nat-ip-info \
nat64-router \
--region=$regionname
出力例
result:
- natIpInfoMappings:
- mode: AUTO
natIp: 34.47.60.91
usage: IN_USE
natName: nat64-natgw
出力に報告された「natIp」は、IP リフレクション ウェブサイトから受信した出力と一致します。
ULA インスタンスから DNS64/NAT64 をテストする
まず、ULA インスタンス「ula-instance」に SSH 接続します。
gcloud compute ssh ula-instance --project $projectname --zone $zonename
<username>@ula-instance:~$
DNS テスト
<username>@ula-instance:~$ host -t AAAA v6.ipv6test.app
<username>@ula-instance:~$ host -t A v6.ipv6test.app
IPv6 AAAA の回答のみが返されることが予想されます。
出力例
<username>@ula-instance:~$ host -t AAAA v6.ipv6test.app
v6.ipv6test.app has IPv6 address 2600:9000:269f:1000:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:6600:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:b600:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:3e00:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:9c00:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:b200:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:a600:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:1400:9:ec55:a1c0:93a1
<username>@ula-instance:~$ host -t A v6.ipv6test.app
v6.ipv6test.app has no A record
IPv4 のみのウェブサイト(v4.ipv6test.app など)の DNS の解決をテストします。A レコード(元の IPv4)と、ウェルノウン プレフィックス 64:ff9b::/96 を使用して DNS64 によって合成された AAAA レコードの両方が返されることが予想されます。
<username>@ula-instance:~$ host -t AAAA v4.ipv6test.app
<username>@ula-instance:~$ host -t A v4.ipv6test.app
出力例
<username>@gua-instance:~$ host -t AAAA v4.ipv6test.app
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:3318
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:3344
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:333c
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:3326
<username>@gua-instance:~$ host -t A v4.ipv6test.app
v4.ipv6test.app has address 54.192.51.68
v4.ipv6test.app has address 54.192.51.24
v4.ipv6test.app has address 54.192.51.60
v4.ipv6test.app has address 54.192.51.38
上記の例では、IPv4 アドレス(54.192.51.38)を 10 進数から 16 進数に変換すると(36 c0 33 26)になります。したがって、AAAA レコードの回答は(64:ff9b::36c0:3326)になることが予想されます。これは、受信した AAAA 回答の 1 つと一致します。
curl テスト
curl を使用して、同じ v4 のみと v6 のみのエンドポイントへの実際の接続をテストします。
まず、インスタンスが IPv6 のみのインスタンスであるため、IPv4 経由でのネットワーク到達性がないことを示します。
<username>@ula-instance:~$ curl -vv -4 --connect-timeout 10 v6.ipv6test.app
<username>@ula-instance:~$ curl -vv -4 --connect-timeout 10 v4.ipv6test.app
両方の curl が失敗します。失敗する理由は異なります。以下は出力例です。
<username>@ula-instance:~$ curl -vv -4 v6.ipv6test.app
* Could not resolve host: v6.ipv6test.app
* Closing connection 0
curl: (6) Could not resolve host: v6.ipv6test.app
<username>@ula-instance:~$ curl -vv -4 --connect-timeout 10 v4.ipv6test.app
* Trying 54.192.51.68:80...
* ipv4 connect timeout after 4993ms, move on!
* Trying 54.192.51.38:80...
* ipv4 connect timeout after 2496ms, move on!
* Trying 54.192.51.24:80...
* ipv4 connect timeout after 1248ms, move on!
* Trying 54.192.51.60:80...
* Connection timeout after 10000 ms
* Closing connection 0
curl: (28) Connection timeout after 10000 ms
IPv6 のみのエンドポイントへの IPv4 curl は、A レコードの DNS の解決が失敗するため失敗します(DNS テストで説明したとおり)。IPv4 のみのエンドポイントへの IPv4 curl は、IPv6 のみのインスタンスが IPv4 アドレスに到達できないため失敗し、タイムアウトが発生します。
次に、IPv6 経由の到達可能性をテストします。
<username>@ula-instance:~$ curl -vv -6 v6.ipv6test.app
<username>@ula-instance:~$ curl -vv -6 v4.ipv6test.app
以下は出力例です。
<username>@ula-instance:~$ curl -vv -6 v6.ipv6test.app
* Trying [2600:9000:20be:c000:9:ec55:a1c0:93a1]:80...
* connect to 2600:9000:20be:c000:9:ec55:a1c0:93a1 port 80 failed: Connection timed out
* Trying [2600:9000:20be:f000:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 84507ms, move on!
* Trying [2600:9000:20be:ae00:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 42253ms, move on!
* Trying [2600:9000:20be:2000:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 21126ms, move on!
* Trying [2600:9000:20be:b600:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 10563ms, move on!
* Trying [2600:9000:20be:7600:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 5282ms, move on!
* Trying [2600:9000:20be:b000:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 2640ms, move on!
* Trying [2600:9000:20be:3400:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 2642ms, move on!
* Failed to connect to v6.ipv6test.app port 80 after 300361 ms: Timeout was reached
* Closing connection 0
<username>@ula-instance:~$ curl -vv -6 v4.ipv6test.app
* Trying [64:ff9b::36c0:333c]:80...
* Connected to v4.ipv6test.app (64:ff9b::36c0:333c) port 80 (#0)
> GET / HTTP/1.1
##
## <Output truncated for brevity>
##
ULA サブネットはインターネットに直接到達できないため、IPv6 のみのウェブサイトへの curl は失敗します。IPv4 のみのウェブサイトへの curl は成功します。これは、DNS64 と NAT64 が GUA インスタンスと ULA インスタンスで同じように動作するためです。インスタンスが IPv6 のみであることが唯一の要件です。
デュアルスタック ULA インスタンスから DNS64/NAT64 をテストする
まず、デュアルスタック ULA インスタンス「dualstack-ula-instance」に SSH 接続します。IAP に IPv4 アドレスを使用するように gcloud に強制するには、「--tunnel-through-iap」フラグを使用する必要があります。
gcloud compute ssh dualstack-ula-instance --project $projectname --zone $zonename --tunnel-through-iap
<username>@dualstack-ula-instance:~$
「host」ユーティリティを使用して DNS64 をテストします。
<username>@dualstack-ula-instance:~$ host v4.ipv6test.app
v4.ipv6test.app has address 54.192.51.38
v4.ipv6test.app has address 54.192.51.24
v4.ipv6test.app has address 54.192.51.68
v4.ipv6test.app has address 54.192.51.60
<username>@dualstack-ula-instance:~$ host v6.ipv6test.app
v6.ipv6test.app has IPv6 address 2600:9000:269f:fc00:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:1c00:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:a200:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:8a00:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:c800:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:c200:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:5800:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:dc00:9:ec55:a1c0:93a1
IPv4 のみのウェブサイトが、合成された DNS64 の回答ではなく、IPv4 アドレスのみを返すようになりました。これは、DNS64 が IPv6 のみのインスタンスにのみ適用され、デュアルスタック インスタンスでは評価されないためです。
DNS64 をバイパスするには、/etc/hosts ファイルにエントリを追加して、NAT64 が機能するかどうかをテストします。デュアルスタック インスタンス内で次のコマンドを実行します。
<username>@dualstack-ula-instance:~$ echo '64:ff9b::36c0:3326 v4.ipv6test.app' | sudo tee -a /etc/hosts
次に、curl を使用して IPv6 経由で ipv4 ウェブサイトに到達できるかどうかをテストします。
<username>@dualstack-ula-instance:~$ curl -vv -6 --connect-timeout 10 v4.ipv6test.app
上記のコマンドの出力例を次に示します。
<username>@dualstack-ula-instance:~$ curl -vv -6 --connect-timeout 10 v4.ipv6test.app
* Trying [64:ff9b::36c0:3326]:80...
* ipv6 connect timeout after 10000ms, move on!
* Failed to connect to v4.ipv6test.app port 80 after 10001 ms: Timeout was reached
* Closing connection 0
curl: (28) Failed to connect to v4.ipv6test.app port 80 after 10001 ms: Timeout was reached
curl はタイムアウトします。これは、DNS64 と同様に、NAT64 を適用するにはインスタンスが IPv6 のみである必要があるためです。
NAT64 がデュアルスタック インスタンスに適用されていないことを確認するには、「get-nat-mapping」コマンドを使用して、NAT ゲートウェイが適用しているすべてのポート マッピングを一覧表示します。cloudshell で次のコマンドを実行します。
gcloud compute routers get-nat-mapping-info \
nat64-router --region $regionname \
--project $projectname
次のスニペットのような出力が表示されます。
---
instanceName: gua-instance
interfaceNatMappings:
- natIpPortRanges:
- 34.47.60.91:1024-1055
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
sourceAliasIpRange: ''
sourceVirtualIp: '2600:1900:40e0:6f:0:1::'
- natIpPortRanges:
- 34.47.60.91:32768-32799
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
sourceAliasIpRange: ''
sourceVirtualIp: '2600:1900:40e0:6f:0:1::'
---
instanceName: ula-instance
interfaceNatMappings:
- natIpPortRanges:
- 34.47.60.91:1056-1087
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
sourceAliasIpRange: ''
sourceVirtualIp: fd20:9c2:93fc:2800:0:0:0:0
- natIpPortRanges:
- 34.47.60.91:32800-32831
numTotalDrainNatPorts: 0
numTotalNatPorts: 32
sourceAliasIpRange: ''
sourceVirtualIp: fd20:9c2:93fc:2800:0:0:0:0
NAT の出力は、NAT64 ゲートウェイがデュアルスタック インスタンスではなく、IPv6 のみの GUA インスタンスと ULA インスタンスにのみポートを割り振ったことを示しています。
8. クリーンアップ
Cloud Router をクリーンアップする
Cloud Shell で、次の操作を行います。
gcloud compute routers delete nat64-router \
--region $regionname \
--project $projectname --quiet
DNS ポリシーのバインドを解除してクリーンアップする
Cloud Shell で、次の操作を行います。
gcloud beta dns policies update allow-dns64 \
--networks="" \
--project $projectname
gcloud beta dns policies delete allow-dns64 \
--project $projectname --quiet
インスタンスをクリーンアップする
Cloud Shell で次の操作を行います(gcloud beta を使用すると、no-graceful-shutdown フラグを使用してインスタンスの削除オペレーションを高速化できます)。
gcloud beta compute instances delete gua-instance \
--zone $zonename \
--no-graceful-shutdown \
--project=$projectname --quiet
gcloud beta compute instances delete ula-instance \
--zone $zonename \
--no-graceful-shutdown \
--project=$projectname --quiet
gcloud beta compute instances delete dualstack-ula-instance \
--zone $zonename \
--no-graceful-shutdown \
--project=$projectname --quiet
サブネットをクリーンアップする
Cloud Shell で、次の操作を行います。
gcloud compute networks subnets delete gua-v6only-subnet \
--project=$projectname --quiet \
--region=$regionname
gcloud compute networks subnets delete ula-v6only-subnet \
--project=$projectname --quiet \
--region=$regionname
gcloud compute networks subnets delete ula-dualstack-subnet \
--project=$projectname --quiet \
--region=$regionname
ファイアウォール ルールをクリーンアップする
Cloud Shell で、次の操作を行います。
gcloud compute firewall-rules delete allow-v6-iap \
--project=$projectname \
--quiet
gcloud compute firewall-rules delete allow-v6-ssh-ula \
--project=$projectname \
--quiet
gcloud compute firewall-rules delete allow-v4-iap \
--project=$projectname \
--quiet
VPC をクリーンアップする
Cloud Shell で、次の操作を行います。
gcloud compute networks delete ipv6-only-vpc \
--project=$projectname \
--quiet
IAM 権限とサービス アカウントをクリーンアップする
Cloud Shell で、次の操作を行います。
gcloud projects remove-iam-policy-binding $projectname \
--member=serviceAccount:ipv6-codelab@$projectname.iam.gserviceaccount.com \
--role=roles/compute.instanceAdmin.v1
gcloud iam service-accounts delete \
ipv6-codelab@$projectname.iam.gserviceaccount.com \
--quiet \
--project $projectname
9. 完了
NAT64 と DNS64 を使用して、IPv6 のみのインスタンスがインターネット上の IPv4 専用の宛先に到達できるようにしました。
次のステップ
以下の Codelab をご覧ください。
- IPv6 アドレスを使用してオンプレミス ホストから Google API にアクセスする
- IP アドレス指定オプション IPv4 と IPv6
- IPv6 静的ルートのネクストホップ インスタンス、ネクストホップ アドレス、ネクストホップ ゲートウェイを使用する