Private Service Connect – Sử dụng phần phụ trợ PSC để truy cập vào các API của Google theo khu vực

1. Giới thiệu

Private Service Connect là một tính năng của mạng Google Cloud cho phép người dùng truy cập vào các dịch vụ của nhà sản xuất. Điều này bao gồm khả năng kết nối với các API của Google thông qua một điểm cuối riêng tư được lưu trữ trong VPC của người dùng(thường là người tiêu dùng).

Ngoài ra, bạn có thể sử dụng phần phụ trợ PSC cùng với bộ cân bằng tải proxy của Google Cloud để trỏ đến các API Google dành riêng cho khu vực. Việc sử dụng phần phụ trợ PSC cung cấp các chế độ kiểm soát chi tiết hơn cho phía người tiêu dùng, chẳng hạn như:

  • Chọn dịch vụ API của Google có sẵn bằng Bản đồ URL
  • Khả năng quan sát sâu hơn
  • Tích hợp Cloud Armor
  • URL tùy chỉnh
  • Quản lý lưu lượng truy cập nâng cao

Bạn có thể xem danh sách các dịch vụ hiện có và API theo khu vực của các dịch vụ đó tại đây.

Trong lớp học lập trình này, bạn sẽ tạo một phần phụ trợ PSC trỏ đến API Cloud KMS theo khu vực và kiểm thử khả năng kết nối với API đó.

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

  • Tạo một bộ khoá và khoá trong Dịch vụ quản lý khoá trên đám mây (KMS).
  • Tạo Trình cân bằng tải ứng dụng nội bộ có Phần phụ trợ PSC trỏ đến API theo khu vực của Cloud KMS
  • Tạo Vùng riêng tư do Cloud DNS quản lý và Bản ghi A.
  • Truy cập vào Cloud KMS theo khu vực

Bạn cần có

  • Một Dự án Google Cloud có quyền "Chủ sở hữu" hoặc quyền "Người chỉnh sửa" đầy đủ.

2. Cấu trúc liên kết của lớp học lập trình

1a18ae253213e215.png

Hệ thống sẽ tạo một VPC dành cho người dùng có một mạng con trong khu vực europe-west9 để lưu trữ máy ảo, quy tắc chuyển tiếp của Trình cân bằng tải ứng dụng nội bộ theo khu vực, phần phụ trợ PSC và một mạng con chỉ dành cho proxy để sử dụng với trình cân bằng tải. Chúng ta sẽ tạo một Bộ khoá và Khoá trong Hệ thống quản lý khoá trên đám mây (KMS) ở khu vực europe-west. Sau đó, chúng ta sẽ tạo trình cân bằng tải và phần phụ trợ PSC để phân giải đến API KMS theo khu vực ở europe-west9.

3. Cách thiết lập và các yêu cầu

Thiết lập môi trường theo tốc độ của riêng bạn

  1. Đăng nhập vào Google Cloud Console rồi tạo một dự án mới hoặc sử dụng lại một dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • Tên dự án là tên hiển thị cho người tham gia dự án này. Đây là một chuỗi ký tự không được API của Google sử dụng. Bạn luôn có thể cập nhật thông tin này.
  • Mã dự án là duy nhất trên tất cả các dự án Google Cloud và không thể thay đổi (không thể thay đổi sau khi đặt). Cloud Console sẽ tự động tạo một chuỗi duy nhất; thường thì bạn không cần quan tâm đến chuỗi này. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham chiếu đến Mã dự án (thường được xác định là PROJECT_ID). Nếu không thích mã được tạo, bạn có thể tạo một mã ngẫu nhiên khác. Ngoài ra, bạn có thể thử dùng email của riêng mình để xem có thể sử dụng hay không. Bạn không thể thay đổi thông tin này sau bước này và thông tin này sẽ được giữ nguyên trong suốt thời gian diễn ra dự án.
  • Xin lưu ý rằng có một giá trị thứ ba là Mã dự án mà một số API sử dụng. Tìm hiểu thêm về cả ba giá trị này trong tài liệu.
  1. Tiếp theo, bạn cần bật tính năng thanh toán trong Cloud Console để sử dụng các tài nguyên/API trên Cloud. Việc tham gia lớp học lập trình này sẽ không tốn kém nhiều chi phí, nếu có. Để tắt các tài nguyên nhằm tránh bị tính phí sau khi hoàn tất hướng dẫn này, bạn có thể xoá các tài nguyên đã tạo hoặc xoá dự án. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí 300 USD.

Khởi động Cloud Shell

Mặc dù có thể điều khiển Google Cloud từ xa trên máy tính xách tay, nhưng trong lớp học lập trình này, bạn sẽ sử dụng Google Cloud Shell, một môi trường dòng lệnh chạy trên đám mây.

Trong Bảng điều khiển Google Cloud, hãy nhấp vào biểu tượng Cloud Shell trên thanh công cụ trên cùng bên phải:

55efc1aaa7a4d3ad.png

Quá trình cấp phép và kết nối với môi trường sẽ chỉ mất vài phút. Khi hoàn tất, bạn sẽ thấy như sau:

7ffe5cbb04455448.png

Máy ảo này được tải sẵn tất cả các công cụ phát triển mà bạn cần. Ứng dụng này cung cấp một thư mục gốc 5 GB ổn định và chạy trên Google Cloud, giúp nâng cao đáng kể hiệu suất mạng và xác thực. Bạn có thể thực hiện tất cả công việc trong lớp học lập trình này trong một trình duyệt. Bạn không cần cài đặt gì cả.

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

Bật API

Trong Cloud Shell, hãy đảm bảo bạn đã thiết lập mã dự án

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

Bật tất cả các dịch vụ cần thiết

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. Tạo mạng VPC, Mạng con và Quy tắc về tường lửa

Tạo mạng VPC

Trong 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

Tạo mạng con

Trong 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

Trong lớp học lập trình này, bạn sẽ tạo một trình cân bằng tải L7 nội bộ theo khu vực để trỏ đến phần phụ trợ API theo khu vực. Bộ cân bằng tải này là bộ cân bằng tải proxy, do đó, bạn cần tạo một "mạng con proxy" dành riêng cho bộ cân bằng tải để thực hiện proxy. Bạn có thể xem thêm thông tin về mạng con chỉ dành cho proxy tại đây.

Trong 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

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

Trong lớp học này, bạn sẽ sử dụng IAP để kết nối với các thực thể mà bạn tạo. Nếu không muốn sử dụng IAP, bạn có thể bỏ qua bước này và thêm địa chỉ IP công khai trên thực thể, đồng thời tạo quy tắc tường lửa cho phép truy cập vào cổng TCP 22 từ 0.0.0.0/0.

Để cho phép IAP kết nối với các phiên bản máy ảo, hãy tạo một quy tắc tường lửa:

  • Áp dụng cho tất cả các phiên bản máy ảo mà bạn muốn truy cập bằng IAP.
  • Cho phép lưu lượng truy cập vào từ dải IP 35.235.240.0/20. Phạm vi này chứa tất cả địa chỉ IP mà IAP sử dụng để chuyển tiếp TCP.

Trong Cloud Shell

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

6. Tạo Cloud NAT

Bạn phải tạo một Cloud NAT để tải các bản phân phối gói Linux xuống.

Tạo Cloud Router

Trong Cloud Shell

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

Tạo Cloud NAT

Trong 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. Tạo khoá và bộ khoá quản lý khoá

Trong Cloud Shell

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

Trong Cloud Shell

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

Trong Cloud Shell, hãy xác nhận rằng bạn đã tạo thành công vòng khoá và khoá trong khu vực europe-west.

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

KẾT QUẢ DỰ KIẾN

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

Hãy lưu ý tên đường dẫn đầy đủ được cung cấp cho các khoá vì bạn sẽ sử dụng tên này để kết nối sau.

8. Tạo máy ảo ứng dụng và kết nối với KMS API

Tiếp theo, bạn sẽ tạo một máy ảo ứng dụng, SSH vào máy ảo đó và kiểm thử độ phân giải của API KMS toàn cục. Kiểm thử này thể hiện tuỳ chọn mặc định để phân giải các API toàn cầu của Google.

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

Tiếp theo, bạn cần cập nhật tài khoản dịch vụ Compute mặc định để có quyền truy cập vào khoá KMS mà bạn đã tạo. Tài khoản dịch vụ điện toán mặc định sẽ có định dạng <Project_Number> -compute@developer.gserviceaccount.com. Để lấy Số dự án, hãy chạy lệnh sau trong Cloud Shell và sao chép số trên dòng cuối cùng của kết quả trả về.

 gcloud projects describe $PROJECT_ID

Cập nhật tài khoản dịch vụ Compute mặc định để có quyền truy cập vào khoá KMS mà bạn đã tạo.

Trong 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

Tạo thêm một cửa sổ dòng lệnh cloud shell bằng cách nhấp vào biểu tượng + (ảnh chụp màn hình bên dưới)

a36edc967333315a.png

Trong thẻ 2, hãy tạo đường hầm thông qua IAP để SSH vào máy ảo ứng dụng. Xin lưu ý rằng các biến môi trường sẽ không được truyền và bạn cần thêm mã dự án vào lệnh bên dưới.

Trong 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

Kết nối với API KMS toàn cục bằng tên khoá KMS mà bạn đã ghi lại trước đó.

Từ thẻ 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'

KẾT QUẢ DỰ KIẾN

*   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

Kiểm tra xem DNS phân giải điểm cuối KMS ở đâu.

Từ thẻ2, client-vm

dig cloudkms.googleapis.com

KẾT QUẢ DỰ KIẾN

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

Từ thẻ2, client-vm

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

KẾT QUẢ DỰ KIẾN

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

Hành vi mặc định cho API của Google là sử dụng điểm cuối dịch vụ API Toàn cầu. Điểm cuối này sẽ phân giải thành danh sách IP công khai. Kết quả tìm kiếm về cloudkms.googleapis.com cho thấy điều này. (Lưu ý: Địa chỉ IP mà bạn thấy có thể là một địa chỉ IP ngoài khác. Đây là hành vi bình thường của API Google.)

Bằng cách sử dụng các điểm cuối API của Google theo khu vực với PSC, bạn có thể đáp ứng các yêu cầu theo khu vực đối với lưu lượng truy cập API cũng như thay đổi độ phân giải từ công khai thành riêng tư. Kết quả truy vấn cloudkms.europe-west9.rep.googleapis.com cho thấy rằng tại thời điểm này, độ phân giải đến điểm cuối API KSM theo khu vực vẫn là công khai.

Trong các phần sau, chúng ta sẽ di chuyển từ việc sử dụng điểm cuối API KMS toàn cầu sang điểm cuối theo khu vực và thay đổi độ phân giải thành riêng tư bằng cách sử dụng phần phụ trợ PSC.

9. Tạo PSC NEG và Trình cân bằng tải

Đối với phần tiếp theo, hãy chuyển về thẻ đầu tiên trong Cloud Shell.

Bạn sẽ tạo một Trình cân bằng tải HTTP(S) nội bộ với một nhóm điểm cuối mạng(NEG) trỏ đến điểm cuối KMS theo khu vực Châu Âu dưới dạng dịch vụ phụ trợ. Quy tắc chuyển tiếp của trình cân bằng tải đóng vai trò là điểm cuối Private Service Connect(PSC).

Tạo Nhóm điểm cuối mạng (NEG) có loại Private Service Connect và dịch vụ mục tiêu europe-west9-cloudkms.example.com

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

Tạo dịch vụ phụ trợ cho trình cân bằng tải.

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

Thêm NEG vào dịch vụ phụ trợ.

Trong Cloud Shell

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

Tạo bản đồ URL cho trình cân bằng tải.

Trong Cloud Shell

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

Tạo Trình so khớp đường dẫn cho URL tuỳ chỉnh mà điểm cuối sẽ sử dụng.

Trong Cloud Shell

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

Tạo quy tắc máy chủ lưu trữ cho URL tuỳ chỉnh europe-west9-cloudkms.example.com.

Trong 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

Tạo proxy HTTPS mục tiêu cho trình cân bằng tải. Để làm việc này, bạn cần tạo một tài nguyên chứng chỉ SSL theo khu vực. Vui lòng xem các bước để tạo chứng chỉ tự ký tại đây. Chúng ta sẽ tạo một chứng chỉ tự ký bằng openssl và sử dụng chứng chỉ đó để tạo tài nguyên chứng chỉ theo khu vực trên GCP. Proxy https mục tiêu sẽ sử dụng chứng chỉ này.

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

Tạo quy tắc chuyển tiếp cho bộ cân bằng tải sẽ đóng vai trò là Điểm cuối kết nối dịch vụ riêng tư. Địa chỉ IP cho quy tắc chuyển tiếp phải thuộc một mạng con theo khu vực trong VPC nằm trong cùng khu vực với điểm cuối API mà bạn đang truy cập.

Trong 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. Cấu hình DNS

Trong phần này, bạn sẽ tạo một vùng DNS riêng tư cho example.com và một bản ghi A trỏ đến quy tắc chuyển tiếp mà chúng ta đã tạo ở bước cuối cùng.

Tạo Vùng riêng DNS được quản lý.

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

Tạo bản ghi A cho europe-west9-cloudkms.example.com.

Trong 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. Kết nối với API KMS theo khu vực thông qua PSC

Chuyển về máy ảo khách trong thẻ 2 để chạy tcpdump nhằm xem tất cả thông tin chi tiết về kết nối và kiểm tra kết nối với điểm cuối KMS theo khu vực thông qua phần phụ trợ PSC.

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

Mở thẻ thứ 3 trong Cloud Shell và SSH vào 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)"

KẾT QUẢ DỰ KIẾN cho lệnh 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


Kiểm tra lại cửa sổ thẻ 2 và kiểm tra thông tin tcpdump. Bạn sẽ thấy rằng mình có thể truy cập vào điểm cuối theo khu vực của Cloud KMS thông qua điểm cuối PSC mà bạn đã tạo và điểm cuối theo khu vực europe-west9 phân giải riêng tư đến vùng DNS trên đám mây được quản lý mà bạn đã tạo. Các dòng liên quan trong đầu ra tcpdump được làm nổi bật ở trên và được tham chiếu ở bên dưới:

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) (Máy chủ siêu dữ liệu GCP phản hồi bằng bản ghi A: 10.0.0.100 – IP của bộ cân bằng tải. Quá trình phân giải DNS đang hoạt động đúng cách. europe-west9-cloudkms.example.com phân giải thành 10.0.0.100 (đây là địa chỉ IP của bộ cân bằng tải)

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 (Đây là giao thức bắt tay TCP cho kết nối HTTPS đến IP của bộ cân bằng tải)

Trong thẻ 3, client-vm

dig europe-west9-cloudkms.example.com

KẾT QUẢ DỰ KIẾN

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

Kết quả của lệnh dig cho thấy URL tuỳ chỉnh mà chúng ta đã tạo cho europe-west9-cloudkms.example.com phân giải chính xác thành 10.0.0.100, đây là địa chỉ IP của bộ cân bằng tải nội bộ. Các yêu cầu đến europe-west9-cloudkms.example.com sẽ được chuyển hướng đến trình cân bằng tải nội bộ, sau đó chuyển tiếp các yêu cầu đó đến điểm cuối theo khu vực của KMS thông qua Private Service Connect.

Giờ đây, bạn có thể đóng cả hai thẻ SSH đến máy ảo khách.

12. Các bước dọn dẹp

Xoá các thành phần của lớp học từ một thiết bị đầu cuối 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. Xin chúc mừng!

Chúc mừng bạn đã hoàn thành lớp học lập trình.