ایجاد نمونه های VM فقط IPv6 و فعال کردن NAT64/DNS64

۱. مقدمه

یکی از چالش‌های اصلی مهاجرت به IPv6، حفظ دسترسی به نقاط پایانی و شبکه‌های فقط IPv4 است. یک فناوری پیشرو برای پرداختن به این چالش، ترکیب استفاده از DNS64 (تعریف شده در RFC6147) برای ترجمه رکوردهای A به رکوردهای AAAA برای کلاینت‌ها است، سپس این ترکیب با NAT64 (تعریف شده در RFC6146) برای ترجمه آدرس‌های IPv6 با فرمت خاص به IPv4 که در آن آدرس IPv4 در آدرس ویژه IPv6 تعبیه شده است، ترکیب می‌شود. این آزمایشگاه کد، کاربر را برای پیکربندی هر دو ویژگی در یک ابر خصوصی مجازی (VPC) پلتفرم ابر گوگل (GCP) راهنمایی می‌کند. هنگامی که GCP NAT64 و DNS64 با هم پیکربندی شوند، به نمونه‌های فقط IPv6 اجازه می‌دهند تا با سرورهای فقط IPv4 در اینترنت ارتباط برقرار کنند.

در این آزمایش، شما یک VPC با انواع مختلف زیرشبکه‌ها و نمونه‌های IPv6 راه‌اندازی خواهید کرد: GUA (آدرس جهانی یونی‌کست) فقط IPv6، ULA (آدرس محلی منحصر به فرد) فقط IPv6 و ULA دو پشته‌ای. سپس سرویس‌های DNS64 و NAT64 مدیریت‌شده‌ی Google Cloud را پیکربندی و آزمایش خواهید کرد تا بتوانید از طریق آنها به وب‌سایت‌های فقط IPv4 دسترسی پیدا کنید.

۲. آنچه یاد خواهید گرفت

  • نحوه ایجاد زیرشبکه‌ها و نمونه‌های فقط IPv6
  • نحوه فعال کردن سرویس DNS64 مدیریت‌شده‌ی گوگل کلود برای یک VPC
  • نحوه ایجاد یک دروازه NAT گوگل کلود پیکربندی شده برای NAT64.
  • نحوه آزمایش وضوح DNS64 از نمونه‌های فقط IPv6 به مقصدهای فقط IPv4.
  • چگونه رفتار DNS64 و NAT64 بین نمونه‌های تک پشته‌ای و دو پشته‌ای متفاوت است.
  • نحوه پیکربندی یک دروازه NAT برای NAT64.
  • نحوه آزمایش اتصال NAT64 از نمونه‌های فقط IPv6 به مقصدهای فقط IPv4.

۳. قبل از شروع

پروژه را برای پشتیبانی از codelab به‌روزرسانی کنید

این Codelab از $variables برای کمک به پیاده‌سازی پیکربندی gcloud در Cloud Shell استفاده می‌کند.

درون Cloud Shell، موارد زیر را انجام دهید

gcloud config list project
gcloud config set project [YOUR-PROJECT-ID]
export projectname=$(gcloud config list --format="value(core.project)")
export zonename=[COMPUTE ZONE NAME]
export regionname=[REGION NAME]

معماری کلی آزمایشگاه

63e4293e033da8d3.png

برای نشان دادن نحوه تعامل NAT64 و DNS64 با انواع مختلف زیرشبکه IPv6، یک VPC واحد با زیرشبکه‌های IPv6 در هر دو نوع GUA و ULA ایجاد خواهید کرد. همچنین یک زیرشبکه دو پشته‌ای (با استفاده از آدرس‌دهی ULA) ایجاد خواهید کرد تا نشان دهید که چگونه DNS64 و NAT64 برای ماشین‌های مجازی دو پشته‌ای اعمال نمی‌شوند.

سپس DNS64 و NAT64 را پیکربندی کرده و اتصال به مقاصد IPv6 و IPv4 را در اینترنت آزمایش خواهید کرد.

۴. مراحل آماده‌سازی

ابتدا، حساب کاربری سرویس، IAM، زیرساخت شبکه و نمونه‌های لازم را در پروژه Google Cloud خود راه‌اندازی کنید.

ایجاد حساب کاربری سرویس و اتصال‌های IAM

ما با ایجاد یک حساب کاربری سرویس جدید شروع می‌کنیم تا به نمونه‌ها اجازه دهیم با استفاده از gcloud از طریق SSH به یکدیگر متصل شوند. ما به این قابلیت نیاز خواهیم داشت زیرا نمی‌توانیم از IAP برای دسترسی به نمونه GUA که فقط IPv6 است استفاده کنیم و cloudshell هنوز اجازه دسترسی مستقیم به IPv6 را نمی‌دهد. دستور(های) زیر را در cloudshell اجرا کنید.

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

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

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

یک VPC ایجاد کنید و ULA را فعال کنید

با اجرای دستور (های) زیر در cloudshell، یک شبکه VPC با حالت زیرشبکه سفارشی و IPv6 داخلی ULA فعال ایجاد کنید.

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

ایجاد قوانین فایروال

قوانین فایروال را برای دسترسی به SSH ایجاد کنید. یک قانون، SSH را از محدوده کلی ULA (fd20::/20) مجاز می‌کند. دو قانون دیگر، ترافیک را از محدوده‌های از پیش تعریف شده IAP IPv6 و IPv4 (به ترتیب 2600:2d00:1:7::/64، 35.235.240.0/20) مجاز می‌دانند.

دستور(های) زیر را در cloudshell اجرا کنید:

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

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

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

ایجاد زیرشبکه‌ها

یک زیرشبکه فقط GUA نسخه ۶، یک زیرشبکه فقط ULA نسخه ۶ و یک زیرشبکه ULA دو پشته‌ای ایجاد کنید. دستور(های) زیر را در cloudshell اجرا کنید:

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

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

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

ایجاد نمونه‌ها

در هر یک از زیرشبکه‌هایی که ایجاد کرده‌اید، نمونه‌هایی ایجاد کنید. نمونه ULA فقط برای IPv6 با cloud-platform مشخص شده است تا به ما امکان دهد از آن به عنوان یک Jumpbox برای نمونه فقط برای IPv6 GUA استفاده کنیم. دستور(های) زیر را در 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

دسترسی اولیه به نمونه و راه‌اندازی

با استفاده از SSH به نمونه ULA که به طور پیش‌فرض از IAP استفاده می‌کند، متصل شوید. از دستور زیر در cloudshell برای SSH به نمونه ULA استفاده کنید:

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

<username>@ula-instance:~$ 

ما همچنین از نمونه ULA به عنوان یک Jumpbox برای نمونه GUA استفاده خواهیم کرد (زیرا IAP با نمونه‌های GUA کار نمی‌کند و ماشین‌های مجازی Cloudshell نمی‌توانند به مقصدهای IPv6 دسترسی داشته باشند).

در حالی که هنوز درون پوسته نمونه ULA هستید، با استفاده از دستور gcloud زیر، سعی کنید از طریق SSH به نمونه GUA متصل شوید.

اولین باری که یک دستور SSH را درون یک نمونه اجرا می‌کنید، از شما خواسته می‌شود که یک جفت کلید SSH تنظیم کنید. تا زمانی که کلید ایجاد شود و دستور SSH اجرا شود، کلید Enter را فشار دهید؛ این یک جفت کلید جدید بدون عبارت عبور ایجاد می‌کند.

ula-instance:~$ gcloud compute ssh gua-instance

WARNING: The private SSH key file for gcloud does not exist.
WARNING: The public SSH key file for gcloud does not exist.
WARNING: You do not have an SSH key for gcloud.
WARNING: SSH keygen will be executed to generate a key.
Generating public/private rsa key pair.

Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/galhabian/.ssh/google_compute_engine
Your public key has been saved in /home/galhabian/.ssh/google_compute_engine.pub
The key fingerprint is:
SHA256:5PYzydjcpWYiFtzetYCBI6vmy9dqyLsxgDORkB9ynqY galhabian@ula-instance
The key's randomart image is:
+---[RSA 3072]----+
|..               |
|+.o      .       |
|o= o  . + .      |
| o=    * o o     |
|+o.   . S o . o  |
|Eo . . . O + = . |
|   .=. .+ @ * .  |
|   +ooo... *     |
|    **..         |
+----[SHA256]-----+

در صورت موفقیت، دستور SSH با موفقیت اجرا شده و شما با موفقیت به نمونه GUA از طریق SSH متصل خواهید شد:

Updating instance ssh metadata...done.                                                                                                                                                                                                                                                                                            
Waiting for SSH key to propagate.
Warning: Permanently added 'compute.3639038240056074485' (ED25519) to the list of known hosts.
Linux gua-instance 6.1.0-34-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.135-1 (2025-04-25) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

<username>@gua-instance:~$ 

۵. نمونه‌های فقط IPv6 را بررسی کنید.

بیایید هر دو نمونه‌ی فقط IPv6 را با اتصال SSH به آنها و بررسی جداول مسیریابی‌شان بررسی کنیم.

بررسی نمونه GUA

ابتدا با پرش از نمونه "ula-instance" به "gua-instance" از طریق SSH وارد شوید.

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

بیایید با استفاده از دستور زیر به جدول مسیریابی IPv6 نمونه نگاه کنیم.

<username>@gua-instance:~$ ip -6 route

2600:1900:4041:461::/65 via fe80::56:11ff:fef9:88c1 dev ens4 proto ra metric 100 expires 81sec pref medium
fe80::/64 dev ens4 proto kernel metric 256 pref medium
default via fe80::56:11ff:fef9:88c1 dev ens4 proto ra metric 100 expires 81sec mtu 1500 pref medium

ما متوجه سه ورودی در جدول مسیریابی می‌شویم

  1. یک مسیر /65 برای زیرشبکه GUA که نمونه به آن تعلق دارد با یک گام بعدی مشتق شده با استفاده از یک آدرس لینک-محلی برای دروازه پیش‌فرض. به یاد داشته باشید که /65 بالایی برای متعادل‌کننده‌های بار شبکه عبوری IPv6 رزرو شده است.
  2. یک مسیر داخلی /64 برای پیشوند تک‌پخشی لینک-محلی fe80::/64
  3. یک مسیر پیش‌فرض که به آدرس لینک-لوکال برای دروازه پیش‌فرض زیرشبکه اشاره می‌کند.

بیایید با صدور این دستور، جدول مسیریابی IPv4 را بررسی کنیم.

<username>@gua-instance:~$ ip -4 route

default via 169.254.1.1 dev ens4 proto dhcp src 169.254.1.2 metric 100 
169.254.1.1 dev ens4 proto dhcp scope link src 169.254.1.2 metric 100 
169.254.169.254 via 169.254.1.1 dev ens4 proto dhcp src 169.254.1.2 metric 100

تعجب‌آور است؟ در واقع، ما در نمونه‌های فقط IPv6، یک جدول مسیریابی IPv4 را صرفاً برای دسترسی به سرور Compute Metadata (169.254.169.154) نگه می‌داریم، زیرا هنوز یک نقطه پایانی فقط IPv4 است.

از آنجایی که این نمونه، زمانی که فقط از IPv6 پشتیبانی می‌کند، آدرس IP 169.254.1.2 را می‌گیرد. این IP به هیچ جای دیگری جز سرور Compute Metadata قابل مسیریابی نیست، بنابراین این نمونه عملاً از تمام شبکه‌های IPv4 ایزوله شده است.

تست‌های کرل

بیایید اتصال واقعی به وب‌سایت‌های فقط نسخه ۴ و فقط نسخه ۶ را با استفاده از curl آزمایش کنیم.

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

در زیر یک نمونه خروجی آمده است.

<username>@gua-instance:~$ curl -vv --connect-timeout 10 v6.ipv6test.app
*   Trying [2600:9000:20be:cc00:9:ec55:a1c0:93a1]:80...
* Connected to v6.ipv6test.app (2600:9000:20be:cc00:9:ec55:a1c0:93a1) port 80 (#0)
> GET / HTTP/1.1
> Host: v6.ipv6test.app
> User-Agent: curl/7.88.1
> Accept: */*
> 
< HTTP/1.1 200 OK
!! Rest of output truncated

<username>@gua-instance:~$ curl -vv --connect-timeout 10 v4.ipv6test.app
*   Trying 3.163.165.4:80...
* ipv4 connect timeout after 4985ms, move on!
*   Trying 3.163.165.50:80...
* ipv4 connect timeout after 2492ms, move on!
*   Trying 3.163.165.127:80...
* ipv4 connect timeout after 1246ms, move on!
*   Trying 3.163.165.37:80...
* ipv4 connect timeout after 1245ms, move on!
* Failed to connect to v4.ipv6test.app port 80 after 10000 ms: Timeout was reached
* Closing connection 0
curl: (28) Failed to connect to v4.ipv6test.app port 80 after 10000 ms: Timeout was reached

همانطور که انتظار می‌رود، هیچ دسترسی به یک نقطه پایانی اینترنت IPv4 از یک نمونه فقط IPv6 وجود ندارد. بدون تأمین DNS64 و NAT64، نمونه فقط IPv6 هیچ مسیری به مقصد IPv4 ندارد. دسترسی به یک مقصد IPv6 به طور معمول زمانی کار می‌کند که نمونه دارای آدرس GUA IPv6 باشد.

بررسی نمونه ULA

از طریق SSH به نمونه "ula-instance" متصل شوید (به طور پیش‌فرض از IAP استفاده می‌کند).

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

بیایید با استفاده از دستور زیر به جدول مسیریابی IPv6 نمونه نگاه کنیم.

<username>@ula-instance:~$ ip -6 route

fd20:f06:2e5e:2000::/64 via fe80::55:82ff:fe6b:1d7 dev ens4 proto ra metric 100 expires 84sec pref medium
fe80::/64 dev ens4 proto kernel metric 256 pref medium
default via fe80::55:82ff:fe6b:1d7 dev ens4 proto ra metric 100 expires 84sec mtu 1500 pref medium

ما متوجه سه ورودی در جدول مسیریابی می‌شویم، مشابه نمونه GUA، با این تفاوت که ماسک به جای /65، /64 است. و مسیر زیرشبکه متعلق به یک محدوده ULA است. (تحت مجموع fd20::/20)

بیایید با صدور این دستور، جدول مسیریابی IPv4 را بررسی کنیم.

<username>@ula-instance:~$ ip -4 route

default via 169.254.1.1 dev ens4 proto dhcp src 169.254.1.2 metric 100 
169.254.1.1 dev ens4 proto dhcp scope link src 169.254.1.2 metric 100 
169.254.169.254 via 169.254.1.1 dev ens4 proto dhcp src 169.254.1.2 metric 100

که وضعیت مشابهی را با نمونه GUA نشان می‌دهد.

تست‌های کرل

تکرار تست‌های اتصال به وب‌سایت‌های فقط نسخه ۴ و فقط نسخه ۶ با استفاده از curl.

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

در زیر یک نمونه خروجی آمده است.

<username>@ula-instance:~$ curl -vv --connect-timeout 10 v6.ipv6test.app
*   Trying [2600:9000:20be:8400:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 4986ms, move on!
*   Trying [2600:9000:20be:9000:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 2493ms, move on!
*   Trying [2600:9000:20be:d600:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 1246ms, move on!
*   Trying [2600:9000:20be:b000:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 622ms, move on!
*   Trying [2600:9000:20be:7200:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 312ms, move on!
*   Trying [2600:9000:20be:8600:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 155ms, move on!
*   Trying [2600:9000:20be:7a00:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 77ms, move on!
*   Trying [2600:9000:20be:ce00:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 77ms, move on!
* Failed to connect to v6.ipv6test.app port 80 after 10000 ms: Timeout was reached
* Closing connection 0

<username>@ula-instance:~$ curl -vv --connect-timeout 10 v4.ipv6test.app
*   Trying 3.163.165.4:80...
* ipv4 connect timeout after 4985ms, move on!
*   Trying 3.163.165.50:80...
* ipv4 connect timeout after 2492ms, move on!
*   Trying 3.163.165.127:80...
* ipv4 connect timeout after 1246ms, move on!
*   Trying 3.163.165.37:80...
* ipv4 connect timeout after 1245ms, move on!
* Failed to connect to v4.ipv6test.app port 80 after 10000 ms: Timeout was reached
* Closing connection 0
curl: (28) Failed to connect to v4.ipv6test.app port 80 after 10000 ms: Timeout was reached

در مورد نمونه ULA، هیچ دسترسی به هر دو نقطه پایانی اینترنت وجود ندارد زیرا برای نقطه پایانی IPv6 نمی‌توانیم از آدرس ULA برای برقراری ارتباط استفاده کنیم و این نمونه به عنوان یک نمونه فقط IPv6، هیچ دسترسی به IPv4 ندارد.

۶. فعال کردن NAT64 و DNS64

سرویس‌های مدیریت‌شده DNS64 و NAT64 را برای VPC خود پیکربندی کنید.

دی‌ان‌اس۶۴

سیاست DNS64 Server را برای VPC خود فعال کنید. این به تحلیلگر DNS VPC می‌گوید که رکوردهای AAAA را برای پاسخ‌های فقط A ترکیب کند. دستور (های) زیر را در cloudshell اجرا کنید:

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

NAT64

یک روتر ابری ایجاد کنید که برای Cloud NAT مورد نیاز است. سپس، یک دروازه Cloud NAT پیکربندی شده برای NAT64 ایجاد کنید، آن را برای همه محدوده‌های IP زیرشبکه فقط IPv6 و تخصیص خودکار IPهای خارجی فعال کنید. دستور(های) زیر را در cloudshell اجرا کنید:

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


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

۷. تست NAT64 و DNS64

حال، بیایید پیکربندی NAT64 و DNS64 شما را از نمونه‌های فقط IPv6 آزمایش کنیم، که با نمونه GUA و به دنبال آن نمونه ULA شروع می‌شود.

تست DNS64/NAT64 از یک نمونه GUA

ابتدا با پرش از نمونه "ula-instance" به "gua-instance" از طریق SSH وارد شوید.

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

تست‌های DNS

تست وضوح DNS یک وب‌سایت فقط با IPv6 (مثلاً v6.ipv6test.app اما هر وب‌سایت فقط با IPv6 باید نتیجه مشابهی داشته باشد).

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

ما انتظار داریم فقط پاسخ‌های IPv6 AAAA برگردانده شوند.

خروجی مثال

<username>@gua-instance:~$ host -t AAAA v6.ipv6test.app
v6.ipv6test.app has IPv6 address 2600:9000:269f:1000:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:6600:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:b600:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:3e00:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:9c00:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:b200:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:a600:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:1400:9:ec55:a1c0:93a1

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

تست DNS resolution یک وب‌سایت فقط IPv4 (مثلاً v4.ipv6test.app). انتظار می‌رود هم یک رکورد A (IPv4 اصلی) و هم یک رکورد AAAA که توسط DNS64 با استفاده از پیشوند معروف 64:ff9b::/96 ترکیب شده است، وجود داشته باشد.

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

خروجی مثال

<username>@gua-instance:~$ host -t AAAA v4.ipv6test.app
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:3318
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:3344
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:333c
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:3326

<username>@gua-instance:~$ host -t A v4.ipv6test.app
v4.ipv6test.app has address 54.192.51.68
v4.ipv6test.app has address 54.192.51.24
v4.ipv6test.app has address 54.192.51.60
v4.ipv6test.app has address 54.192.51.38

در مثال بالا، آدرس IPv4 (54.192.51.38) در مبنای ده به (36 c0 33 26) در مبنای شانزده تبدیل می‌شود و از این رو انتظار داریم پاسخی برای رکورد AAAA به صورت (64:ff9b::36c0:3326) باشد که با یکی از پاسخ‌های AAAA دریافتی ما مطابقت دارد.

تست‌های کرل

بیایید اتصال واقعی به همان نقاط پایانی فقط v4 و فقط v6 را با استفاده از curl روی IPv6 آزمایش کنیم.

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

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

در زیر یک نمونه خروجی آمده است.

<username>@gua-instance:~$ curl -vv -6 v6.ipv6test.app
*   Trying [2600:9000:269f:1000:9:ec55:a1c0:93a1]:80...
* Connected to v6.ipv6test.app (2600:9000:269f:1000:9:ec55:a1c0:93a1) port 80 (#0)
> GET / HTTP/1.1

##
## <Output truncated for brevity>
##

<username>@gua-instance:~$ curl -vv -6 v4.ipv6test.app
*   Trying [64:ff9b::36c0:333c]:80...
* Connected to v4.ipv6test.app (64:ff9b::36c0:333c) port 80 (#0)
> GET / HTTP/1.1

##
## <Output truncated for brevity>
##

هر دو دستور curl با موفقیت اجرا شدند. توجه کنید که چگونه اتصال به یک وب‌سایت فقط IPv4 از طریق IPv6 به دلیل همکاری NAT64 و DNS64 برای فعال کردن موفقیت‌آمیز اتصال امکان‌پذیر شد.

بررسی آی‌پی‌های مبدا

بیایید از یک سرویس انعکاس IP برای بررسی IP منبع مشاهده شده توسط مقصد استفاده کنیم.

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

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

خروجی نمونه

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

<username>@gua-instance:~$ curl -6 v6.ipv6test.app
2600:1900:40e0:6f:0:1::

آدرس IPv6 گزارش شده باید با آدرس IPv6 نمونه مطابقت داشته باشد. این آدرس باید با خروجی دستور "ip -6 address" در نمونه مطابقت داشته باشد. به عنوان مثال

<username>@gua-instance:~$ ip -6 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 2600:1900:40e0:6f:0:1::/128 scope global dynamic noprefixroute
       valid_lft 79912sec preferred_lft 79912sec
    inet6 fe80::86:d9ff:fe34:27ed/64 scope link
       valid_lft forever preferred_lft forever

با این حال، آدرس IPv4 گزارش شده باید با آدرس IP خارجی دروازه Cloud NAT مطابقت داشته باشد، زیرا قبل از اتصال به اینترنت، عملکرد NAT64 را انجام می‌دهد. این موضوع را می‌توان با اجرای این دستور gcloud در cloudshell تأیید کرد.

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

خروجی نمونه

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

توجه داشته باشید که "natIp" گزارش شده در خروجی با خروجی دریافتی از وب‌سایت IP reflection مطابقت دارد.

تست DNS64/NAT64 از یک نمونه ULA

ابتدا، به نمونه ULA با نام "ula-instance" از طریق SSH متصل شوید.

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

<username>@ula-instance:~$

تست‌های DNS

تست وضوح DNS یک وب‌سایت فقط با IPv6 (مثلاً v6.ipv6test.app اما هر وب‌سایت فقط با IPv6 باید نتیجه مشابهی داشته باشد).

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

ما انتظار داریم فقط پاسخ‌های IPv6 AAAA برگردانده شوند.

خروجی مثال

<username>@ula-instance:~$ host -t AAAA v6.ipv6test.app
v6.ipv6test.app has IPv6 address 2600:9000:269f:1000:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:6600:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:b600:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:3e00:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:9c00:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:b200:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:a600:9:ec55:a1c0:93a1
v6.ipv6test.app has IPv6 address 2600:9000:269f:1400:9:ec55:a1c0:93a1

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

تست DNS resolution یک وب‌سایت فقط IPv4 (مثلاً v4.ipv6test.app). انتظار می‌رود هم یک رکورد A (IPv4 اصلی) و هم یک رکورد AAAA که توسط DNS64 با استفاده از پیشوند معروف 64:ff9b::/96 ترکیب شده است، وجود داشته باشد.

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

خروجی مثال

<username>@gua-instance:~$ host -t AAAA v4.ipv6test.app
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:3318
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:3344
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:333c
v4.ipv6test.app has IPv6 address 64:ff9b::36c0:3326

<username>@gua-instance:~$ host -t A v4.ipv6test.app
v4.ipv6test.app has address 54.192.51.68
v4.ipv6test.app has address 54.192.51.24
v4.ipv6test.app has address 54.192.51.60
v4.ipv6test.app has address 54.192.51.38

در مثال بالا، آدرس IPv4 (54.192.51.38) در مبنای ده به (36 c0 33 26) در مبنای شانزده تبدیل می‌شود و از این رو انتظار داریم پاسخی برای رکورد AAAA به صورت (64:ff9b::36c0:3326) باشد که با یکی از پاسخ‌های AAAA دریافتی ما مطابقت دارد.

تست‌های کرل

بیایید اتصال واقعی به همان نقاط پایانی فقط v4 و فقط v6 را با استفاده از curl آزمایش کنیم.

به عنوان نقطه شروع، نشان می‌دهیم که دسترسی‌پذیری از طریق IPv4 امکان‌پذیر نیست، زیرا نمونه مورد نظر، فقط از 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

در حالی که هر دو curl با شکست مواجه می‌شوند. آنها به دلایل مختلف با شکست مواجه می‌شوند. در زیر یک نمونه خروجی آمده است.

<username>@ula-instance:~$ curl -vv -4 v6.ipv6test.app
* Could not resolve host: v6.ipv6test.app
* Closing connection 0
curl: (6) Could not resolve host: v6.ipv6test.app

<username>@ula-instance:~$ curl -vv -4 --connect-timeout 10 v4.ipv6test.app
*   Trying 54.192.51.68:80...
* ipv4 connect timeout after 4993ms, move on!
*   Trying 54.192.51.38:80...
* ipv4 connect timeout after 2496ms, move on!
*   Trying 54.192.51.24:80...
* ipv4 connect timeout after 1248ms, move on!
*   Trying 54.192.51.60:80...
* Connection timeout after 10000 ms
* Closing connection 0
curl: (28) Connection timeout after 10000 ms

اتصال IPv4 به یک نقطه پایانی فقط IPv6 با شکست مواجه می‌شود زیرا تجزیه و تحلیل DNS برای رکورد A با شکست مواجه می‌شود (همانطور که در آزمایش‌های DNS نشان داده شد). اتصال IPv4 به یک نقطه پایانی فقط IPv4 با شکست مواجه می‌شود زیرا یک نمونه فقط IPv6 هیچ دسترسی به هیچ آدرس IPv4 ندارد و به همین دلیل با وقفه زمانی مواجه می‌شویم.

حالا بیایید قابلیت دسترسی را روی IPv6 آزمایش کنیم.

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

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

در زیر یک نمونه خروجی آمده است.

<username>@ula-instance:~$ curl -vv -6 v6.ipv6test.app
*   Trying [2600:9000:20be:c000:9:ec55:a1c0:93a1]:80...
* connect to 2600:9000:20be:c000:9:ec55:a1c0:93a1 port 80 failed: Connection timed out
*   Trying [2600:9000:20be:f000:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 84507ms, move on!
*   Trying [2600:9000:20be:ae00:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 42253ms, move on!
*   Trying [2600:9000:20be:2000:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 21126ms, move on!
*   Trying [2600:9000:20be:b600:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 10563ms, move on!
*   Trying [2600:9000:20be:7600:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 5282ms, move on!
*   Trying [2600:9000:20be:b000:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 2640ms, move on!
*   Trying [2600:9000:20be:3400:9:ec55:a1c0:93a1]:80...
* ipv6 connect timeout after 2642ms, move on!
* Failed to connect to v6.ipv6test.app port 80 after 300361 ms: Timeout was reached
* Closing connection 0

<username>@ula-instance:~$ curl -vv -6 v4.ipv6test.app
*   Trying [64:ff9b::36c0:333c]:80...
* Connected to v4.ipv6test.app (64:ff9b::36c0:333c) port 80 (#0)
> GET / HTTP/1.1

##
## <Output truncated for brevity>
##

در حالی که curl به وب‌سایت فقط IPv6 با شکست مواجه می‌شود زیرا زیرشبکه‌های ULA دسترسی مستقیم به اینترنت ندارند، curl به وب‌سایت فقط IPv4 با موفقیت انجام می‌شود زیرا DNS64 و NAT64 برای نمونه‌های GUA و ULA به یک شکل عمل می‌کنند؛ تنها شرط لازم این است که نمونه فقط IPv6 باشد.

تست DNS64/NAT64 از یک نمونه ULA دو پشته‌ای

ابتدا، از طریق SSH به نمونه Dual-Stack ULA با نام "dualstack-ula-instance" متصل شوید. برای اینکه gcloud را مجبور به استفاده از آدرس IPv4 برای IAP کنیم، باید از فلگ "–tunnel-through-iap" استفاده کنیم.

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

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

بیایید اکنون DNS64 را با استفاده از ابزار "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

توجه کنید که وب‌سایت فقط IPv4 اکنون فقط آدرس‌های IPv4 را برمی‌گرداند و دیگر پاسخ‌های مصنوعی DNS64 را برنمی‌گرداند. دلیل این امر این است که DNS64 فقط برای نمونه‌های فقط IPv6 اعمال می‌شود و برای نمونه‌های دو پشته‌ای ارزیابی نمی‌شود.

برای رفع نیاز به DNS64، بیایید یک ورودی به فایل /etc/hosts اضافه کنیم تا بررسی کنیم که آیا NAT64 کار می‌کند یا خیر. دستور زیر را در نمونه‌ی دو پشته‌ای اجرا کنید:

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

سپس بیایید از curl برای آزمایش دسترسی به وب‌سایت ipv4 از طریق IPv6 استفاده کنیم.

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

این هم نمونه خروجی دستور بالا

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

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

حلقه باید زمان‌بندی شود زیرا درست مانند DNS64، NAT64 نیز برای اعمال شدن نیاز به این دارد که نمونه فقط IPv6 باشد.

برای تأیید اینکه NAT64 در واقع روی نمونه‌ی دو پشته‌ای اعمال نمی‌شود، بیایید از دستور "get-nat-mapping" برای فهرست کردن تمام نگاشت‌های پورت که NAT gateway اعمال می‌کند، استفاده کنیم. دستور(های) زیر را در cloudshell اجرا کنید:

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

شما باید انتظار خروجی مشابه قطعه کد زیر را داشته باشید:

---
instanceName: gua-instance
interfaceNatMappings:
- natIpPortRanges:
  - 34.47.60.91:1024-1055
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  sourceAliasIpRange: ''
  sourceVirtualIp: '2600:1900:40e0:6f:0:1::'
- natIpPortRanges:
  - 34.47.60.91:32768-32799
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  sourceAliasIpRange: ''
  sourceVirtualIp: '2600:1900:40e0:6f:0:1::'
---
instanceName: ula-instance
interfaceNatMappings:
- natIpPortRanges:
  - 34.47.60.91:1056-1087
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  sourceAliasIpRange: ''
  sourceVirtualIp: fd20:9c2:93fc:2800:0:0:0:0
- natIpPortRanges:
  - 34.47.60.91:32800-32831
  numTotalDrainNatPorts: 0
  numTotalNatPorts: 32
  sourceAliasIpRange: ''
  sourceVirtualIp: fd20:9c2:93fc:2800:0:0:0:0

خروجی NAT نشان می‌دهد که دروازه NAT64 فقط پورت‌هایی را برای نمونه‌های GUA و ULA که فقط IPv6 هستند اختصاص داده است، اما برای نمونه دو پشته‌ای این کار را نکرده است.

۸. تمیز کردن

روتر ابری را تمیز کنید

درون Cloud Shell، موارد زیر را انجام دهید:

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

رفع انسداد و پاکسازی خط‌مشی DNS

درون Cloud Shell، موارد زیر را انجام دهید:

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

موارد پاکسازی

درون Cloud Shell، موارد زیر را انجام دهید: (توجه داشته باشید، gcloud beta برای این استفاده می‌شود که بتوانیم از پرچم no-graceful-shutdown برای عملیات حذف سریع‌تر نمونه استفاده کنیم)

gcloud beta compute instances delete gua-instance \
         --zone $zonename \
         --no-graceful-shutdown \
         --project=$projectname --quiet

gcloud beta compute instances delete ula-instance \
         --zone $zonename \
         --no-graceful-shutdown \
         --project=$projectname --quiet

gcloud beta compute instances delete dualstack-ula-instance \
         --zone $zonename \
         --no-graceful-shutdown \
         --project=$projectname --quiet

پاکسازی زیرشبکه‌ها

درون Cloud Shell، موارد زیر را انجام دهید:

gcloud compute networks subnets delete gua-v6only-subnet \
    --project=$projectname --quiet \
    --region=$regionname
 
gcloud compute networks subnets delete ula-v6only-subnet \
    --project=$projectname --quiet \
    --region=$regionname

gcloud compute networks subnets delete ula-dualstack-subnet \
    --project=$projectname --quiet \
    --region=$regionname

پاک کردن قوانین فایروال

درون Cloud Shell، موارد زیر را انجام دهید:

gcloud compute firewall-rules delete allow-v6-iap \
       --project=$projectname \
       --quiet

gcloud compute firewall-rules delete allow-v6-ssh-ula \
       --project=$projectname \
       --quiet

gcloud compute firewall-rules delete allow-v4-iap \
--project=$projectname \
--quiet

وی پی سی را تمیز کنید

درون Cloud Shell، موارد زیر را انجام دهید:

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

مجوزهای IAM و حساب سرویس را پاک کنید

درون Cloud Shell، موارد زیر را انجام دهید:

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

gcloud iam service-accounts delete \
     ipv6-codelab@$projectname.iam.gserviceaccount.com \
     --quiet \
     --project $projectname

۹. تبریک

شما با موفقیت از NAT64 و DNS64 استفاده کردید تا به نمونه‌های فقط IPv6 اجازه دهید به مقاصد فقط IPv4 در اینترنت دسترسی پیدا کنند.

بعدش چی؟

به برخی از این آزمایشگاه‌های کد نگاهی بیندازید...

مطالعه بیشتر و ویدیوها

اسناد مرجع