Tạo các phiên bản máy ảo chỉ có IPv6 và bật NAT64/DNS64

1. Giới thiệu

Một trong những thách thức chính khi di chuyển sang IPv6 là duy trì khả năng tiếp cận các mạng và điểm cuối chỉ có IPv4. Một công nghệ hàng đầu để giải quyết thách thức này là kết hợp việc sử dụng DNS64 (được xác định trong RFC6147) để dịch bản ghi A thành bản ghi AAAA cho các máy khách. Sau đó, công nghệ này được kết hợp với NAT64 (được xác định trong RFC6146) để dịch các địa chỉ IPv6 có định dạng đặc biệt thành IPv4, trong đó địa chỉ IPv4 được nhúng vào địa chỉ IPv6 đặc biệt. Lớp học lập trình này hướng dẫn người dùng định cấu hình cả hai tính năng trên một Đám mây riêng ảo (VPC) của Google Cloud Platform (GCP). Khi được định cấu hình cùng nhau, NAT64 và DNS64 của GCP cho phép các phiên bản chỉ có IPv6 giao tiếp với các máy chủ chỉ có IPv4 trên Internet.

Trong phòng thí nghiệm này, bạn sẽ thiết lập một VPC có nhiều loại mạng con và phiên bản IPv6 : GUA (Địa chỉ truyền đơn toàn cầu) chỉ dành cho IPv6, ULA (Địa chỉ cục bộ duy nhất) chỉ dành cho IPv6 và ULA ngăn xếp kép. Sau đó, bạn sẽ định cấu hình và kiểm thử các dịch vụ DNS64 và NAT64 do Google Cloud quản lý để truy cập vào các trang web chỉ có IPv4.

2. Kiến thức bạn sẽ học được

  • Cách tạo các phiên bản và mạng con chỉ có IPv6
  • Cách bật dịch vụ DNS64 được quản lý của Google Cloud cho một VPC .
  • Cách tạo một cổng NAT Google Cloud được định cấu hình cho NAT64 .
  • Cách kiểm thử tính năng phân giải DNS64 từ các phiên bản chỉ có IPv6 đến các đích đến chỉ có IPv4.
  • Sự khác biệt về hành vi của DNS64 và NAT64 giữa các phiên bản ngăn xếp đơn và ngăn xếp kép.
  • Cách định cấu hình một cổng NAT cho NAT64.
  • Cách kiểm thử khả năng kết nối NAT64 từ các phiên bản chỉ có IPv6 đến các đích đến chỉ có IPv4.

3. Trước khi bắt đầu

Cập nhật dự án để hỗ trợ lớp học lập trình

Lớp học lập trình này sử dụng các $biến để hỗ trợ việc triển khai cấu hình gcloud trong Cloud Shell.

Trong Cloud Shell, hãy thực hiện các bước sau

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]

Cấu trúc tổng thể của phòng thí nghiệm

63e4293e033da8d3.png

Để minh hoạ cách NAT64 và DNS64 tương tác với các loại mạng con IPv6 khác nhau, bạn sẽ tạo một VPC duy nhất có mạng con IPv6 ở cả GUA và ULA. Bạn cũng sẽ tạo một mạng con ngăn xếp kép (sử dụng địa chỉ ULA) để minh hoạ cách DNS64 và NAT64 không áp dụng cho các VM ngăn xếp kép.

Sau đó, bạn sẽ định cấu hình DNS64 và NAT64, đồng thời kiểm tra khả năng kết nối với các đích đến IPv6 và IPv4 trên Internet.

4. Các bước chuẩn bị

Trước tiên, hãy thiết lập tài khoản dịch vụ, IAM, cơ sở hạ tầng mạng và các phiên bản cần thiết trong dự án Google Cloud của bạn.

Tạo Tài khoản dịch vụ và các mối liên kết IAM

Chúng ta bắt đầu bằng cách tạo một tài khoản dịch vụ mới để cho phép các phiên bản SSH với nhau bằng gcloud. Chúng ta sẽ cần khả năng này vì không thể dùng IAP để truy cập vào phiên bản chỉ có IPv6 của GUA và cloudshell hiện chưa cho phép truy cập trực tiếp vào IPv6. Chạy(các) lệnh sau trong cloudshell.

gcloud iam service-accounts create ipv6-codelab \
     --description="temporary service account for a codelab" \
     --display-name="ipv6codelabSA" \
     --project $projectname

gcloud projects add-iam-policy-binding  $projectname \
--member=serviceAccount:ipv6-codelab@$projectname.iam.gserviceaccount.com \
--role=roles/compute.instanceAdmin.v1

gcloud iam service-accounts add-iam-policy-binding \
    ipv6-codelab@$projectname.iam.gserviceaccount.com \
--member=serviceAccount:ipv6-codelab@$projectname.iam.gserviceaccount.com \
--role=roles/iam.serviceAccountUser

Tạo VPC và bật ULA

Tạo một mạng VPC ở chế độ mạng con tuỳ chỉnh và bật IPv6 nội bộ ULA bằng cách chạy(các) lệnh sau trong cloudshell.

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

Tạo quy tắc tường lửa

Tạo quy tắc tường lửa để cho phép truy cập SSH. Một quy tắc cho phép SSH từ dải ULA tổng thể (fd20::/20). Hai quy tắc khác cho phép lưu lượng truy cập từ các dải IPv6 và IPv4 được xác định trước của IAP (lần lượt là 2600:2d00:1:7::/64, 35.235.240.0/20).

Chạy(các) lệnh sau trong cloudshell:

gcloud compute firewall-rules create allow-v6-ssh-ula \
--direction=INGRESS --priority=200 \
--network=ipv6-only-vpc --action=ALLOW \
--rules=tcp:22 --source-ranges=fd20::/20 \
--project=$projectname 

gcloud compute firewall-rules create allow-v6-iap \
--direction=INGRESS --priority=300 \
--network=ipv6-only-vpc --action=ALLOW \
--rules=tcp --source-ranges=2600:2d00:1:7::/64 \
--project=$projectname 

gcloud compute firewall-rules create allow-v4-iap \
--direction=INGRESS --priority=300 \
--network=ipv6-only-vpc --action=ALLOW \
--rules=tcp --source-ranges=35.235.240.0/20 \
--project=$projectname 

Tạo mạng con

Tạo một mạng con chỉ có GUA v6, một mạng con chỉ có ULA v6 và một mạng con ULA có ngăn xếp kép. Chạy(các) lệnh sau trong cloudshell:

gcloud compute networks subnets create gua-v6only-subnet \
--network=ipv6-only-vpc \
--project=$projectname \
--stack-type=IPV6_ONLY \
--ipv6-access-type=external \
--region=$regionname 

gcloud compute networks subnets create ula-v6only-subnet  \
--network=ipv6-only-vpc \
--project=$projectname \
--stack-type=IPV6_ONLY \
--ipv6-access-type=internal \
--enable-private-ip-google-access \
--region=$regionname

gcloud compute networks subnets create ula-dualstack-subnet  \
--network=ipv6-only-vpc \
--project=$projectname \
--stack-type=IPV4_IPV6 \
--range=10.120.0.0/16 \
--ipv6-access-type=internal \
--region=$regionname 

Tạo các phiên bản

Tạo các phiên bản trong từng mạng con mà bạn vừa tạo. Phiên bản ULA chỉ có IPv6 được chỉ định bằng cloud-platform để cho phép chúng tôi sử dụng phiên bản này làm jumpbox cho phiên bản chỉ có IPv6 GUA. Chạy(các) lệnh sau trong cloudshell:

gcloud compute instances create gua-instance \
--subnet gua-v6only-subnet \
--stack-type IPV6_ONLY \
--zone $zonename \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--service-account=ipv6-codelab@$projectname.iam.gserviceaccount.com \
--project=$projectname

gcloud compute instances create ula-instance \
--subnet ula-v6only-subnet \
--stack-type IPV6_ONLY \
--zone $zonename \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--service-account=ipv6-codelab@$projectname.iam.gserviceaccount.com \
--project=$projectname

gcloud compute instances create dualstack-ula-instance \
--subnet ula-dualstack-subnet \
--stack-type IPV4_IPV6 \
--zone $zonename \
--project=$projectname

Thiết lập và truy cập vào phiên bản ban đầu

SSH đến phiên bản ULA sẽ sử dụng IAP theo mặc định. Sử dụng lệnh sau trong cloudshell để SSH vào phiên bản ULA:

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

<username>@ula-instance:~$ 

Chúng tôi cũng sẽ sử dụng phiên bản ULA làm jumpbox cho phiên bản GUA (vì IAP không hoạt động với các phiên bản GUA và VM Cloud Shell không thể truy cập vào các đích đến IPv6).

Trong khi vẫn ở trong shell của phiên bản ULA. Thử SSH vào phiên bản GUA bằng lệnh gcloud sau.

Trong lần đầu tiên bạn chạy một lệnh SSH bên trong một phiên bản, lệnh này sẽ nhắc bạn thiết lập một cặp khoá SSH. Tiếp tục nhấn phím Enter cho đến khi khoá được tạo và lệnh SSH được thực thi; thao tác này sẽ tạo một cặp khoá mới mà không có cụm mật khẩu.

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

Nếu thành công, lệnh SSH sẽ thành công và bạn sẽ SSH thành công vào phiên bản 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. Kiểm tra các phiên bản chỉ có IPv6.

Hãy kiểm tra cả hai phiên bản chỉ có IPv6 bằng cách SSH vào chúng và kiểm tra bảng định tuyến của chúng.

Kiểm tra phiên bản GUA

SSH vào "gua-instance" bằng cách chuyển qua phiên bản "ula-instance" trước.

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

Hãy xem bảng định tuyến IPv6 của phiên bản bằng lệnh sau

<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

Chúng ta thấy 3 mục trong bảng định tuyến

  1. Tuyến đường /65 cho mạng con GUA mà phiên bản thuộc về với một bước nhảy tiếp theo được dẫn xuất bằng cách sử dụng địa chỉ liên kết cục bộ cho cổng mặc định. Hãy nhớ rằng /65 trên được dành riêng cho Bộ cân bằng tải mạng truyền qua IPv6
  2. Một tuyến đường /64 tích hợp cho tiền tố unicast liên kết cục bộ fe80::/64
  3. Một tuyến đường mặc định trỏ đến địa chỉ liên kết cục bộ cho cổng mặc định của mạng con.

Hãy xem bảng định tuyến IPv4 bằng cách đưa ra lệnh sau

<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

Ngạc nhiên chưa? Trên thực tế, chúng tôi duy trì một bảng định tuyến IPv4 trong các phiên bản chỉ có IPv6 để cho phép truy cập vào máy chủ siêu dữ liệu của Compute (169.254.169.154) vì đây vẫn là một điểm cuối chỉ có IPv4.

Vì phiên bản này có IP 169.254.1.2 khi là phiên bản chỉ có IPv6. IP này không thể định tuyến đến bất kỳ nơi nào khác ngoài máy chủ Siêu dữ liệu của Compute, vì vậy, phiên bản này được cách ly hiệu quả với tất cả các mạng IPv4.

Kiểm thử bằng curl

Hãy kiểm tra khả năng kết nối thực tế với các trang web chỉ có v4 và chỉ có v6 bằng cách sử dụng curl.

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

Dưới đây là một kết quả mẫu.

<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

Như dự kiến, không có khả năng kết nối đến một điểm cuối Internet IPv4 từ một phiên bản chỉ có IPv6. Nếu không cung cấp DNS64 và NAT64, phiên bản chỉ có IPv6 sẽ không có đường dẫn đến đích đến IPv4. Khả năng truy cập vào một đích đến IPv6 hoạt động bình thường vì phiên bản này có địa chỉ IPv6 GUA.

Kiểm tra phiên bản ULA

SSH vào phiên bản "ula-instance" (theo mặc định, sử dụng IAP).

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

Hãy xem bảng định tuyến IPv6 của phiên bản bằng lệnh sau

<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

Chúng ta thấy 3 mục trong bảng định tuyến, tương tự như phiên bản GUA, ngoại trừ việc mặt nạ là /64 thay vì /65. Và tuyến mạng con thuộc một dải ULA. (trong tập hợp fd20::/20)

Hãy xem bảng định tuyến IPv4 bằng cách đưa ra lệnh sau

<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

Điều này cho thấy một tình huống tương tự như phiên bản GUA.

Kiểm thử bằng curl

Lặp lại các bài kiểm thử khả năng kết nối với các trang web chỉ có v4 và chỉ có v6 bằng cách sử dụng curl.

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

Dưới đây là một kết quả mẫu.

<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

Trong trường hợp phiên bản ULA, không có khả năng tiếp cận cả hai điểm cuối trên Internet vì đối với điểm cuối IPv6, chúng ta không thể sử dụng địa chỉ ULA để giao tiếp và phiên bản này không có khả năng tiếp cận IPv4 vì là phiên bản chỉ có IPv6.

6. Bật NAT64 và DNS64

Định cấu hình các dịch vụ DNS64 và NAT64 được quản lý cho VPC của bạn.

DNS64

Bật chính sách Máy chủ DNS64 cho VPC của bạn . Lệnh này yêu cầu trình phân giải DNS của VPC tổng hợp các bản ghi AAAA cho các phản hồi chỉ có A. Chạy(các) lệnh sau trong cloudshell:

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

NAT64

Tạo một Bộ định tuyến đám mây (bắt buộc đối với Cloud NAT). Sau đó, hãy tạo một cổng Cloud NAT được định cấu hình cho NAT64, cho phép cổng này hoạt động cho tất cả dải IP của mạng con chỉ có IPv6 và tự động phân bổ IP bên ngoài. Chạy(các) lệnh sau trong cloudshell:

gcloud compute routers create nat64-router \
--network=ipv6-only-vpc \
--region=$regionname \
--project=$projectname


gcloud beta compute routers nats create nat64-natgw \
--router=nat64-router \
--region=$regionname \
--auto-allocate-nat-external-ips \
--nat64-all-v6-subnet-ip-ranges \
--project=$projectname
 

7. Kiểm thử NAT64 và DNS64

Bây giờ, hãy kiểm thử cấu hình NAT64 và DNS64 của bạn từ các phiên bản chỉ có IPv6, bắt đầu bằng phiên bản GUA, sau đó là phiên bản ULA.

Kiểm thử DNS64/NAT64 từ một phiên bản GUA

SSH vào "gua-instance" bằng cách chuyển qua phiên bản "ula-instance" trước.

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

Kiểm tra DNS

Kiểm thử quá trình phân giải DNS của một trang web chỉ có IPv6 (ví dụ: v6.ipv6test.app nhưng mọi trang web chỉ có IPv6 đều sẽ cho ra kết quả tương tự).

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

Chúng tôi chỉ mong đợi các câu trả lời AAAA IPv6 được trả về.

Kết quả ví dụ

<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

Kiểm thử quy trình phân giải DNS của một trang web chỉ có IPv4 (ví dụ: v4.ipv6test.app). Bạn mong đợi cả bản ghi A (IPv4 gốc) và bản ghi AAAA do DNS64 tổng hợp bằng tiền tố nổi tiếng 64:ff9b::/96 .

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

Kết quả ví dụ

<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

Trong ví dụ trên, địa chỉ IPv4 (54.192.51.38) ở dạng số thập phân sẽ được chuyển thành (36 c0 33 26) ở dạng số thập lục phân. Do đó, chúng ta sẽ mong đợi câu trả lời cho bản ghi AAAA là (64:ff9b::36c0:3326), trùng khớp với một trong các câu trả lời AAAA mà chúng ta nhận được.

Kiểm thử bằng curl

Hãy kiểm tra khả năng kết nối thực tế với cùng các điểm cuối chỉ dành cho v4 và chỉ dành cho v6 bằng cách sử dụng curl qua IPv6

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

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

Dưới đây là một kết quả mẫu.

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

Cả hai lệnh curl đều thành công. Lưu ý rằng bạn có thể kết nối với một trang web chỉ hỗ trợ IPv4 qua IPv6 nhờ NAT64 và DNS64 hoạt động song song để kết nối thành công.

Kiểm tra IP nguồn

Hãy sử dụng dịch vụ phản chiếu IP để kiểm tra IP nguồn mà đích đến quan sát được .

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

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

Đầu ra mẫu

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

Địa chỉ IPv6 được báo cáo phải khớp với địa chỉ IPv6 của phiên bản . Địa chỉ này phải khớp với đầu ra của lệnh "ip -6 address" trên phiên bản. Ví dụ:

<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

Tuy nhiên, địa chỉ IPv4 được báo cáo phải khớp với địa chỉ IP bên ngoài của cổng Cloud NAT vì cổng này đang thực hiện chức năng NAT64 trước khi truyền dữ liệu ra Internet. Bạn có thể xác minh điều này bằng cách chạy lệnh gcloud sau trong cloudshell

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

Đầu ra mẫu

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

Xin lưu ý rằng "natIp" được báo cáo trong đầu ra khớp với đầu ra nhận được từ trang web phản chiếu IP.

Kiểm thử DNS64/NAT64 từ một phiên bản ULA

Trước tiên, hãy SSH vào phiên bản ULA "ula-instance"

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

<username>@ula-instance:~$

Kiểm tra DNS

Kiểm thử quá trình phân giải DNS của một trang web chỉ có IPv6 (ví dụ: v6.ipv6test.app nhưng mọi trang web chỉ có IPv6 đều sẽ cho ra kết quả tương tự).

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

Chúng tôi chỉ mong đợi các câu trả lời AAAA IPv6 được trả về.

Kết quả ví dụ

<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

Kiểm thử quy trình phân giải DNS của một trang web chỉ có IPv4 (ví dụ: v4.ipv6test.app). Bạn mong đợi cả bản ghi A (IPv4 gốc) và bản ghi AAAA do DNS64 tổng hợp bằng tiền tố nổi tiếng 64:ff9b::/96 .

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

Kết quả ví dụ

<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

Trong ví dụ trên, địa chỉ IPv4 (54.192.51.38) ở dạng số thập phân sẽ được chuyển thành (36 c0 33 26) ở dạng số thập lục phân. Do đó, chúng ta sẽ mong đợi câu trả lời cho bản ghi AAAA là (64:ff9b::36c0:3326), trùng khớp với một trong các câu trả lời AAAA mà chúng ta nhận được.

Kiểm thử bằng curl

Hãy kiểm tra khả năng kết nối thực tế với cùng các điểm cuối chỉ có v4 và chỉ có v6 bằng cách sử dụng curl.

Để bắt đầu, hãy cho thấy rằng không thể kết nối qua IPv4 vì phiên bản này chỉ có 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

Cả hai lệnh curl đều sẽ không thành công. Các yêu cầu này sẽ không thành công vì nhiều lý do. Dưới đây là một kết quả mẫu.

<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

Lệnh curl IPv4 đến một điểm cuối chỉ có IPv6 sẽ không thành công vì hoạt động phân giải DNS cho bản ghi A không thành công (như minh hoạ trong các bài kiểm thử DNS). Lệnh curl IPv4 đến một điểm cuối chỉ có IPv4 sẽ không thành công vì một phiên bản chỉ có IPv6 không có khả năng tiếp cận bất kỳ địa chỉ IPv4 nào và chúng ta sẽ gặp phải tình trạng hết thời gian chờ do đó.

Bây giờ, hãy kiểm tra khả năng kết nối qua IPv6.

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

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

Dưới đây là một kết quả mẫu.

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

Mặc dù lệnh curl đến trang web chỉ có IPv6 không thành công vì các mạng con ULA không có khả năng truy cập trực tiếp vào Internet. Lệnh curl đến trang web chỉ có IPv4 sẽ thành công vì DNS64 và NAT64 hoạt động theo cùng một cách cho các thực thể GUA và ULA; yêu cầu duy nhất là thực thể chỉ có IPv6.

Kiểm thử DNS64/NAT64 từ một phiên bản ULA có ngăn xếp kép

Trước tiên, hãy SSH vào phiên bản ULA có hai ngăn xếp "dualstack-ula-instance". Chúng ta cần sử dụng cờ "–tunnel-through-iap" để buộc gcloud sử dụng địa chỉ IPv4 cho IAP.

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

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

Bây giờ, hãy kiểm thử DNS64 bằng tiện ích "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

Lưu ý rằng trang web chỉ hỗ trợ IPv4 hiện chỉ trả về địa chỉ IPv4 chứ không còn trả về câu trả lời DNS64 tổng hợp nữa. Đó là vì DNS64 chỉ được áp dụng cho các phiên bản chỉ có IPv6 và không được đánh giá cho các phiên bản có ngăn xếp kép.

Để bỏ qua nhu cầu về DNS64, hãy thêm một mục vào tệp /etc/hosts để kiểm tra xem NAT64 có hoạt động hay không. Chạy lệnh sau trong phiên bản ngăn xếp kép:

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

Sau đó, hãy dùng curl để kiểm thử việc truy cập vào trang web ipv4 qua IPv6

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

Sau đây là kết quả mẫu của lệnh trên

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

*   Trying [64:ff9b::36c0:3326]:80...
* ipv6 connect timeout after 10000ms, move on!
* Failed to connect to v4.ipv6test.app port 80 after 10001 ms: Timeout was reached
* Closing connection 0
curl: (28) Failed to connect to v4.ipv6test.app port 80 after 10001 ms: Timeout was reached

Curl sẽ hết thời gian chờ vì giống như DNS64, NAT64 cũng yêu cầu phiên bản chỉ có IPv6 để áp dụng.

Để xác nhận rằng NAT64 không thực sự áp dụng cho phiên bản ngăn xếp kép, hãy sử dụng lệnh "get-nat-mapping" để liệt kê tất cả các ánh xạ cổng mà cổng NAT đang áp dụng. Chạy(các) lệnh sau trong cloudshell:

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

Bạn sẽ thấy kết quả tương tự như đoạn mã dưới đây:

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

Đầu ra NAT cho thấy cổng NAT64 chỉ phân bổ cổng cho các phiên bản GUA và ULA chỉ có IPv6 chứ không phải phiên bản ngăn xếp kép.

8. Dọn dẹp

Dọn dẹp Cloud Router

Trong Cloud Shell, hãy thực hiện các bước sau:

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

Huỷ liên kết và dọn dẹp chính sách DNS

Trong Cloud Shell, hãy thực hiện các bước sau:

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

Dọn dẹp các đối tượng

Trong Cloud Shell, hãy thực hiện các thao tác sau: (lưu ý: gcloud beta được dùng để cho phép chúng ta sử dụng cờ no-graceful-shutdown cho thao tác xoá phiên bản nhanh hơn)

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

Dọn dẹp mạng con

Trong Cloud Shell, hãy thực hiện các bước sau:

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

Dọn dẹp các quy tắc tường lửa

Trong Cloud Shell, hãy thực hiện các bước sau:

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

Dọn dẹp VPC

Trong Cloud Shell, hãy thực hiện các bước sau:

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

Dọn dẹp quyền IAM và Tài khoản dịch vụ

Trong Cloud Shell, hãy thực hiện các bước sau:

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. Xin chúc mừng

Bạn đã sử dụng thành công NAT64 và DNS64 để cho phép các phiên bản chỉ có IPv6 truy cập vào các đích đến chỉ có IPv4 trên Internet.

Tiếp theo là gì?

Hãy xem một số lớp học lập trình này...

Tài liệu đọc thêm và video

Tài liệu tham khảo