۱. مقدمه
یکی از چالشهای اصلی مهاجرت به 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]
معماری کلی آزمایشگاه

برای نشان دادن نحوه تعامل 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
ما متوجه سه ورودی در جدول مسیریابی میشویم
- یک مسیر /65 برای زیرشبکه GUA که نمونه به آن تعلق دارد با یک گام بعدی مشتق شده با استفاده از یک آدرس لینک-محلی برای دروازه پیشفرض. به یاد داشته باشید که /65 بالایی برای متعادلکنندههای بار شبکه عبوری IPv6 رزرو شده است.
- یک مسیر داخلی /64 برای پیشوند تکپخشی لینک-محلی fe80::/64
- یک مسیر پیشفرض که به آدرس لینک-لوکال برای دروازه پیشفرض زیرشبکه اشاره میکند.
بیایید با صدور این دستور، جدول مسیریابی 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 در اینترنت دسترسی پیدا کنند.
بعدش چی؟
به برخی از این آزمایشگاههای کد نگاهی بیندازید...
- دسترسی به APIهای گوگل از طریق میزبانهای داخلی با استفاده از آدرسهای IPv6
- گزینههای آدرسدهی IP نسخه ۴ و ۶
- استفاده از مسیرهای استاتیک IPv6 برای نمونه گام بعدی، آدرس گام بعدی و دروازه گام بعدی