יצירת מכונות וירטואליות עם IPv6 בלבד והפעלת NAT64/DNS64

1. מבוא

אחד האתגרים העיקריים במעבר ל-IPv6 הוא שמירה על נגישות לנקודות קצה ולרשתות עם IPv4 בלבד. אחת מהטכנולוגיות המובילות להתמודדות עם האתגר הזה היא שילוב של שימוש ב-DNS64 (מוגדר ב-RFC6147) כדי לתרגם רשומות A לרשומות AAAA עבור לקוחות, ואז שילוב של NAT64 (מוגדר ב-RFC6146) כדי לתרגם כתובות IPv6 בפורמט מיוחד ל-IPv4, כאשר כתובת ה-IPv4 מוטמעת בכתובת ה-IPv6 המיוחדת. בשיעור הזה נסביר איך להגדיר את שני התכונות בענן וירטואלי פרטי (VPC) ב-Google Cloud Platform ‏ (GCP). כשמגדירים את GCP NAT64 ו-DNS64 ביחד, מכונות עם IPv6 בלבד יכולות לתקשר עם שרתים עם IPv4 בלבד באינטרנט.

בשיעור ה-Lab הזה תגדירו רשת VPC עם סוגים שונים של תת-רשתות ומופעים של IPv6 : ‏ GUA (כתובת גלובלית של יוניקאסט) רק ל-IPv6,‏ ULA (כתובת מקומית ייחודית) רק ל-IPv6 ו-ULA עם פרוטוקול כפול. לאחר מכן, תגדירו ותבדקו את שירותי ה-DNS64 וה-NAT64 המנוהלים של Google Cloud כדי לגשת מהם לאתרים עם IPv4 בלבד.

2. מה תלמדו

  • איך יוצרים רשתות משנה ומכונות עם כתובות IPv6 בלבד
  • איך מפעילים את שירות ה-DNS64 המנוהל של Google Cloud עבור VPC .
  • איך ליצור שער Cloud NAT שמוגדר ל-NAT64 .
  • איך בודקים תרגום DNS64 ממכונות עם IPv6 בלבד ליעדים עם IPv4 בלבד.
  • איך ההתנהגות של DNS64 ו-NAT64 שונה בין מקרים של מחסנית יחידה לבין מקרים של מחסנית כפולה.
  • איך מגדירים שער NAT ל-NAT64.
  • איך בודקים קישוריות NAT64 ממופעי IPv6 בלבד ליעדים של IPv4 בלבד.

3. לפני שמתחילים

עדכון הפרויקט כדי לתמוך ב-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]

ארכיטקטורת Lab כוללת

63e4293e033da8d3.png

כדי להדגים איך NAT64 ו-DNS64 פועלים עם סוגים שונים של תת-רשתות IPv6, תיצרו רשת VPC אחת עם תת-רשתות IPv6 בפורמטים GUA ו-ULA. בנוסף, תיצרו רשת משנה עם פרוטוקול כפול (באמצעות כתובות ULA) כדי להדגים איך DNS64 ו-NAT64 לא חלים על מכונות וירטואליות עם פרוטוקול כפול.

לאחר מכן תגדירו DNS64 ו-NAT64 ותבדקו את הקישוריות ליעדי IPv6 ו-IPv4 באינטרנט.

4. שלבי ההכנה

קודם צריך להגדיר את חשבון השירות, IAM, תשתית הרשת והמופעים הנדרשים בפרויקט Google Cloud.

יצירה של חשבון שירות ושל הרשאות IAM

מתחילים ביצירת חשבון שירות חדש כדי לאפשר למכונות להתחבר זו לזו באמצעות SSH באמצעות gcloud. אנחנו נצטרך את היכולת הזו כי אי אפשר להשתמש ב-IAP כדי לגשת למופע GUA שהוא רק IPv6, ו-Cloud Shell עדיין לא מאפשר גישה ישירה ל-IPv6. מריצים את הפקודות הבאות ב-Cloud Shell.

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

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

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

יצירת VPC והפעלת ULA

כדי ליצור רשת VPC עם מצב תת-רשת מותאם אישית וכתובות IPv6 פנימיות מסוג ULA, מריצים את הפקודות הבאות ב-Cloud Shell.

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). שני כללים נוספים מאפשרים תעבורה מטווחים מוגדרים מראש של IPv6 ו-IPv4 ב-IAP (‎2600:2d00:1:7::/64 ו-‎35.235.240.0/20 בהתאמה).

מריצים את הפקודות הבאות ב-Cloud Shell:

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

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

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

יצירת רשתות משנה

יוצרים תת-רשת GUA v6 בלבד, תת-רשת ULA v6 בלבד ותת-רשת ULA עם מחסנית כפולה. מריצים את הפקודות הבאות ב-Cloud Shell:

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

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

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

יצירת מופעים

יוצרים מכונות בכל אחת מרשתות המשנה שיצרתם. מופע ULA עם IPv6 בלבד מצוין באמצעות cloud-platform כדי לאפשר לנו להשתמש בו כ-jumpbox למופע GUA עם IPv6 בלבד. מריצים את הפקודות הבאות ב-Cloud Shell:

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

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

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

גישה ראשונית למופע והגדרה

מתחברים עם SSH למופע ULA שישתמש ב-IAP כברירת מחדל. כדי להתחבר באמצעות SSH למופע ULA, מריצים את הפקודה הבאה ב-Cloud Shell:

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

<username>@ula-instance:~$ 

נשתמש גם במופע ULA כ-jumpbox למופע GUA (כי IAP לא פועל עם מופעי GUA, ולמכונות וירטואליות ב-Cloudshell אין גישה ליעדי IPv6).

עדיין בתוך מעטפת מופע ULA. מנסים להשתמש ב-SSH כדי להתחבר למופע GUA באמצעות פקודת gcloud הבאה.

בפעם הראשונה שמריצים פקודת SSH בתוך מופע, מוצגת בקשה להגדיר צמד מפתחות SSH. ממשיכים ללחוץ על Enter עד שהמפתח נוצר ופקודת ה-SSH מופעלת. כך נוצר זוג מפתחות חדש ללא סיסמה.

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:

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. בדיקה של מכונות שהוקצו להן רק כתובות IPv6.

נבדוק את שתי המכונות הווירטואליות עם IPv6 בלבד באמצעות SSH ונבחן את טבלאות הניתוב שלהן.

בדיקת מופע GUA

מתחברים ל-SSH ב-gua-instance באמצעות דילוג דרך המופע ula-instance.

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

מפתיע? למעשה, אנחנו מתחזקים טבלת ניתוב של IPv4 במופעים של IPv6 בלבד, אך ורק כדי לאפשר גישה לשרת המטא-נתונים של Compute (169.254.169.154), כי הוא עדיין נקודת קצה של IPv4 בלבד.

כי המופע מקבל את כתובת ה-IP‏ 169.254.1.2 כשהוא מופע IPv6 בלבד. אי אפשר לנתב את כתובת ה-IP הזו לשום מקום מלבד לשרת המטא-נתונים של Compute, ולכן המכונה מבודדת למעשה מכל רשתות IPv4.

בדיקות Curl

נבדוק את החיבור בפועל לאתרים עם IPv4 בלבד ולאתרים עם IPv6 בלבד באמצעות 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, אבל המסכה היא ‎ /64 במקום ‎ /65. ונתיב תת-הרשת שייך לטווח 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

חזרה על בדיקות הקישוריות לאתרים עם IPv4 בלבד ולאתרים עם IPv6 בלבד באמצעות 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 כדי לתקשר החוצה, ולמופע אין אפשרות להגיע ל-IPv4 כי הוא מופע IPv6 בלבד.

6. הפעלת NAT64 ו-DNS64

מגדירים את שירותי ה-DNS64 וה-NAT64 המנוהלים עבור ה-VPC.

DNS64

מפעילים את מדיניות שרת DNS64 עבור ה-VPC . ההגדרה הזו אומרת לפתרון ה-DNS של ה-VPC ליצור רשומות AAAA לתשובות מסוג A בלבד. מריצים את הפקודות הבאות ב-Cloud Shell:

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

NAT64

יוצרים Cloud Router, שנדרש ל-Cloud NAT . לאחר מכן, יוצרים שער Cloud NAT שמוגדר ל-NAT64, ומפעילים אותו לכל טווחי כתובות ה-IP של רשתות המשנה שהן IPv6 בלבד, ומקצים באופן אוטומטי כתובות IP חיצוניות. מריצים את הפקודות הבאות ב-Cloud Shell:

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


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

7. בדיקת NAT64 ו-DNS64

עכשיו נבדוק את ההגדרה של NAT64 ו-DNS64 מהמופעים של IPv6 בלבד, החל מהמופע של GUA ואחריו המופע של ULA.

בדיקת DNS64/NAT64 ממופע GUA

מתחברים ל-SSH ב-gua-instance באמצעות דילוג דרך המופע ula-instance.

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 של אתר 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 שקיבלנו.

בדיקות Curl

בואו נבדוק את הקישוריות בפועל לאותן נקודות קצה v4-only ו-v6-only באמצעות 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 כדי לבדוק את כתובת ה-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 הזו ב-Cloud Shell

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.

בדיקת DNS64/NAT64 ממופע ULA

קודם כל, מתחברים באמצעות SSH למופע ULA‏ ula-instance

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 של אתר 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 שקיבלנו.

בדיקות Curl

נבדוק את הקישוריות בפועל לאותן נקודות קצה עם IPv4 בלבד ועם IPv6 בלבד באמצעות 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

הפקודה curl של IPv4 לנקודת קצה של IPv6 בלבד נכשלת כי רזולוציית ה-DNS של רשומת ה-A נכשלת (כפי שמוצג במהלך בדיקות ה-DNS). הפקודה curl של IPv4 לנקודת קצה של IPv4 בלבד נכשלת כי למכונה של IPv6 בלבד אין אפשרות להגיע לכתובת IPv4 כלשהי, ולכן מתקבל פסק זמן.

עכשיו נבדוק את יכולת ההגעה (reachability) דרך 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 עם Dual-Stack

קודם כל, מתחברים באמצעות SSH למכונת ה-ULA עם כתובות IPv4 ו-IPv6 ‏dualstack-ula-instance. אנחנו צריכים להשתמש בדגל ‎–tunnel-through-iap כדי לאלץ את gcloud להשתמש בכתובת IPv4 עבור 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 בלבד, ולא על מקרים שבהם נעשה שימוש ב-dual-stack.

כדי לעקוף את הצורך ב-DNS64, נוסיף רשומה לקובץ ‎ /etc/hosts כדי לבדוק אם NAT64 פועל. מריצים את הפקודה הבאה בתוך מופע עם תמיכה ב-IPv4 ו-IPv6:

<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

הפקודה curl אמורה להגיע לזמן קצוב לתפוגה (timeout), כי כמו DNS64, גם NAT64 דורש שהמופע יהיה IPv6 בלבד כדי להחיל אותו.

כדי לוודא ש-NAT64 לא חל על מופע עם תמיכה כפולה ב-IPv4 ו-IPv6, נשתמש בפקודה get-nat-mapping כדי להציג את כל מיפויי היציאות ששער ה-NAT מחיל. מריצים את הפקודות הבאות ב-Cloud Shell:

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 בלבד, אבל לא למופע dual-stack.

8. הסרת המשאבים

ניקוי של Cloud Router

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

ניקוי ה-VPC

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

9. מזל טוב

השתמשתם בהצלחה ב-NAT64 וב-DNS64 כדי לאפשר למופעים עם IPv6 בלבד להגיע ליעדים עם IPv4 בלבד באינטרנט.

מה השלב הבא?

כדאי לעיין בכמה מה-codelabs האלה…

קריאה נוספת וסרטונים

מסמכי עזר