Tworzenie instancji maszyn wirtualnych obsługujących tylko adresy IPv6 i włączanie NAT64/DNS64

1. Wprowadzenie

Jednym z głównych wyzwań związanych z migracją do IPv6 jest utrzymanie dostępności punktów końcowych i sieci obsługujących tylko IPv4. Jedną z głównych technologii, która pomaga rozwiązać ten problem, jest połączenie DNS64 (zdefiniowanego w RFC6147) do tłumaczenia rekordów A na rekordy AAAA dla klientów z NAT64 (zdefiniowanym w RFC6146) do tłumaczenia specjalnie sformatowanych adresów IPv6 na IPv4, gdzie adres IPv4 jest osadzony w specjalnym adresie IPv6. W tym samouczku dowiesz się, jak skonfigurować obie te funkcje w prywatnym środowisku wirtualnym w chmurze (VPC) Google Cloud Platform (GCP). Gdy NAT64 i DNS64 w GCP są skonfigurowane razem, umożliwiają instancjom obsługującym tylko IPv6 komunikację z serwerami obsługującymi tylko IPv4 w internecie.

W tym module skonfigurujesz sieć VPC z różnymi typami podsieci i instancji IPv6 : IPv6-only GUA (Global Unicast Address), IPv6-only ULA (Unique Local Address) i ULA o podwójnym stosie. Następnie skonfigurujesz i przetestujesz zarządzane przez Google Cloud usługi DNS64 i NAT64, aby uzyskać z nich dostęp do witryn korzystających tylko z IPv4.

2. Czego się nauczysz

  • Tworzenie podsieci i instancji obsługujących tylko IPv6
  • Jak włączyć zarządzaną usługę DNS64 Google Cloud w sieci VPC .
  • Jak utworzyć bramę Cloud NAT w Google Cloud skonfigurowaną pod kątem NAT64 .
  • Jak przetestować rozpoznawanie DNS64 z instancji obsługujących tylko IPv6 do miejsc docelowych obsługujących tylko IPv4.
  • Jak zachowanie DNS64 i NAT64 różni się w przypadku instancji z jednym i dwoma stosami.
  • Jak skonfigurować bramę NAT dla NAT64.
  • Jak przetestować połączenie NAT64 z instancji obsługujących tylko IPv6 do miejsc docelowych obsługujących tylko IPv4.

3. Zanim zaczniesz

Aktualizowanie projektu pod kątem obsługi samouczka

W tym laboratorium wykorzystywane są zmienne, które ułatwiają wdrażanie konfiguracji gcloud w Cloud Shell.

W Cloud Shell wykonaj te czynności:

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]

Ogólna architektura modułu

63e4293e033da8d3.png

Aby zademonstrować, jak NAT64 i DNS64 współdziałają z różnymi typami podsieci IPv6, utworzysz jedną sieć VPC z podsieciami IPv6 w wersjach GUA i ULA. Utworzysz też podsieć z podwójnym stosem (z adresowaniem ULA), aby pokazać, że DNS64 i NAT64 nie mają zastosowania do maszyn wirtualnych z podwójnym stosem.

Następnie skonfigurujesz DNS64 i NAT64 oraz przetestujesz połączenia z miejscami docelowymi IPv6 i IPv4 w internecie.

4. Kroki przygotowawcze

Najpierw skonfiguruj w projekcie Google Cloud niezbędne konto usługi, IAM, infrastrukturę sieciową i instancje.

Tworzenie konta usługi i powiązań uprawnień

Zaczynamy od utworzenia nowego konta usługi, aby umożliwić instancjom łączenie się ze sobą przez SSH za pomocą gcloud. Będzie nam to potrzebne, ponieważ nie możemy używać IAP do uzyskiwania dostępu do instancji GUA obsługującej tylko IPv6, a Cloud Shell nie zezwala jeszcze na bezpośredni dostęp do IPv6. Uruchom w Cloud Shell te polecenia:

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

Tworzenie sieci VPC i włączanie ULA

Utwórz sieć VPC z niestandardowym trybem podsieci i włączonym wewnętrznym adresem IPv6 ULA, uruchamiając w Cloud Shell te polecenia:

gcloud compute networks create ipv6-only-vpc \
--project=$projectname \
--subnet-mode=custom \
--mtu=1500 --bgp-routing-mode=global \
--enable-ula-internal-ipv6

Utwórz reguły zapory sieciowej

Utwórz reguły zapory sieciowej, które zezwalają na dostęp SSH. Jedna reguła zezwala na SSH z całego zakresu ULA (fd20::/20). Dwie kolejne reguły zezwalają na ruch z predefiniowanych zakresów adresów IPv6 i IPv4 IAP (odpowiednio 2600:2d00:1:7::/64 i 35.235.240.0/20).

Uruchom w Cloud Shell te polecenia:

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 

Tworzenie podsieci

Utwórz podsieć obsługującą tylko adresy GUA v6, podsieć obsługującą tylko adresy ULA v6 i podsieć z podwójnym stosem ULA. Uruchom w Cloud Shell te polecenia:

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 

Tworzenie maszyn wirtualnych

Utwórz instancje w każdej z utworzonych przed chwilą podsieci. Instancja ULA tylko z IPv6 jest określona za pomocą platformy chmurowej, co pozwala nam używać jej jako serwera pośredniczącego do instancji GUA tylko z IPv6. Uruchom w Cloud Shell te polecenia:

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

Początkowy dostęp do instancji i jej konfiguracja

Połącz się przez SSH z instancją ULA, która domyślnie będzie korzystać z IAP. Aby nawiązać połączenie SSH z instancją ULA, użyj w Cloud Shell tego polecenia:

gcloud compute ssh ula-instance --project $projectname --zone $zonename

<username>@ula-instance:~$ 

Będziemy też używać instancji ULA jako serwera pośredniczącego dla instancji GUA (ponieważ IAP nie działa z instancjami GUA, a maszyny wirtualne Cloud Shell nie mają dostępu do miejsc docelowych IPv6).

Pozostając w powłoce instancji ULA. Spróbuj nawiązać połączenie SSH z instancją GUA za pomocą tego polecenia gcloud.

Gdy po raz pierwszy uruchomisz polecenie SSH w instancji, pojawi się prośba o skonfigurowanie pary kluczy SSH. Naciskaj klawisz Enter, aż klucz zostanie utworzony i wykonane zostanie polecenie SSH. Spowoduje to utworzenie nowej pary kluczy bez hasła.

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]-----+

Jeśli polecenie SSH zadziała, nawiążesz połączenie SSH z instancją GUA:

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. Sprawdź instancje tylko IPv6.

Przyjrzyjmy się obu instancjom tylko IPv6, łącząc się z nimi przez SSH i sprawdzając ich tablice routingu.

Sprawdzanie instancji GUA

Połącz się z instancją „gua-instance” przez SSH, najpierw przechodząc przez instancję „ula-instance”.

gcloud compute ssh ula-instance --project $projectname --zone $zonename
<username>@ula-instance:~$ gcloud compute ssh gua-instance

Sprawdźmy tabelę routingu IPv6 instancji za pomocą tego polecenia:

<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

W tabeli routingu widzimy 3 wpisy.

  1. Trasa /65 dla podsieci GUA, do której należy instancja, z wyprowadzonym następnym przeskokiem wykorzystującym adres lokalny połączenia dla domyślnej bramy. Pamiętaj, że górny zakres /65 jest zarezerwowany dla przekazujących sieciowych systemów równoważenia obciążenia IPv6.
  2. Wbudowana trasa /64 dla prefiksu typu link-local unicast fe80::/64
  3. Trasa domyślna wskazująca adres lokalny połączenia dla domyślnej bramy podsieci.

Przyjrzyjmy się tabeli routingu IPv4, wpisując to polecenie:

<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

Zaskoczenie? W przypadku instancji obsługujących tylko adresy IPv6 utrzymujemy tabelę routingu IPv4, aby umożliwić dostęp do serwera metadanych Compute (169.254.169.254), ponieważ jest to nadal punkt końcowy obsługujący tylko adresy IPv4.

Ponieważ instancja przyjmuje adres IP 169.254.1.2, gdy jest instancją tylko IPv6. Ten adres IP nie jest kierowany nigdzie poza serwer metadanych Compute, więc instancja jest skutecznie odizolowana od wszystkich sieci IPv4.

Testy loków

Sprawdźmy rzeczywistą łączność ze stronami internetowymi obsługującymi tylko protokół IPv4 i tylko protokół IPv6 za pomocą polecenia curl.

<username>@gua-instance:~$ curl -vv --connect-timeout 10 v6.ipv6test.app
<username>@gua-instance:~$ curl -vv --connect-timeout 10 v4.ipv6test.app

Poniżej znajdziesz przykładowe dane wyjściowe.

<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

Zgodnie z oczekiwaniami z instancji obsługującej tylko adresy IPv6 nie można uzyskać dostępu do punktu końcowego internetu IPv4. Bez udostępnienia DNS64 i NAT64 instancja obsługująca tylko IPv6 nie ma ścieżki do miejsca docelowego IPv4. Dostępność miejsca docelowego IPv6 działa normalnie, ponieważ instancja ma adres IPv6 GUA.

Sprawdzanie instancji ULA

Połącz się z instancją „ula-instance” przez SSH (domyślnie używa IAP).

gcloud compute ssh ula-instance --project $projectname --zone $zonename

Sprawdźmy tabelę routingu IPv6 instancji za pomocą tego polecenia:

<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

W tabeli routingu widzimy 3 wpisy podobne do tych w przypadku instancji GUA, z wyjątkiem maski, która ma wartość /64 zamiast /65. Trasa podsieci należy do zakresu ULA. (w ramach agregatu fd20::/20)

Przyjrzyjmy się tabeli routingu IPv4, wpisując to polecenie:

<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

Pokazuje ona sytuację podobną do instancji GUA.

Testy loków

Powtórz testy połączenia ze stronami internetowymi obsługującymi tylko IPv4 i tylko IPv6 za pomocą polecenia curl.

<username>@ula-instance:~$ curl -vv --connect-timeout 10 v6.ipv6test.app
<username>@ula-instance:~$ curl -vv --connect-timeout 10 v4.ipv6test.app

Poniżej znajdziesz przykładowe dane wyjściowe.

<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

W przypadku instancji ULA nie ma możliwości dotarcia do obu punktów końcowych internetu, ponieważ w przypadku punktu końcowego IPv6 nie możemy użyć adresu ULA do komunikacji wychodzącej, a instancja nie ma możliwości dotarcia do IPv4 jako instancja obsługująca tylko IPv6.

6. Włączanie NAT64 i DNS64

Skonfiguruj zarządzane usługi DNS64 i NAT64 dla sieci VPC.

DNS64

Włącz zasadę serwera DNS64 dla sieci VPC . Informuje to resolver DNS sieci VPC, aby syntetyzował rekordy AAAA dla odpowiedzi zawierających tylko rekordy A. Uruchom w Cloud Shell te polecenia:

gcloud beta dns policies create allow-dns64 \
    --description="Enable DNS64 Policy" \
    --networks=ipv6-only-vpc \
    --enable-dns64-all-queries \
    --project $projectname

NAT64

Utwórz router Cloud Router, który jest wymagany w przypadku Cloud NAT . Następnie utwórz bramę Cloud NAT skonfigurowaną dla NAT64, włączając ją dla wszystkich zakresów adresów IP podsieci tylko z IPv6 i automatycznie przydzielając zewnętrzne adresy IP. Uruchom w Cloud Shell te polecenia:

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. Testowanie NAT64 i DNS64

Teraz przetestuj konfigurację NAT64 i DNS64 na instancjach tylko z IPv6, zaczynając od instancji GUA, a następnie od instancji ULA.

Testowanie DNS64/NAT64 z instancji GUA

Połącz się z instancją „gua-instance” przez SSH, najpierw przechodząc przez instancję „ula-instance”.

gcloud compute ssh ula-instance --project $projectname --zone $zonename
<username>@ula-instance:~$ gcloud compute ssh gua-instance

Testy DNS

Sprawdź rozpoznawanie nazw DNS witryny obsługującej tylko IPv6 (np. v6.ipv6test.app, ale każda witryna obsługująca tylko IPv6 powinna dać podobny wynik).

<username>@gua-instance:~$ host -t AAAA v6.ipv6test.app
<username>@gua-instance:~$ host -t A v6.ipv6test.app

Oczekujemy, że zostaną zwrócone tylko odpowiedzi AAAA IPv6.

Przykładowe dane wyjściowe

<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

Sprawdź rozpoznawanie nazw DNS witryny obsługującej tylko IPv4 (np. v4.ipv6test.app). Oczekujesz zarówno rekordu A (oryginalny adres IPv4), jak i rekordu AAAA wygenerowanego przez DNS64 przy użyciu znanego prefiksu 64:ff9b::/96 .

<username>@gua-instance:~$ host -t AAAA v4.ipv6test.app
<username>@gua-instance:~$ host -t A v4.ipv6test.app

Przykładowe dane wyjściowe

<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

W podanym wyżej przykładzie adres IPv4 (54.192.51.38) w systemie dziesiętnym odpowiada wartości (36 c0 33 26) w systemie szesnastkowym. Dlatego oczekujemy, że odpowiedź dla rekordu AAAA będzie miała postać (64:ff9b::36c0:3326), co zgadza się z jedną z otrzymanych odpowiedzi AAAA.

Testy loków

Sprawdźmy rzeczywistą łączność z tymi samymi punktami końcowymi obsługującymi tylko IPv4 i tylko IPv6 za pomocą polecenia curl przez IPv6.

<username>@gua-instance:~$ curl -vv -6 v6.ipv6test.app

<username>@gua-instance:~$ curl -vv -6 v4.ipv6test.app

Poniżej znajdziesz przykładowe dane wyjściowe.

<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>
##

Oba polecenia curl działają. Zwróć uwagę, że połączenie ze stroną internetową obsługującą tylko IPv4 przez IPv6 było możliwe dzięki współpracy NAT64 i DNS64, które umożliwiły połączenie.

Sprawdzanie źródłowych adresów IP

Użyjmy usługi odbijania adresu IP, aby sprawdzić źródłowy adres IP widziany przez miejsce docelowe .

<username>@gua-instance:~$ curl -6 v4.ipv6test.app

<username>@gua-instance:~$ curl -6 v6.ipv6test.app

Przykładowe dane wyjściowe

<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::

Zgłoszony adres IPv6 powinien być zgodny z adresem IPv6 instancji . Adres powinien być zgodny z wynikiem polecenia „ip -6 address” w instancji. Przykład

<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

Zgłoszony adres IPv4 powinien jednak być zgodny z zewnętrznym adresem IP bramy Cloud NAT, ponieważ przed wyjściem do internetu wykonuje ona funkcję NAT64. Możesz to sprawdzić, uruchamiając to polecenie gcloud w Cloud Shell.

gcloud compute routers get-nat-ip-info \
       nat64-router \
       --region=$regionname

Przykładowe dane wyjściowe

result:
- natIpInfoMappings:
  - mode: AUTO
    natIp: 34.47.60.91
    usage: IN_USE
  natName: nat64-natgw

Zwróć uwagę, że adres „natIp” podany w danych wyjściowych jest zgodny z danymi wyjściowymi otrzymanymi z witryny odbijającej adres IP.

Testowanie DNS64/NAT64 z instancji ULA

Najpierw połącz się przez SSH z instancją ULA „ula-instance”.

gcloud compute ssh ula-instance --project $projectname --zone $zonename

<username>@ula-instance:~$

Testy DNS

Sprawdź rozpoznawanie nazw DNS witryny obsługującej tylko IPv6 (np. v6.ipv6test.app, ale każda witryna obsługująca tylko IPv6 powinna dać podobny wynik).

<username>@ula-instance:~$ host -t AAAA v6.ipv6test.app
<username>@ula-instance:~$ host -t A v6.ipv6test.app

Oczekujemy, że zostaną zwrócone tylko odpowiedzi AAAA IPv6.

Przykładowe dane wyjściowe

<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

Sprawdź rozpoznawanie nazw DNS witryny obsługującej tylko IPv4 (np. v4.ipv6test.app). Oczekujesz zarówno rekordu A (oryginalny adres IPv4), jak i rekordu AAAA wygenerowanego przez DNS64 przy użyciu znanego prefiksu 64:ff9b::/96 .

<username>@ula-instance:~$ host -t AAAA v4.ipv6test.app
<username>@ula-instance:~$ host -t A v4.ipv6test.app

Przykładowe dane wyjściowe

<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

W podanym wyżej przykładzie adres IPv4 (54.192.51.38) w systemie dziesiętnym odpowiada wartości (36 c0 33 26) w systemie szesnastkowym. Dlatego oczekujemy, że odpowiedź dla rekordu AAAA będzie miała postać (64:ff9b::36c0:3326), co zgadza się z jedną z otrzymanych odpowiedzi AAAA.

Testy loków

Sprawdźmy rzeczywistą łączność z tymi samymi punktami końcowymi tylko w wersji 4 i tylko w wersji 6 za pomocą polecenia curl.

Na początek pokażemy, że osiągalność przez IPv4 nie jest możliwa, ponieważ instancja obsługuje tylko IPv6.

<username>@ula-instance:~$ curl -vv -4 --connect-timeout 10 v6.ipv6test.app
<username>@ula-instance:~$ curl -vv -4 --connect-timeout 10 v4.ipv6test.app

Oba polecenia curl zakończą się niepowodzeniem. Niepowodzenia mogą mieć różne przyczyny. Poniżej znajdziesz przykładowe dane wyjściowe.

<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

Polecenie curl IPv4 do punktu końcowego obsługującego tylko IPv6 nie działa, ponieważ nie udało się rozpoznać rekordu A (co zostało wykazane podczas testów DNS). Polecenie curl IPv4 do punktu końcowego obsługującego tylko IPv4 nie działa, ponieważ instancja obsługująca tylko IPv6 nie ma dostępu do żadnego adresu IPv4 i z tego powodu następuje przekroczenie limitu czasu.

Przetestujmy teraz osiągalność przez IPv6.

<username>@ula-instance:~$ curl -vv -6 v6.ipv6test.app

<username>@ula-instance:~$ curl -vv -6 v4.ipv6test.app

Poniżej znajdziesz przykładowe dane wyjściowe.

<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>
##

Polecenie curl do witryny obsługującej tylko IPv6 nie powiedzie się, ponieważ podsieci ULA nie mają bezpośredniego dostępu do internetu. Polecenie curl do strony internetowej obsługującej tylko IPv4 działa, ponieważ DNS64 i NAT64 działają w ten sam sposób w przypadku instancji GUA i ULA. Jedynym wymaganiem jest to, aby instancja obsługiwała tylko IPv6.

Testowanie DNS64/NAT64 z instancji ULA z podwójnym stosem

Najpierw połącz się przez SSH z instancją ULA z podwójnym stosem „dualstack-ula-instance”. Musimy użyć flagi „–tunnel-through-iap”, aby wymusić używanie przez gcloud adresu IPv4 w przypadku IAP.

gcloud compute ssh dualstack-ula-instance --project $projectname --zone $zonename --tunnel-through-iap 

<username>@dualstack-ula-instance:~$

Przetestujmy teraz DNS64 za pomocą narzędzia „host”.

<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

Zwróć uwagę, że witryna obsługująca tylko IPv4 zwraca teraz tylko adresy IPv4, a nie syntetyczne odpowiedzi DNS64. Dzieje się tak, ponieważ DNS64 jest stosowany tylko w przypadku instancji obsługujących tylko IPv6 i nie jest oceniany w przypadku instancji z podwójnym stosem.

Aby obejść konieczność korzystania z DNS64, dodajmy wpis do pliku /etc/hosts, aby sprawdzić, czy NAT64 działa. Uruchom to polecenie na instancji z podwójnym stosem:

<username>@dualstack-ula-instance:~$ echo '64:ff9b::36c0:3326 v4.ipv6test.app' | sudo tee -a /etc/hosts

Następnie użyjemy polecenia curl, aby sprawdzić, czy można uzyskać dostęp do witryny IPv4 za pomocą protokołu IPv6.

<username>@dualstack-ula-instance:~$ curl -vv -6 --connect-timeout 10 v4.ipv6test.app

Oto przykładowe dane wyjściowe powyższego polecenia:

<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

Polecenie curl powinno przekroczyć limit czasu, ponieważ podobnie jak DNS64, NAT64 wymaga, aby instancja obsługiwała tylko IPv6.

Aby potwierdzić, że NAT64 nie jest stosowany do instancji z podwójnym stosem, użyj polecenia „get-nat-mapping”, aby wyświetlić listę wszystkich mapowań portów stosowanych przez bramę NAT. Uruchom w Cloud Shell te polecenia:

gcloud compute routers get-nat-mapping-info \
      nat64-router --region $regionname \
      --project $projectname

Powinny pojawić się dane wyjściowe podobne do tych poniżej:

---
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

Dane wyjściowe NAT pokazują, że brama NAT64 przydzieliła porty tylko instancjom GUA i ULA obsługującym tylko IPv6, ale nie instancji z podwójnym stosem.

8. Czyszczenie danych

Czyszczenie routera Cloud Router

W Cloud Shell wykonaj te czynności:

gcloud compute routers delete nat64-router \
      --region $regionname \
      --project $projectname --quiet

Odłączanie i czyszczenie zasad DNS

W Cloud Shell wykonaj te czynności:

gcloud beta dns policies update allow-dns64 \
    --networks="" \
    --project $projectname
gcloud beta dns policies delete allow-dns64 \
    --project $projectname --quiet

Usuwanie instancji

W Cloud Shell wykonaj te czynności: (uwaga: używamy gcloud beta, aby móc użyć flagi no-graceful-shutdown, która przyspiesza usuwanie instancji)

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

Czyszczenie podsieci

W Cloud Shell wykonaj te czynności:

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

Czyszczenie reguł zapory sieciowej

W Cloud Shell wykonaj te czynności:

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

Czyszczenie VPC

W Cloud Shell wykonaj te czynności:

gcloud compute networks delete ipv6-only-vpc \
       --project=$projectname \
       --quiet

Usuwanie uprawnień i konta usługi

W Cloud Shell wykonaj te czynności:

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. Gratulacje

Udało Ci się użyć NAT64 i DNS64, aby umożliwić instancjom obsługującym tylko IPv6 docieranie do miejsc docelowych obsługujących tylko IPv4 w internecie.

Co dalej?

Wypróbuj te ćwiczenia z programowania:

Więcej informacji i filmy

Dokumentacja