Private Service Connect: استخدام خلفية PSC للوصول إلى واجهات Google APIs الإقليمية

1. مقدمة

‫Private Service Connect هي إحدى إمكانات شبكات Google Cloud التي تتيح للمستهلكين الوصول إلى خدمات مقدّمي الخدمات. ويشمل ذلك إمكانية الاتصال بواجهات Google APIs من خلال نقطة نهاية خاصة مستضافة داخل شبكة VPC الخاصة بالمستخدم(عادةً ما تكون شبكة المستهلك).

بالإضافة إلى ذلك، يمكن استخدام PSC Backends مع موازنات تحميل وكيل Google Cloud للإشارة إلى واجهات Google APIs الخاصة بمنطقة معيّنة. يتيح استخدام PSC Backends عناصر تحكّم أكثر دقة من جهة المستهلك، مثل:

  • اختيار خدمات Google API المتاحة باستخدام "خريطة عناوين URL"
  • إمكانية تتبُّع البيانات بشكلٍ أكثر تفصيلاً
  • دمج Cloud Armor
  • عناوين URL المخصّصة
  • إدارة الزيارات المتقدّمة

يمكنك الاطّلاع على قائمة بالخدمات المتاحة وواجهات برمجة التطبيقات الإقليمية الخاصة بها هنا.

في هذا الدرس التطبيقي، ستنشئ خلفية PSC تشير إلى واجهة برمجة التطبيقات الإقليمية Cloud KMS API وتختبر إمكانية الاتصال بهذه الواجهة.

أهداف الدورة التعليمية

  • أنشئ سلسلة مفاتيح ومفتاحًا في Cloud Key Management Service (KMS).
  • إنشاء جهاز موازنة حمل داخلي للتطبيقات مع خلفية PSC تشير إلى واجهة برمجة تطبيقات إقليمية في Cloud KMS
  • إنشاء منطقة خاصة مُدارة وسجلّ A في Cloud DNS
  • الوصول إلى Cloud KMS الإقليمي

المتطلبات

  • مشروع Google Cloud لديه أذونات "المالك" أو "المحرّر" الكاملة

2. بنية الدروس التطبيقية حول الترميز

1a18ae253213e215.png

سيتم إنشاء شبكة VPC للمستهلك مع شبكة فرعية واحدة في منطقة europe-west9 لاستضافة جهاز افتراضي وقاعدة إعادة التوجيه الخاصة بـ "موازن الحمل الإقليمي الداخلي للتطبيقات" وواجهة PSC الخلفية وشبكة فرعية واحدة للخادم الوكيل فقط لاستخدامها مع موازن الحمل. سننشئ سلسلة مفاتيح ومفتاحًا في خدمة إدارة المفاتيح في السحابة الإلكترونية (KMS) في منطقة أوروبا الغربية. بعد ذلك، سننشئ جهاز موازنة الحمل وخادم PSC الخلفي لحلّ واجهة برمجة التطبيقات الإقليمية لنظام إدارة المفاتيح (KMS) في europe-west9.

3- الإعداد والمتطلبات

إعداد البيئة بالسرعة التي تناسبك

  1. سجِّل الدخول إلى Google Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديلها في أي وقت.
  • رقم تعريف المشروع هو معرّف فريد في جميع مشاريع Google Cloud ولا يمكن تغييره بعد ضبطه. تنشئ Cloud Console تلقائيًا سلسلة فريدة، ولا يهمّك عادةً ما هي. في معظم دروس البرمجة، عليك الرجوع إلى رقم تعريف مشروعك (يُشار إليه عادةً باسم PROJECT_ID). إذا لم يعجبك رقم التعريف الذي تم إنشاؤه، يمكنك إنشاء رقم تعريف عشوائي آخر. يمكنك بدلاً من ذلك تجربة اسم مستخدم من اختيارك ومعرفة ما إذا كان متاحًا. لا يمكن تغيير هذا الخيار بعد هذه الخطوة وسيظل ساريًا طوال مدة المشروع.
  • للعلم، هناك قيمة ثالثة، وهي رقم المشروع، تستخدمها بعض واجهات برمجة التطبيقات. يمكنك الاطّلاع على مزيد من المعلومات عن كل هذه القيم الثلاث في المستندات.
  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد/واجهات برمجة تطبيقات Cloud. لن تكلفك تجربة هذا الدرس التطبيقي حول الترميز الكثير، إن وُجدت أي تكلفة على الإطلاق. لإيقاف الموارد وتجنُّب تحمّل تكاليف تتجاوز هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع. يمكن لمستخدمي Google Cloud الجدد الاستفادة من برنامج الفترة التجريبية المجانية بقيمة 300 دولار أمريكي.

بدء Cloud Shell

على الرغم من إمكانية تشغيل Google Cloud عن بُعد من الكمبيوتر المحمول، ستستخدم في هذا الدرس العملي Google Cloud Shell، وهي بيئة سطر أوامر تعمل في السحابة الإلكترونية.

من Google Cloud Console، انقر على رمز Cloud Shell في شريط الأدوات أعلى يسار الصفحة:

55efc1aaa7a4d3ad.png

لن يستغرق توفير البيئة والاتصال بها سوى بضع لحظات. عند الانتهاء، من المفترض أن يظهر لك ما يلي:

7ffe5cbb04455448.png

يتم تحميل هذه الآلة الافتراضية مزوّدة بكل أدوات التطوير التي ستحتاج إليها. توفّر هذه الخدمة دليلًا منزليًا ثابتًا بسعة 5 غيغابايت، وتعمل على Google Cloud، ما يؤدي إلى تحسين أداء الشبكة والمصادقة بشكل كبير. يمكن إكمال جميع المهام في هذا الدرس العملي ضمن المتصفّح. لست بحاجة إلى تثبيت أي تطبيق.

4. قبل البدء

تفعيل واجهات برمجة التطبيقات

داخل Cloud Shell، تأكَّد من إعداد رقم تعريف مشروعك

gcloud config list project
gcloud config set project <project-id>
export PROJECT_ID=$(gcloud config get-value project)
export REGION=europe-west9
export ZONE=europe-west9-a
echo $PROJECT_ID
echo $REGION
echo $ZONE

تفعيل جميع الخدمات اللازمة

gcloud services enable compute.googleapis.com
gcloud services enable servicedirectory.googleapis.com
gcloud services enable dns.googleapis.com
gcloud services enable cloudkms.googleapis.com

5- إنشاء شبكة VPC وشبكات فرعية وقواعد جدار الحماية

إنشاء شبكة VPC

من Cloud Shell

# Set environment variables

export VPC_NAME="consumer-vpc"
export SUBNET_NAME="consumer-subnet-1"

# Create VPC network

gcloud compute networks create ${VPC_NAME} \
    --subnet-mode=custom \
    --bgp-routing-mode=regional

إنشاء شبكات فرعية

من Cloud Shell

gcloud compute networks subnets create ${SUBNET_NAME} \
    --network=${VPC_NAME} \
    --region=${REGION} \
    --range=10.0.0.0/24 \
    --enable-private-ip-google-access

في هذا التمرين العملي، ستنشئ جهاز موازنة حمل داخليًا على مستوى المنطقة من الطبقة 7 للإشارة إلى الخلفيات الإقليمية لواجهة برمجة التطبيقات. موازن التحميل هذا هو موازن تحميل خادم وكيل، لذا عليك إنشاء "شبكة فرعية للخادم الوكيل" مخصّصة لموازن التحميل لتنفيذ الخادم الوكيل. يمكنك الاطّلاع على مزيد من المعلومات حول الشبكة الفرعية التي تستخدم الوكيل فقط هنا.

من Cloud Shell

gcloud compute networks subnets create eu-west9-proxy-subnet \
--network=${VPC_NAME} \
--region=${REGION} \
--range=10.100.100.0/24 \
--purpose=REGIONAL_MANAGED_PROXY \
--role=ACTIVE

إنشاء قواعد جدار الحماية

في هذا التمرين العملي، ستستخدم خدمة IAP للاتصال بالأجهزة الافتراضية التي تنشئها. إذا كنت تفضّل عدم استخدام IAP، يمكنك تخطّي هذه الخطوة، وإضافة عناوين IP عامة على الجهاز الظاهري بدلاً من ذلك وإنشاء قاعدة جدار حماية تتيح الدخول على منفذ TCP رقم 22 من 0.0.0.0/0.

للسماح لميزة "الوصول إلى الأجهزة الافتراضية عبر الإنترنت" بالاتصال بأجهزة VM الافتراضية، أنشئ قاعدة جدار حماية تتضمّن ما يلي:

  • ينطبق على جميع مثيلات الأجهزة الافتراضية التي تريد إتاحتها باستخدام IAP.
  • تسمح هذه القاعدة بحركة البيانات الواردة من نطاق عناوين IP 35.235.240.0/20. يحتوي هذا النطاق على جميع عناوين IP التي تستخدمها خدمة IAP لإعادة توجيه بروتوكول TCP.

من Cloud Shell

gcloud compute firewall-rules create allow-ssh-iap \
    --network=${VPC_NAME} \
--allow tcp:22 \
--source-ranges=35.235.240.0/20

6. إنشاء Cloud NAT

يجب إنشاء Cloud NAT لتنزيل حِزم توزيع Linux.

إنشاء Cloud Router

من Cloud Shell

gcloud compute routers create crnat \
    --network=${VPC_NAME} \
    --region=${REGION}

إنشاء Cloud NAT

من Cloud Shell

gcloud compute routers nats create europe-nat \
    --router=crnat \
    --auto-allocate-nat-external-ips \
    --nat-all-subnet-ip-ranges \
    --enable-logging \
    --region=${REGION}

7. إنشاء سلسلة مفاتيح ومفتاح لإدارة المفاتيح

من Cloud Shell

gcloud kms keyrings create europe-kr \
    --location ${REGION}

من Cloud Shell

gcloud kms keys create europe-key \
    --location ${REGION} \
    --keyring europe-kr \
    --purpose encryption

من Cloud Shell، تأكَّد من إنشاء سلسلة المفاتيح والمفتاح بنجاح في منطقة أوروبا الغربية.

gcloud kms keys list \
    --location ${REGION} \
    --keyring europe-kr

النتيجة المتوقّعة

NAME: projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key
PURPOSE: ENCRYPT_DECRYPT
ALGORITHM: GOOGLE_SYMMETRIC_ENCRYPTION
PROTECTION_LEVEL: SOFTWARE
LABELS: 
PRIMARY_ID: 1
PRIMARY_STATE: ENABLED

دوِّن اسم المسار الكامل الذي تم تحديده للمفاتيح لأنّك ستستخدمه للاتصال لاحقًا.

8. إنشاء جهاز افتراضي للعميل والاتصال بواجهة برمجة التطبيقات KMS API

بعد ذلك، ستنشئ جهازًا افتراضيًا للعميل، وتستخدم SSH للوصول إلى الجهاز الافتراضي، وتختبر إمكانية الوصول إلى واجهة برمجة التطبيقات العالمية لنظام إدارة المفاتيح (KMS). يمثّل هذا الاختبار الخيار التلقائي لحلّ المشاكل في Google APIs العالمية.

من Cloud Shell

#Create the startup script

touch startup.sh

#Open the startup.sh file using a text editor of your choice (e.g., nano, vim, gedit, etc.)

nano startup.sh 

#Paste the following script content into the startup.sh file

#! /bin/bash 
sudo apt-get update 
sudo apt-get install dnsutils -y 
sudo apt-get install tcpdump -y

#Save the changes you made to the startup.sh file
#Use the chmod command to make the script executable

chmod +x startup.sh

#Create the VM instance

gcloud compute instances create client-vm \
    --network="${VPC_NAME}" \
    --subnet="${SUBNET_NAME}" \
    --zone="europe-west9-a" \
    --machine-type="e2-medium" \
    --no-address \
    --scopes="https://www.googleapis.com/auth/cloud-platform" \
    --image-family="debian-12" \
    --image-project="debian-cloud" \
    --metadata-from-file="startup-script=./startup.sh" 

بعد ذلك، عليك تعديل حساب خدمة Compute التلقائي للوصول إلى مفتاح KMS الذي أنشأته. سيكون حساب خدمة Compute التلقائي بالتنسيق <Project_Number> -compute@developer.gserviceaccount.com. للحصول على رقم المشروع، شغِّل الأمر التالي من Cloud Shell وانسخ الرقم في السطر الأخير من النتائج المعروضة.

 gcloud projects describe $PROJECT_ID

عدِّل حساب الخدمة التلقائي في Compute للوصول إلى مفتاح KMS الذي أنشأته.

من Cloud Shell

gcloud kms keys add-iam-policy-binding europe-key \
    --location $REGION \
    --keyring europe-kr \
    --member serviceAccount:<project_number>-compute@developer.gserviceaccount.com \
    --role roles/cloudkms.admin

أنشئ نافذة طرفية إضافية في Cloud Shell من خلال النقر على علامة الجمع (+) (لقطة الشاشة أدناه)

a36edc967333315a.png

في علامة التبويب 2، يمكنك إنشاء نفق من خلال IAP إلى SSH في client-vm. يُرجى العلم أنّ متغيّرات البيئة لن يتم نقلها، وعليك إضافة رقم تعريف مشروعك إلى الأمر أدناه.

من Cloud Shell

# Set the environment variable

export PROJECT_ID=$(gcloud config get-value project)

# ssh into the client-vm

gcloud beta compute ssh --zone europe-west9-a "client-vm" \
--tunnel-through-iap \
--project $PROJECT_ID

اتّصِل بواجهة برمجة التطبيقات KMS API العامة باستخدام اسم مفتاح KMS الذي دوّنته سابقًا.

من علامة التبويب 2، client-vm

# Store the access token in a variable

TOKEN=$(gcloud auth print-access-token)

# Run the full command with maximum verbosity
curl -v \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
'https://cloudkms.googleapis.com/v1/projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key'

النتيجة المتوقّعة

*   Trying 216.58.214.74:443...
* Connected to cloudkms.googleapis.com (216.58.214.74) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=upload.video.google.com
*  start date: Aug 26 07:12:45 2024 GMT
*  expire date: Nov 18 07:12:44 2024 GMT
*  subjectAltName: host "cloudkms.googleapis.com" matched cert's "*.googleapis.com"
*  issuer: C=US; O=Google Trust Services; CN=WR2
*  SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /v1/projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key]
* h2h3 [:scheme: https]
* h2h3 [:authority: cloudkms.googleapis.com]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* h2h3 [authorization: Bearer dsnkjfdnvjfd
* h2h3 [content-type: application/json]
* Using Stream ID: 1 (easy handle 0x55ed8bb7ece0)
> GET /v1/projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key HTTP/2
> Host: cloudkms.googleapis.com
> user-agent: curl/7.88.1
> accept: */*
> authorization: Bearer dsnkjfdnvjfd
> content-type: application/json
>
< HTTP/2 200
< content-type: application/json; charset=UTF-8
< vary: X-Origin
< vary: Referer
< vary: Origin,Accept-Encoding
< date: Tue, 24 Sep 2024 18:25:42 GMT
< server: ESF
< cache-control: private
< x-xss-protection: 0
< x-frame-options: SAMEORIGIN
< x-content-type-options: nosniff
< accept-ranges: none
<
{
  "name": "projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key",
  "primary": {
    "name": "projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key/cryptoKeyVersions/1",
    "state": "ENABLED",
    "createTime": "2024-09-24T17:56:01.905156045Z",
    "protectionLevel": "SOFTWARE",
    "algorithm": "GOOGLE_SYMMETRIC_ENCRYPTION",
    "generateTime": "2024-09-24T17:56:01.905156045Z"
  },
  "purpose": "ENCRYPT_DECRYPT",
  "createTime": "2024-09-24T17:56:01.905156045Z",
  "versionTemplate": {
    "protectionLevel": "SOFTWARE",
    "algorithm": "GOOGLE_SYMMETRIC_ENCRYPTION"
  },
  "destroyScheduledDuration": "2592000s"
}
* Connection #0 to host cloudkms.googleapis.com left intact

تحقَّق من المكان الذي يحلّ فيه نظام أسماء النطاقات نقطة نهاية "خدمة إدارة المفاتيح".

من علامة التبويب 2، client-vm

dig cloudkms.googleapis.com

النتيجة المتوقّعة

 <<>> DiG 9.18.28-1~deb12u2-Debian <<>> cloudkms.googleapis.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62617
;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;cloudkms.googleapis.com.       IN      A

;; ANSWER SECTION:
cloudkms.googleapis.com. 300    IN      A       142.250.74.234
cloudkms.googleapis.com. 300    IN      A       142.250.75.234
cloudkms.googleapis.com. 300    IN      A       216.58.214.170
cloudkms.googleapis.com. 300    IN      A       172.217.20.170
cloudkms.googleapis.com. 300    IN      A       172.217.20.202
cloudkms.googleapis.com. 300    IN      A       216.58.215.42
cloudkms.googleapis.com. 300    IN      A       216.58.213.74
cloudkms.googleapis.com. 300    IN      A       142.250.179.74
cloudkms.googleapis.com. 300    IN      A       142.250.179.106
cloudkms.googleapis.com. 300    IN      A       142.250.178.138
cloudkms.googleapis.com. 300    IN      A       142.250.201.170
cloudkms.googleapis.com. 300    IN      A       172.217.18.202
cloudkms.googleapis.com. 300    IN      A       216.58.214.74

;; Query time: 4 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Wed Oct 23 19:58:58 UTC 2024
;; MSG SIZE  rcvd: 260

من علامة التبويب 2، client-vm

dig cloudkms.europe-west9.rep.googleapis.com

النتيجة المتوقّعة

<<>> DiG 9.18.28-1~deb12u2-Debian <<>> cloudkms.europe-west9.rep.googleapis.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2736
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;cloudkms.europe-west9.rep.googleapis.com. IN A

;; ANSWER SECTION:
cloudkms.europe-west9.rep.googleapis.com. 3043 IN A 34.1.65.232

;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Wed Oct 23 20:00:04 UTC 2024
;; MSG SIZE  rcvd: 85

السلوك التلقائي لخدمات Google APIs هو استخدام نقطة نهاية خدمة Global API. سيتم حل نقطة النهاية هذه إلى قائمة بعناوين IP العامة. يظهر ذلك عند البحث عن cloudkms.googleapis.com. (ملاحظة: قد يكون عنوان IP الذي يظهر لك عنوان IP خارجيًا مختلفًا. وهذا سلوك عادي في Google APIs.)

باستخدام نقاط نهاية Google API الإقليمية مع PSC، يمكنك استيفاء المتطلبات الإقليمية لعدد الزيارات إلى واجهة برمجة التطبيقات، بالإضافة إلى تغيير مستوى العرض من عام إلى خاص. يُظهر الأمر dig إلى cloudkms.europe-west9.rep.googleapis.com أنّه في هذه المرحلة، لا يزال حل نقطة نهاية واجهة برمجة التطبيقات الإقليمية لخدمة إدارة المفاتيح (KSM) متاحًا للجميع.

في الأقسام التالية، سننتقل من استخدام نقطة نهاية Global KMS API إلى نقطة النهاية الإقليمية، وسنغيّر عملية الربط إلى خاص باستخدام PSC Backends.

9- إنشاء مجموعة NEG وLoad Balancer لخدمة Private Service Connect

للانتقال إلى القسم التالي، ارجع إلى علامة التبويب الأولى في Cloud Shell.

ستنشئ "جهاز موازنة حمل داخلي HTTP(S)" مع مجموعة نقاط نهاية شبكة(NEG) تشير إلى نقطة نهاية KMS الإقليمية في أوروبا كخدمة خلفية. تعمل قاعدة إعادة التوجيه الخاصة بموازنة الحمل كنقطة نهاية Private Service Connect(PSC).

أنشئ مجموعة نقاط نهاية الشبكة (NEG) من النوع Private Service Connect والخدمة المستهدَفة europe-west9-cloudkms.example.com

من Cloud Shell

#Set the necessary variables

NEG_NAME="l7psc-kms-neg"
PSC_TARGET="cloudkms.europe-west9.rep.googleapis.com"

#Create the Private Service Connect NEG

gcloud compute network-endpoint-groups create ${NEG_NAME} \
    --project=${PROJECT_ID} \
    --region=${REGION} \
    --network-endpoint-type=PRIVATE_SERVICE_CONNECT \
    --psc-target-service=${PSC_TARGET}

# Verify the NEG creation

gcloud compute network-endpoint-groups describe ${NEG_NAME} \
    --project=${PROJECT_ID} \
    --region=${REGION}

أنشئ خدمة الخلفية لجهاز موازنة الحمل.

من Cloud Shell

# 1. Set the necessary variables

BACKEND_SERVICE_NAME="l7-psc-kms"

# 2. Create the backend service

gcloud compute backend-services create $BACKEND_SERVICE_NAME \
  --load-balancing-scheme=INTERNAL_MANAGED \
  --protocol=HTTPS \
  --region=$REGION \

أضِف مجموعة NEG إلى خدمة الخلفية.

من Cloud Shell

gcloud compute backend-services add-backend $BACKEND_SERVICE_NAME \
  --network-endpoint-group=${NEG_NAME} \
  --region=$REGION

أنشئ خريطة عناوين URL لجهاز موازنة الحمل.

من Cloud Shell

gcloud compute url-maps create l7-psc-url-map \
  --default-service=l7-psc-kms \
  --region=$REGION

أنشئ أداة مطابقة المسار لعنوان URL المخصّص الذي ستستخدمه نقطة النهاية.

من Cloud Shell

gcloud compute url-maps add-path-matcher l7-psc-url-map \
 --path-matcher-name=example \
 --default-service=l7-psc-kms \
 --region=$REGION

أنشئ قاعدة المضيف لعنوان URL المخصّص europe-west9-cloudkms.example.com.

من Cloud Shell

gcloud compute url-maps add-host-rule l7-psc-url-map \
--hosts=europe-west9-cloudkms.example.com \
--path-matcher-name=example \
--region=$REGION

أنشئ خادم وكيل HTTPS مستهدفًا لجهاز موازنة الحمل. يتطلّب ذلك إنشاء مورد شهادة طبقة المقابس الآمنة إقليمي. يُرجى الاطّلاع هنا على خطوات إنشاء شهادة موقعة ذاتيًا. سننشئ شهادة موقّعة ذاتيًا باستخدام openssl، وسنستخدمها لإنشاء مورد شهادة إقليمي على Google Cloud Platform. سيستخدم خادم وكيل HTTPS المستهدف هذه الشهادة.

من Cloud Shell

# Set environment variables

export CERT_NAME="my-ssl-cert"

# Generate a private key

openssl genrsa -out private.key 2048

#  Create a configuration file for the CSR

cat > csr_config.cnf << EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[dn]
CN = example.com
O = My Organization
C = US

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = example.com
DNS.2 = *.example.com
EOF

# Create a CSR using the configuration

openssl req -new -key private.key -out server.csr -config csr_config.cnf

# Create a self-signed certificate using the CSR

openssl x509 -req -days 365 -in server.csr -signkey private.key -out server.crt \
    -extfile csr_config.cnf -extensions req_ext

# Verify the certificate

openssl x509 -in server.crt -text -noout

#Create a regional SSL certificate resource 

gcloud compute ssl-certificates create ${CERT_NAME} \
    --region=${REGION} \
    --certificate=server.crt \
    --private-key=private.key

#Create the target HTTPS proxy for the load balancer 

gcloud compute target-https-proxies create psc-http-proxy \
    --region=${REGION} \
    --url-map=l7-psc-url-map \
    --ssl-certificates=${CERT_NAME}

أنشئ قاعدة إعادة التوجيه لموازنة التحميل التي ستعمل كنقطة نهاية Private Service Connect. يجب أن ينتمي عنوان IP الخاص بقاعدة إعادة التوجيه إلى شبكة فرعية إقليمية في السحابة الإلكترونية الخاصة الافتراضية (VPC) ضِمن المنطقة نفسها التي يتم الوصول إلى نقطة نهاية واجهة برمجة التطبيقات فيها.

من Cloud Shell

# Set environment variables

export PROXY_NAME="psc-http-proxy"

# Create the forwarding rule

gcloud compute forwarding-rules create kms-lb-rule \
    --project=${PROJECT_ID} \
    --region=${REGION} \
    --load-balancing-scheme=INTERNAL_MANAGED \
    --network=${VPC_NAME} \
    --subnet=${SUBNET_NAME} \
    --target-https-proxy=${PROXY_NAME} \
    --target-https-proxy-region=${REGION} \
    --address=10.0.0.100 \
    --ports=443

10. إعدادات نظام أسماء النطاقات

في هذا القسم، ستنشئ منطقة نظام أسماء نطاقات خاصًا للنطاق example.com، وسجلّ A يشير إلى قاعدة إعادة التوجيه التي أنشأناها في الخطوة الأخيرة.

أنشئ منطقة نظام أسماء نطاقات خاصًا مُدارًا.

من Cloud Shell

# Set environment variables

export LB_RULE_NAME="kms-lb-rule"
export DNS_ZONE_NAME="example-com-private-zone"

# Create the private DNS zone

gcloud dns managed-zones create ${DNS_ZONE_NAME} \
    --dns-name="example.com." \
    --description="Private DNS zone for example.com" \
    --visibility=private \
    --networks=${VPC_NAME}

أنشئ سجلّ A لـ europe-west9-cloudkms.example.com.

من Cloud Shell

gcloud dns record-sets transaction start \
   --zone=${DNS_ZONE_NAME}

gcloud dns record-sets transaction add 10.0.0.100 \
   --name=europe-west9-cloudkms.example.com \
   --ttl=300 \
   --type=A \
   --zone=${DNS_ZONE_NAME}

gcloud dns record-sets transaction execute \
   --zone=${DNS_ZONE_NAME}

11. الربط بواجهة برمجة التطبيقات الإقليمية KMS API من خلال PSC

ارجع إلى client-vm في علامة التبويب 2 لتشغيل tcpdump من أجل الاطّلاع على جميع تفاصيل الاتصال واختبار عمليات الاتصال بنقطة نهاية KMS الإقليمية من خلال PSC Backend.

sudo tcpdump -i any net 10.0.0.100 or port 53 -n

افتح علامة تبويب ثالثة في Cloud Shell واستخدِم بروتوكول SSH للوصول إلى client-vm.

# Set environment variables

export PROJECT_ID=$(gcloud config get-value project)
export KMS_HOSTNAME="europe-west9-cloudkms.example.com"
export KEY_RING="europe-kr"
export KEY_NAME="europe-key"
export REGION="europe-west9"

# Command to access the specific key

curl -k "https://${KMS_HOSTNAME}/v1/projects/${PROJECT_ID}/locations/${REGION}/keyRings/${KEY_RING}/cryptoKeys/${KEY_NAME}" \
  -H "Authorization: Bearer $(gcloud auth print-access-token)"

النتيجة المتوقّعة لأمر curl + TCPDUMP

{
  "name": "projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key",
  "primary": {
    "name": "projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key/cryptoKeyVersions/1",
    "state": "ENABLED",
    "createTime": "2024-10-10T18:50:24.357027036Z",
    "protectionLevel": "SOFTWARE",
    "algorithm": "GOOGLE_SYMMETRIC_ENCRYPTION",
    "generateTime": "2024-10-10T18:50:24.357027036Z"
  },
  "purpose": "ENCRYPT_DECRYPT",
  "createTime": "2024-10-10T18:50:24.357027036Z",
  "versionTemplate": {
    "protectionLevel": "SOFTWARE",
    "algorithm": "GOOGLE_SYMMETRIC_ENCRYPTION"
  },
  "destroyScheduledDuration": "2592000s"
}


Tcpdump output

listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
18:13:51.220209 lo    In  IP 127.0.0.1.48873 > 127.0.0.53.53: 2086+ [1au] A? europe-west9-cloudkms.example.com. (62)
18:13:51.220230 lo    In  IP 127.0.0.1.48873 > 127.0.0.53.53: 24619+ [1au] AAAA? europe-west9-cloudkms.example.com. (62)
18:13:51.220669 ens4  Out IP 10.0.0.2.52121 > 169.254.169.254.53: 8885+ [1au] A? europe-west9-cloudkms.example.com. (62)
18:13:51.220784 ens4  Out IP 10.0.0.2.53041 > 169.254.169.254.53: 57748+ [1au] AAAA? europe-west9-cloudkms.example.com. (62)
18:13:51.229638 ens4  In  IP 169.254.169.254.53 > 10.0.0.2.52121: 8885 1/0/1 A 10.0.0.100 (78)
18:13:51.229945 lo    In  IP 127.0.0.53.53 > 127.0.0.1.48873: 2086 1/0/1 A 10.0.0.100 (78)
18:13:51.230068 ens4  In  IP 169.254.169.254.53 > 10.0.0.2.53041: 57748 0/1/1 (155)
18:13:51.230203 lo    In  IP 127.0.0.53.53 > 127.0.0.1.48873: 24619 0/1/1 (155)
18:13:51.230390 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [S], seq 1606150798, win 65320, options [mss 1420,sackOK,TS val 4135800856 ecr 0,nop,wscale 7], length 0
18:13:51.232565 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [S.], seq 1041507402, ack 1606150799, win 65535, options [mss 1420,sackOK,TS val 2276748382 ecr 4135800856,nop,wscale 8], length 0
18:13:51.232583 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [.], ack 1, win 511, options [nop,nop,TS val 4135800859 ecr 2276748382], length 0
18:13:51.235494 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [P.], seq 1:518, ack 1, win 511, options [nop,nop,TS val 4135800862 ecr 2276748382], length 517
18:13:51.236571 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [.], ack 518, win 267, options [nop,nop,TS val 2276748387 ecr 4135800862], length 0
18:13:51.239119 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [P.], seq 1:1356, ack 518, win 267, options [nop,nop,TS val 2276748389 ecr 4135800862], length 1355
18:13:51.239140 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [.], ack 1356, win 501, options [nop,nop,TS val 4135800865 ecr 2276748389], length 0
18:13:51.240978 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [P.], seq 518:598, ack 1356, win 501, options [nop,nop,TS val 4135800867 ecr 2276748389], length 80
18:13:51.241266 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [P.], seq 598:684, ack 1356, win 501, options [nop,nop,TS val 4135800867 ecr 2276748389], length 86
18:13:51.241366 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [P.], seq 684:1646, ack 1356, win 501, options [nop,nop,TS val 4135800867 ecr 2276748389], length 962
18:13:51.242370 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [.], ack 684, win 267, options [nop,nop,TS val 2276748392 ecr 4135800867], length 0
18:13:51.242619 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [P.], seq 1356:1433, ack 1646, win 278, options [nop,nop,TS val 2276748393 ecr 4135800867], length 77
18:13:51.242730 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [P.], seq 1646:1677, ack 1433, win 501, options [nop,nop,TS val 4135800869 ecr 2276748393], length 31
18:13:51.248724 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [.], ack 1677, win 278, options [nop,nop,TS val 2276748399 ecr 4135800869], length 0
18:13:51.296676 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [P.], seq 1433:2357, ack 1677, win 278, options [nop,nop,TS val 2276748447 ecr 4135800869], length 924
18:13:51.297223 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [F.], seq 1677, ack 2357, win 501, options [nop,nop,TS val 4135800923 ecr 2276748447], length 0
18:13:51.298304 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [P.], seq 2357:2381, ack 1678, win 278, options [nop,nop,TS val 2276748448 ecr 4135800923], length 24
18:13:51.298305 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [F.], seq 2381, ack 1678, win 278, options [nop,nop,TS val 2276748448 ecr 4135800923], length 0
18:13:51.298336 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [R], seq 1606152476, win 0, length 0
18:13:51.298343 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [R], seq 1606152476, win 0, length 0


ارجع إلى نافذة علامة التبويب 2 وافحص معلومات tcpdump. ستلاحظ أنّه تمكّنت من الوصول إلى نقطة النهاية الإقليمية في Cloud KMS من خلال نقطة نهاية PSC التي أنشأتها، وأنّ نقطة النهاية الإقليمية europe-west9 يتم توجيهها بشكل خاص إلى منطقة Cloud DNS المُدارة التي أنشأتها. تم تمييز الأسطر ذات الصلة في ناتج tcpdump أعلاه والإشارة إليها أدناه:

18:13:51.229638 ens4 In IP 169.254.169.254.53 > 10.0.0.2.52121: 8885 1/0/1 A 10.0.0.100 (78) (يستجيب خادم البيانات الوصفية في GCP بسجلّ A: 10.0.0.100، وهو عنوان IP لموازن التحميل. تعمل عملية التحويل باستخدام نظام أسماء النطاقات (DNS) بشكل صحيح. يتم تحليل europe-west9-cloudkms.example.com إلى 10.0.0.100، وهو عنوان IP لجهاز موازنة الحمل)

18:13:51.230390 ens4 Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [S], seq 1606150798, win 65320, options [mss 1420,sackOK,TS val 4135800856 ecr 0,nop,wscale 7], length 0 (تعرض هذه الخطوة مصافحة TCP لاتصال HTTPS بعنوان IP الخاص بجهاز موازنة الحمل)

في علامة التبويب 3، client-vm

dig europe-west9-cloudkms.example.com

النتيجة المتوقّعة

; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> europe-west9-cloudkms.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7008
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;europe-west9-cloudkms.example.com. IN  A

;; ANSWER SECTION:
europe-west9-cloudkms.example.com. 300 IN A     10.0.0.100

;; Query time: 12 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Fri Oct 11 20:03:00 UTC 2024
;; MSG SIZE  rcvd: 78

يوضّح ناتج الأمر dig أنّ عنوان URL المخصّص الذي أنشأناه لـ europe-west9-cloudkms.example.com يتم تحويله بشكلٍ صحيح إلى 10.0.0.100، وهو عنوان IP لموازنة التحميل الداخلية. سيتم توجيه الطلبات إلى europe-west9-cloudkms.example.com إلى جهاز موازنة الحمل الداخلي، الذي يعيد توجيهها بعد ذلك إلى نقطة النهاية الإقليمية لخدمة إدارة المفاتيح (KMS) من خلال Private Service Connect.

يمكنك الآن إغلاق علامتَي تبويب SSH إلى client-vm.

12. خطوات التنظيف

حذف مكوّنات المختبر من نافذة Cloud Shell واحدة

# Set environment variables

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
export REGION=europe-west9
export ZONE=europe-west9-a
export VPC_NAME="consumer-vpc"
export SUBNET_NAME="consumer-subnet-1"
export NEG_NAME="l7psc-kms-neg"
export BACKEND_SERVICE_NAME="l7-psc-kms"
export CERT_NAME="my-ssl-cert"
export PROXY_NAME="psc-http-proxy"
export LB_RULE_NAME="kms-lb-rule"
export DNS_ZONE_NAME="example-com-private-zone"

#  Delete DNS records and zone

gcloud dns record-sets delete europe-west9-cloudkms.example.com. \
    --zone=${DNS_ZONE_NAME} --type=A --quiet
gcloud dns managed-zones delete ${DNS_ZONE_NAME} --quiet

#  Delete Load Balancer components

gcloud compute forwarding-rules delete ${LB_RULE_NAME} --region=${REGION} --quiet
gcloud compute target-https-proxies delete ${PROXY_NAME} --region=${REGION} --quiet
gcloud compute url-maps delete l7-psc-url-map --region=${REGION} --quiet
gcloud compute backend-services delete ${BACKEND_SERVICE_NAME} --region=${REGION} --quiet
gcloud compute network-endpoint-groups delete ${NEG_NAME} --region=${REGION} --quiet

# Delete SSL certificate

gcloud compute ssl-certificates delete ${CERT_NAME} --region=${REGION} --quiet

#  Delete VM instance

gcloud compute instances delete client-vm --zone=${ZONE} --quiet

#  Delete firewall rules

gcloud compute firewall-rules delete allow-ssh-iap --quiet

# Delete Cloud NAT and router

gcloud compute routers nats delete europe-nat --router=crnat --region=${REGION} --quiet
gcloud compute routers delete crnat --region=${REGION} --quiet

#  Delete subnets and VPC

gcloud compute networks subnets delete ${SUBNET_NAME} --region=${REGION} --quiet
gcloud compute networks subnets delete eu-west9-proxy-subnet --region=${REGION} --quiet
gcloud compute networks delete ${VPC_NAME} --quiet

# Schedule KMS key for deletion and provide instructions for keyring deletion

gcloud kms keys remove-iam-policy-binding europe-key \
    --location ${REGION} \
    --keyring europe-kr \
    --member serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com \
    --role roles/cloudkms.admin

gcloud kms keys versions destroy 1 --location=${REGION} --keyring=europe-kr --key=europe-key

#  Disable services (optional, only if you want to completely disable these APIs)

gcloud services disable compute.googleapis.com --force
gcloud services disable servicedirectory.googleapis.com --force
gcloud services disable dns.googleapis.com --force
gcloud services disable cloudkms.googleapis.com --force

#  Clean up local files

rm -f private.key server.csr server.crt csr_config.cnf startup.sh

13. تهانينا!

تهانينا على إكمال هذا الدرس العملي.