1. Introdução
Um dos principais desafios da migração para o IPv6 é manter a capacidade de alcançar endpoints e redes somente IPv4. Uma tecnologia líder para resolver esse desafio é combinar o uso do DNS64 (definido no RFC6147) para traduzir registros A em registros AAAA para clientes. Isso é combinado com o NAT64 (definido no RFC6146) para traduzir endereços IPv6 formatados especialmente em IPv4, em que o endereço IPv4 é incorporado ao endereço IPv6 especial. Este codelab orienta o usuário na configuração dos dois recursos em uma nuvem privada virtual (VPC) do Google Cloud Platform (GCP). Quando configurados juntos, o NAT64 e o DNS64 do GCP permitem que instâncias somente IPv6 se comuniquem com servidores somente IPv4 na Internet.
Neste laboratório, você vai configurar uma VPC com diferentes tipos de sub-redes e instâncias IPv6 : GUA (endereço Unicast global) somente IPv6, ULA (endereço local exclusivo) somente IPv6 e ULA de pilha dupla. Em seguida, você vai configurar e testar os serviços gerenciados DNS64 e NAT64 do Google Cloud para acessar sites somente IPv4.
2. O que você vai aprender
- Como criar sub-redes e instâncias somente IPv6
- Como ativar o serviço DNS64 gerenciado do Google Cloud para uma VPC .
- Como criar um gateway do Google Cloud NAT configurado para NAT64 .
- Como testar a resolução do DNS64 de instâncias somente IPv6 para destinos somente IPv4.
- Como o comportamento do DNS64 e do NAT64 difere entre instâncias de pilha única e dupla.
- Como configurar um gateway NAT para NAT64.
- Como testar a conectividade NAT64 de instâncias somente IPv6 para destinos somente IPv4.
3. Antes de começar
Atualizar o projeto para oferecer suporte ao codelab
Este codelab usa $variáveis para ajudar na implementação da configuração da gcloud no Cloud Shell.
No Cloud Shell, faça o seguinte:
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]
Arquitetura geral do laboratório

Para demonstrar como o NAT64 e o DNS64 interagem com diferentes tipos de sub-redes IPv6, você vai criar uma única VPC com sub-redes IPv6 nos formatos GUA e ULA. Você também vai criar uma sub-rede de pilha dupla (usando endereçamento ULA) para demonstrar como o DNS64 e o NAT64 não se aplicam a VMs de pilha dupla.
Em seguida, você vai configurar o DNS64 e o NAT64 e testar a conectividade com destinos IPv6 e IPv4 na Internet.
4. Etapas de preparação
Primeiro, configure a conta de serviço, o IAM, a infraestrutura de rede e as instâncias necessárias no seu projeto do Google Cloud.
Criar uma conta de serviço e vinculações do IAM
Começamos criando uma conta de serviço para permitir que as instâncias façam SSH entre si usando o gcloud. Precisamos dessa capacidade porque não podemos usar o IAP para acessar a instância somente IPv6 do GUA, e o Cloud Shell ainda não permite acesso direto ao IPv6. Execute os comandos a seguir no Cloud Shell.
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
Criar uma VPC e ativar o ULA
Crie uma rede VPC com modo de sub-rede personalizada e IPv6 interno ULA ativado executando os seguintes comandos no Cloud Shell.
gcloud compute networks create ipv6-only-vpc \
--project=$projectname \
--subnet-mode=custom \
--mtu=1500 --bgp-routing-mode=global \
--enable-ula-internal-ipv6
Crie regras de firewall
Crie regras de firewall para permitir o acesso SSH. Uma regra permite o SSH do intervalo ULA geral (fd20::/20). Mais duas regras permitem o tráfego dos intervalos IPv6 e IPv4 predefinidos do IAP (2600:2d00:1:7::/64 e 35.235.240.0/20, respectivamente).
Execute os comandos a seguir no Cloud Shell:
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
Criar sub-redes
Crie uma sub-rede somente GUA v6, uma sub-rede somente ULA v6 e uma sub-rede ULA de pilha dupla. Execute os comandos a seguir no Cloud Shell:
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
Criar instâncias
Crie instâncias em cada uma das sub-redes que você acabou de criar. A instância ULA somente IPv6 é especificada com a plataforma do Cloud para permitir que a usemos como uma jumpbox para a instância GUA somente IPv6. Execute os comandos a seguir no Cloud Shell:
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
Configuração e acesso inicial à instância
Faça SSH na instância da ULA, que usará o IAP por padrão. Use o seguinte comando no Cloud Shell para se conectar à instância da ULA por SSH:
gcloud compute ssh ula-instance --project $projectname --zone $zonename
<username>@ula-instance:~$
Também vamos usar a instância da ULA como uma jumpbox para a instância da GUA, já que a IAP não funciona com instâncias da GUA e as VMs do Cloud Shell não podem acessar destinos IPv6.
Ainda no shell da instância da ULA. Tente fazer SSH na instância do GUA usando o seguinte comando gcloud.
Na primeira vez que você executar um comando SSH em uma instância, será necessário configurar um par de chaves SSH. Continue pressionando "Enter" até que a chave seja criada e o comando SSH seja executado. Isso cria um novo par de chaves sem senha longa.
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]-----+
Se for bem-sucedido, o comando SSH será executado e você terá feito o SSH com sucesso na instância do 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. Analise as instâncias somente IPv6.
Vamos examinar as duas instâncias somente IPv6 fazendo SSH nelas e analisando as tabelas de roteamento.
Examinar a instância do GUA
Use SSH para acessar a "gua-instance" primeiro passando pela "ula-instance".
gcloud compute ssh ula-instance --project $projectname --zone $zonename
<username>@ula-instance:~$ gcloud compute ssh gua-instance
Vamos analisar a tabela de rotas IPv6 da instância usando o seguinte comando:
<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
Notamos três entradas na tabela de roteamento
- Uma rota /65 para a sub-rede GUA a que a instância pertence com um próximo salto derivado usando um endereço local de link para o gateway padrão. Lembre-se de que o /65 superior é reservado para balanceadores de carga de rede de passagem IPv6.
- Uma rota /64 integrada para o prefixo unicast link-local fe80::/64
- Uma rota padrão que aponta para o endereço local de link do gateway padrão da sub-rede.
Vamos analisar a tabela de roteamento IPv4 executando este comando
<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
Surpreendente? Na verdade, mantemos uma tabela de roteamento IPv4 em instâncias somente IPv6 estritamente para permitir o acesso ao servidor de metadados do Compute (169.254.169.154), já que ele ainda é um endpoint somente IPv4.
Como a instância assume o IP 169.254.1.2 quando é uma instância somente IPv6. Esse IP não pode ser roteado em nenhum lugar, exceto para o servidor de metadados do Compute. Portanto, a instância fica isolada de todas as redes IPv4.
Testes de curl
Vamos testar a conectividade real com sites somente IPv4 e somente IPv6 usando curl.
<username>@gua-instance:~$ curl -vv --connect-timeout 10 v6.ipv6test.app
<username>@gua-instance:~$ curl -vv --connect-timeout 10 v4.ipv6test.app
Confira abaixo um exemplo de saída.
<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
Como esperado, não há capacidade de alcançar um endpoint da Internet IPv4 de uma instância somente IPv6. Sem o provisionamento do DNS64 e do NAT64, a instância somente IPv6 não tem um caminho para um destino IPv4. A capacidade de alcançar um destino IPv6 funciona normalmente porque a instância tem um endereço IPv6 GUA.
Examinar instância da ULA
Acesse a instância "ula-instance" por SSH (usa o IAP por padrão).
gcloud compute ssh ula-instance --project $projectname --zone $zonename
Vamos analisar a tabela de rotas IPv6 da instância usando o seguinte comando:
<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
Notamos três entradas na tabela de roteamento, semelhantes à instância GUA, exceto que a máscara é /64 em vez de /65. E a rota de sub-rede pertence a um intervalo de ULA. (no agregado fd20::/20)
Vamos analisar a tabela de roteamento IPv4 executando este comando
<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
que mostra uma situação semelhante à da instância do GUA.
Testes de curl
Repetindo os testes de conectividade para sites somente v4 e somente v6 usando curl.
<username>@ula-instance:~$ curl -vv --connect-timeout 10 v6.ipv6test.app
<username>@ula-instance:~$ curl -vv --connect-timeout 10 v4.ipv6test.app
Confira abaixo um exemplo de saída.
<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
No caso da instância ULA, não há capacidade de alcançar os dois endpoints da Internet. Isso porque, para o endpoint IPv6, não é possível usar um endereço ULA para se comunicar, e a instância não tem capacidade de alcançar o IPv4 como uma instância somente IPv6.
6. Ativar NAT64 e DNS64
Configure os serviços gerenciados DNS64 e NAT64 para sua VPC.
DNS64
Ative a política de servidor DNS64 para sua VPC . Isso informa ao resolvedor de DNS da VPC para sintetizar registros AAAA para respostas somente A. Execute os comandos a seguir no Cloud Shell:
gcloud beta dns policies create allow-dns64 \
--description="Enable DNS64 Policy" \
--networks=ipv6-only-vpc \
--enable-dns64-all-queries \
--project $projectname
NAT64
Crie um Cloud Router, que é necessário para o Cloud NAT . Em seguida, crie um gateway do Cloud NAT configurado para NAT64, ativando-o para todos os intervalos de IP de sub-rede somente IPv6 e alocando IPs externos automaticamente. Execute os comandos a seguir no Cloud Shell:
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. Testar NAT64 e DNS64
Agora, vamos testar a configuração do NAT64 e do DNS64 nas instâncias somente IPv6, começando pela instância GUA e depois pela ULA.
Como testar DNS64/NAT64 de uma instância GUA
Use SSH para acessar a "gua-instance" primeiro passando pela "ula-instance".
gcloud compute ssh ula-instance --project $projectname --zone $zonename
<username>@ula-instance:~$ gcloud compute ssh gua-instance
Testes de DNS
Teste a resolução de DNS de um site somente IPv6 (por exemplo, v6.ipv6test.app, mas qualquer site somente IPv6 deve gerar um resultado semelhante.
<username>@gua-instance:~$ host -t AAAA v6.ipv6test.app
<username>@gua-instance:~$ host -t A v6.ipv6test.app
Esperamos que apenas respostas AAAA IPv6 sejam retornadas.
Exemplo de saída
<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
Teste a resolução DNS de um site somente IPv4 (por exemplo, v4.ipv6test.app). Você espera um registro A (o IPv4 original) e um registro AAAA sintetizado pelo DNS64 usando o prefixo conhecido 64:ff9b::/96 .
<username>@gua-instance:~$ host -t AAAA v4.ipv6test.app
<username>@gua-instance:~$ host -t A v4.ipv6test.app
Exemplo de saída
<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
No exemplo acima, o endereço IPv4 (54.192.51.38) em decimal seria traduzido para (36 c0 33 26) em hexadecimal. Portanto, esperamos que uma resposta para o registro AAAA seja (64:ff9b::36c0:3326), que corresponde a uma das respostas AAAA que recebemos.
Testes de curl
Vamos testar a conectividade real com os mesmos endpoints somente v4 e somente v6 usando curl por IPv6.
<username>@gua-instance:~$ curl -vv -6 v6.ipv6test.app
<username>@gua-instance:~$ curl -vv -6 v4.ipv6test.app
Confira abaixo um exemplo de saída.
<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>
##
Os dois comandos curl são concluídos. Observe como a conexão com um site somente IPv4 por IPv6 foi possível porque o NAT64 e o DNS64 funcionaram em conjunto para ativar a conectividade.
Verificar IPs de origem
Vamos usar um serviço de reflexão de IP para verificar o IP de origem observado pelo destino .
<username>@gua-instance:~$ curl -6 v4.ipv6test.app
<username>@gua-instance:~$ curl -6 v6.ipv6test.app
Exemplo de saída
<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::
O endereço IPv6 informado precisa corresponder ao endereço IPv6 da instância . Esse endereço precisa corresponder à saída do comando "ip -6 address" na instância. Por exemplo:
<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
No entanto, o endereço IPv4 informado precisa corresponder ao endereço IP externo do gateway do Cloud NAT, já que ele executa a função NAT64 antes de sair para a Internet. Para verificar, execute este comando da gcloud no Cloud Shell:
gcloud compute routers get-nat-ip-info \
nat64-router \
--region=$regionname
Exemplo de saída
result:
- natIpInfoMappings:
- mode: AUTO
natIp: 34.47.60.91
usage: IN_USE
natName: nat64-natgw
O "natIp" informado na saída corresponde à saída recebida do site de reflexão de IP.
Como testar DNS64/NAT64 de uma instância ULA
Primeiro, faça SSH na instância da ULA "ula-instance"
gcloud compute ssh ula-instance --project $projectname --zone $zonename
<username>@ula-instance:~$
Testes de DNS
Teste a resolução de DNS de um site somente IPv6 (por exemplo, v6.ipv6test.app, mas qualquer site somente IPv6 deve gerar um resultado semelhante.
<username>@ula-instance:~$ host -t AAAA v6.ipv6test.app
<username>@ula-instance:~$ host -t A v6.ipv6test.app
Esperamos que apenas respostas AAAA IPv6 sejam retornadas.
Exemplo de saída
<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
Teste a resolução DNS de um site somente IPv4 (por exemplo, v4.ipv6test.app). Você espera um registro A (o IPv4 original) e um registro AAAA sintetizado pelo DNS64 usando o prefixo conhecido 64:ff9b::/96 .
<username>@ula-instance:~$ host -t AAAA v4.ipv6test.app
<username>@ula-instance:~$ host -t A v4.ipv6test.app
Exemplo de saída
<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
No exemplo acima, o endereço IPv4 (54.192.51.38) em decimal seria traduzido para (36 c0 33 26) em hexadecimal. Portanto, esperamos que uma resposta para o registro AAAA seja (64:ff9b::36c0:3326), que corresponde a uma das respostas AAAA que recebemos.
Testes de curl
Vamos testar a conectividade real com os mesmos endpoints somente IPv4 e somente IPv6 usando curl.
Para começar, vamos mostrar que a capacidade de alcançar o IPv4 não é possível, já que a instância é somente 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
As duas solicitações curl vão falhar. Elas vão falhar por motivos diferentes. Confira abaixo um exemplo de saída.
<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
O curl IPv4 para um endpoint somente IPv6 falha porque a resolução DNS do registro A não funciona, conforme demonstrado durante os testes de DNS. O curl IPv4 para um endpoint somente IPv4 falha porque uma instância somente IPv6 não tem acessibilidade a nenhum endereço IPv4, e recebemos um tempo limite devido a isso.
Agora vamos testar a acessibilidade pelo IPv6.
<username>@ula-instance:~$ curl -vv -6 v6.ipv6test.app
<username>@ula-instance:~$ curl -vv -6 v4.ipv6test.app
Confira abaixo um exemplo de saída.
<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>
##
O curl para o site somente IPv6 falha porque as sub-redes ULA não têm capacidade de alcance direto à Internet. O curl para o site somente IPv4 é bem-sucedido porque o DNS64 e o NAT64 operam da mesma forma para instâncias GUA e ULA. O único requisito é que a instância seja somente IPv6.
Como testar DNS64/NAT64 em uma instância ULA de pilha dupla
Primeiro, use SSH na instância ULA de pilha dupla "dualstack-ula-instance". Precisamos usar a flag "–tunnel-through-iap" para forçar a gcloud a usar o endereço IPv4 para o IAP.
gcloud compute ssh dualstack-ula-instance --project $projectname --zone $zonename --tunnel-through-iap
<username>@dualstack-ula-instance:~$
Vamos testar o DNS64 agora usando o utilitário "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
Observe como o site somente IPv4 agora está retornando apenas endereços IPv4 e não mais as respostas sintéticas do DNS64. Isso ocorre porque o DNS64 só é aplicado a instâncias somente IPv6 e não é avaliado para instâncias de pilha dupla.
Para evitar a necessidade do DNS64, vamos adicionar uma entrada ao arquivo /etc/hosts para testar se o NAT64 funciona. Execute o seguinte comando na instância de pilha dupla:
<username>@dualstack-ula-instance:~$ echo '64:ff9b::36c0:3326 v4.ipv6test.app' | sudo tee -a /etc/hosts
Em seguida, use o curl para testar o acesso ao site IPv4 por IPv6.
<username>@dualstack-ula-instance:~$ curl -vv -6 --connect-timeout 10 v4.ipv6test.app
Confira um exemplo de saída do comando acima:
<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
O curl vai atingir o tempo limite porque, assim como o DNS64, o NAT64 também exige que a instância seja somente IPv6 para ser aplicado.
Para confirmar que o NAT64 não está sendo aplicado à instância de pilha dupla, use o comando "get-nat-mapping" para listar todos os mapeamentos de porta que o gateway NAT está aplicando. Execute os comandos a seguir no Cloud Shell:
gcloud compute routers get-nat-mapping-info \
nat64-router --region $regionname \
--project $projectname
A saída será semelhante ao snippet abaixo:
---
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
A saída do NAT mostra que o gateway NAT64 alocou portas apenas para as instâncias GUA e ULA somente IPv6, mas não para a instância de pilha dupla.
8. Limpar
Limpar o Cloud Router
No Cloud Shell, faça o seguinte:
gcloud compute routers delete nat64-router \
--region $regionname \
--project $projectname --quiet
Desvincular e limpar a política de DNS
No Cloud Shell, faça o seguinte:
gcloud beta dns policies update allow-dns64 \
--networks="" \
--project $projectname
gcloud beta dns policies delete allow-dns64 \
--project $projectname --quiet
Limpar instâncias
No Cloud Shell, faça o seguinte: (observe que o gcloud beta é usado para permitir o uso da flag "no-graceful-shutdown" para uma operação de exclusão de instância mais rápida)
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
Limpar sub-redes
No Cloud Shell, faça o seguinte:
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
Limpar regras de firewall
No Cloud Shell, faça o seguinte:
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
Limpar a VPC
No Cloud Shell, faça o seguinte:
gcloud compute networks delete ipv6-only-vpc \
--project=$projectname \
--quiet
Limpar permissões do IAM e conta de serviço
No Cloud Shell, faça o seguinte:
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. Parabéns
Você usou o NAT64 e o DNS64 para permitir que instâncias somente IPv6 alcancem destinos somente IPv4 na Internet.
A seguir
Confira alguns destes codelabs:
- Acessar APIs do Google de hosts locais usando endereços IPv6
- Opções de endereçamento IP IPv4 e IPv6
- Usar a instância, o endereço e o gateway do próximo salto das rotas estáticas IPv6