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
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.
- 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.
- Wbudowana trasa /64 dla prefiksu typu link-local unicast fe80::/64
- 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:
- Dostęp do interfejsów API Google z hostów lokalnych za pomocą adresów IPv6
- Opcje adresowania IP IPv4 i IPv6
- Używanie instancji następnego przeskoku, adresu następnego przeskoku i bramy następnego przeskoku w przypadku statycznych tras IPv6