১. ভূমিকা
প্রাইভেট সার্ভিস কানেক্ট হলো গুগল ক্লাউড নেটওয়ার্কিং-এর একটি সক্ষমতা, যা কনজিউমারদের প্রডিউসার সার্ভিস অ্যাক্সেস করার সুযোগ দেয়। এর মধ্যে ব্যবহারকারীর (সাধারণত কনজিউমার) ভিপিসি-র (VPC) মধ্যে হোস্ট করা একটি প্রাইভেট এন্ডপয়েন্টের মাধ্যমে গুগল এপিআই-এর (API) সাথে সংযোগ করার ক্ষমতা অন্তর্ভুক্ত।
এছাড়াও, অঞ্চল-নির্দিষ্ট গুগল এপিআই নির্দেশ করার জন্য পিএসসি ব্যাকএন্ডগুলোকে গুগল ক্লাউড প্রক্সি লোড ব্যালান্সারের সাথে একত্রে ব্যবহার করা যেতে পারে। পিএসসি ব্যাকএন্ড ব্যবহারের মাধ্যমে গ্রাহক পর্যায়ে আরও সূক্ষ্ম নিয়ন্ত্রণ পাওয়া যায়, যেমন:
- ইউআরএল ম্যাপ ব্যবহার করে কোন কোন গুগল এপিআই পরিষেবা উপলব্ধ আছে তা নির্বাচন করা
- গভীরতর পর্যবেক্ষণযোগ্যতা
- ক্লাউড আর্মার ইন্টিগ্রেশন
- কাস্টম ইউআরএল
- উন্নত ট্র্যাফিক ব্যবস্থাপনা
উপলব্ধ পরিষেবা এবং তাদের আঞ্চলিক এপিআই-এর তালিকা এখানে পাওয়া যাবে।
এই কোডল্যাবে, আপনি আঞ্চলিক ক্লাউড কেএমএস এপিআই (API)-কে নির্দেশ করে একটি পিএসসি ব্যাকএন্ড (PSC Backend) তৈরি করবেন এবং সেই এপিআই-এর সাথে সংযোগ পরীক্ষা করবেন।
আপনি যা শিখবেন
- একটি ক্লাউড কী ম্যানেজমেন্ট সার্ভিস (কেএমএস) কী রিং এবং চাবি তৈরি করুন।
- একটি PSC ব্যাকএন্ড সহ একটি অভ্যন্তরীণ অ্যাপ্লিকেশন লোড ব্যালেন্সার তৈরি করুন যা একটি ক্লাউড KMS আঞ্চলিক API-এর দিকে নির্দেশিত থাকবে।
- ক্লাউড ডিএনএস পরিচালিত প্রাইভেট জোন এবং এ রেকর্ড তৈরি করা।
- আঞ্চলিক ক্লাউড কেএমএস অ্যাক্সেস করুন
আপনার যা যা লাগবে
- একটি গুগল ক্লাউড প্রজেক্ট, যেখানে আদর্শগতভাবে 'Owner' অথবা সম্পূর্ণ 'Editor' পারমিশন থাকা উচিত।
২. কোডল্যাব টপোলজি

একটি কনজিউমার ভিপিসি তৈরি করা হবে, যেখানে europe-west9 রিজিয়নে একটি ভিএম (VM), ইন্টারনাল রিজিওনাল অ্যাপ্লিকেশন লোড ব্যালেন্সার ফরওয়ার্ডিং রুল এবং পিএসসি ব্যাকএন্ড হোস্ট করার জন্য একটি সাবনেট এবং লোড ব্যালেন্সারের সাথে ব্যবহারের জন্য শুধুমাত্র একটি প্রক্সি সাবনেট থাকবে। আমরা europe-west রিজিয়নের ক্লাউড কী ম্যানেজমেন্ট সিস্টেমে (KMS) একটি কী রিং এবং কী তৈরি করব। এরপর আমরা europe-west9-এ রিজিওনাল কেএমএস এপিআই (KMS API)-কে রিজলভ করার জন্য লোড ব্যালেন্সার এবং পিএসসি ব্যাকএন্ড তৈরি করব।
৩. সেটআপ এবং প্রয়োজনীয়তা
স্ব-গতিতে পরিবেশ সেটআপ
- Google Cloud Console- এ সাইন-ইন করুন এবং একটি নতুন প্রজেক্ট তৈরি করুন অথবা বিদ্যমান কোনো প্রজেক্ট পুনরায় ব্যবহার করুন। যদি আপনার আগে থেকে Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তবে আপনাকে অবশ্যই একটি তৈরি করতে হবে।



- প্রজেক্টের নামটি হলো এই প্রজেক্টের অংশগ্রহণকারীদের প্রদর্শিত নাম। এটি একটি ক্যারেক্টার স্ট্রিং যা গুগল এপিআই ব্যবহার করে না। আপনি যেকোনো সময় এটি আপডেট করতে পারেন।
- প্রজেক্ট আইডি সমস্ত গুগল ক্লাউড প্রজেক্ট জুড়ে অনন্য এবং অপরিবর্তনীয় (একবার সেট করার পর এটি পরিবর্তন করা যায় না)। ক্লাউড কনসোল স্বয়ংক্রিয়ভাবে একটি অনন্য স্ট্রিং তৈরি করে; সাধারণত এটি কী তা নিয়ে আপনার মাথা ঘামানোর দরকার নেই। বেশিরভাগ কোডল্যাবে, আপনাকে আপনার প্রজেক্ট আইডি উল্লেখ করতে হবে (যা সাধারণত
PROJECT_IDহিসাবে চিহ্নিত করা হয়)। তৈরি করা আইডিটি আপনার পছন্দ না হলে, আপনি এলোমেলোভাবে আরেকটি তৈরি করতে পারেন। বিকল্পভাবে, আপনি আপনার নিজের আইডি দিয়ে চেষ্টা করে দেখতে পারেন যে সেটি উপলব্ধ আছে কিনা। এই ধাপের পরে এটি পরিবর্তন করা যাবে না এবং প্রজেক্টের পুরো সময়কাল জুড়ে এটি অপরিবর্তিত থাকবে। - আপনার অবগতির জন্য জানাচ্ছি যে, তৃতীয় একটি ভ্যালু রয়েছে, যা হলো প্রজেক্ট নম্বর , এবং কিছু এপিআই এটি ব্যবহার করে থাকে। ডকুমেন্টেশনে এই তিনটি ভ্যালু সম্পর্কে আরও বিস্তারিত জানুন।
- এরপর, ক্লাউড রিসোর্স/এপিআই ব্যবহার করার জন্য আপনাকে ক্লাউড কনসোলে বিলিং চালু করতে হবে। এই কোডল্যাবটি সম্পন্ন করতে খুব বেশি খরচ হবে না, এমনকি আদৌ কোনো খরচ নাও হতে পারে। এই টিউটোরিয়ালের পর বিলিং এড়াতে রিসোর্সগুলো বন্ধ করার জন্য, আপনি আপনার তৈরি করা রিসোর্সগুলো অথবা প্রজেক্টটি ডিলিট করে দিতে পারেন। নতুন গুগল ক্লাউড ব্যবহারকারীরা ৩০০ মার্কিন ডলারের ফ্রি ট্রায়াল প্রোগ্রামের জন্য যোগ্য।
ক্লাউড শেল শুরু করুন
যদিও গুগল ক্লাউড আপনার ল্যাপটপ থেকে দূরবর্তীভাবে পরিচালনা করা যায়, এই কোডল্যাবে আপনি গুগল ক্লাউড শেল ব্যবহার করবেন, যা ক্লাউডে চালিত একটি কমান্ড লাইন পরিবেশ।
গুগল ক্লাউড কনসোল থেকে, উপরের ডানদিকের টুলবারে থাকা ক্লাউড শেল আইকনটিতে ক্লিক করুন:

পরিবেশটি প্রস্তুত করতে এবং এর সাথে সংযোগ স্থাপন করতে মাত্র কয়েক মুহূর্ত সময় লাগবে। এটি শেষ হলে, আপনি এইরকম কিছু দেখতে পাবেন:

এই ভার্চুয়াল মেশিনটিতে আপনার প্রয়োজনীয় সমস্ত ডেভেলপমেন্ট টুলস লোড করা আছে। এটি একটি স্থায়ী ৫ জিবি হোম ডিরেক্টরি প্রদান করে এবং গুগল ক্লাউডে চলে, যা নেটওয়ার্ক পারফরম্যান্স ও অথেনটিকেশনকে ব্যাপকভাবে উন্নত করে। এই কোডল্যাবে আপনার সমস্ত কাজ একটি ব্রাউজারের মধ্যেই করা যাবে। আপনাকে কিছুই ইনস্টল করতে হবে না।
৪. শুরু করার আগে
এপিআই সক্ষম করুন
ক্লাউড শেলের ভিতরে, নিশ্চিত করুন যে আপনার প্রজেক্ট আইডি সেট আপ করা আছে।
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
৫. ভিপিসি নেটওয়ার্ক, সাবনেট এবং ফায়ারওয়াল নিয়ম তৈরি করুন
ভিপিসি নেটওয়ার্ক তৈরি করুন
ক্লাউড শেল থেকে
# 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
সাবনেট তৈরি করুন
ক্লাউড শেল থেকে
gcloud compute networks subnets create ${SUBNET_NAME} \
--network=${VPC_NAME} \
--region=${REGION} \
--range=10.0.0.0/24 \
--enable-private-ip-google-access
এই ল্যাবে, আপনি আঞ্চলিক এপিআই ব্যাকএন্ডগুলোকে নির্দেশ করার জন্য একটি অভ্যন্তরীণ L7 আঞ্চলিক লোড ব্যালেন্সার তৈরি করবেন। এই লোড ব্যালেন্সারটি একটি প্রক্সি লোড ব্যালেন্সার, তাই প্রক্সির কাজটি সম্পাদনের জন্য আপনাকে লোড ব্যালেন্সারটির জন্য একটি বিশেষ "প্রক্সি সাবনেট" তৈরি করতে হবে। শুধুমাত্র প্রক্সির জন্য ব্যবহৃত সাবনেটটি সম্পর্কে আরও তথ্য এখানে পাওয়া যাবে।
ক্লাউড শেল থেকে
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 ব্যবহার করতে না চান, তাহলে আপনি এই ধাপটি বাদ দিতে পারেন এবং এর পরিবর্তে ইনস্ট্যান্সে পাবলিক আইপি অ্যাড্রেস যোগ করতে পারেন ও একটি ফায়ারওয়াল নিয়ম তৈরি করতে পারেন যা 0.0.0.0/0 থেকে TCP পোর্ট 22-এ ইনগ্রেসের অনুমতি দেয়।
আপনার VM ইনস্ট্যান্সগুলিতে IAP-কে সংযোগ করার অনুমতি দিতে, এমন একটি ফায়ারওয়াল নিয়ম তৈরি করুন যা:
- এটি সেই সমস্ত VM ইনস্ট্যান্সের ক্ষেত্রে প্রযোজ্য, যেগুলোকে আপনি IAP ব্যবহার করে অ্যাক্সেসযোগ্য করতে চান।
- 35.235.240.0/20 আইপি রেঞ্জ থেকে ইনগ্রেস ট্র্যাফিকের অনুমতি দেয়। এই রেঞ্জে সেই সমস্ত আইপি অ্যাড্রেস রয়েছে যা IAP টিসিপি ফরওয়ার্ডিংয়ের জন্য ব্যবহার করে।
ক্লাউড শেল থেকে
gcloud compute firewall-rules create allow-ssh-iap \
--network=${VPC_NAME} \
--allow tcp:22 \
--source-ranges=35.235.240.0/20
৬. ক্লাউড NAT তৈরি করুন
লিনাক্স প্যাকেজ ডিস্ট্রিবিউশন ডাউনলোড করার জন্য একটি ক্লাউড ন্যাট (Cloud NAT) তৈরি করতে হবে।
ক্লাউড রাউটার তৈরি করুন
ক্লাউড শেল থেকে
gcloud compute routers create crnat \
--network=${VPC_NAME} \
--region=${REGION}
ক্লাউড NAT তৈরি করুন
ক্লাউড শেল থেকে
gcloud compute routers nats create europe-nat \
--router=crnat \
--auto-allocate-nat-external-ips \
--nat-all-subnet-ip-ranges \
--enable-logging \
--region=${REGION}
৭. কী ম্যানেজমেন্ট কী রিং এবং কী তৈরি করুন
ক্লাউড শেল থেকে
gcloud kms keyrings create europe-kr \
--location ${REGION}
ক্লাউড শেল থেকে
gcloud kms keys create europe-key \
--location ${REGION} \
--keyring europe-kr \
--purpose encryption
ক্লাউড শেল থেকে নিশ্চিত করুন যে ইউরোপ-ওয়েস্ট অঞ্চলে কী রিং এবং কী সফলভাবে তৈরি হয়েছে।
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
কী-গুলোর জন্য দেওয়া সম্পূর্ণ পাথ নেমটি নোট করে রাখুন, কারণ পরবর্তীতে সংযোগ করার জন্য আপনাকে এটি ব্যবহার করতে হবে।
৮. ক্লায়েন্ট ভিএম তৈরি করুন এবং কেএমএস এপিআই-এর সাথে সংযোগ করুন।
এরপর আপনি একটি ক্লায়েন্ট ভিএম তৈরি করবেন, ভিএম-টিতে SSH করবেন এবং গ্লোবাল KMS API-এর রেজোলিউশন পরীক্ষা করবেন। এই পরীক্ষাটি গ্লোবাল গুগল এপিআই রেজোলিউশনের জন্য ডিফল্ট বিকল্পটি উপস্থাপন করে।
ক্লাউড শেল থেকে
#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"
এরপরে, আপনার তৈরি করা KMS কী-তে অ্যাক্সেস পেতে ডিফল্ট কম্পিউট সার্ভিস অ্যাকাউন্টটি আপডেট করতে হবে। ডিফল্ট কম্পিউট সার্ভিস অ্যাকাউন্টটি <Project_Number> -compute@developer.gserviceaccount.com ফরম্যাটে থাকবে। প্রজেক্ট নম্বরটি পেতে ক্লাউড শেল থেকে নিম্নলিখিত কমান্ডটি চালান এবং রিটার্ন ফলাফলের শেষ লাইনের নম্বরটি কপি করুন।
gcloud projects describe $PROJECT_ID
আপনার তৈরি করা KMS কী-তে অ্যাক্সেস পেতে ডিফল্ট কম্পিউট সার্ভিস অ্যাকাউন্টটি আপডেট করুন।
ক্লাউড শেল থেকে
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
+ এ ক্লিক করে একটি অতিরিক্ত ক্লাউড শেল টার্মিনাল তৈরি করুন (নিচের স্ক্রিনশট দেখুন)।

ট্যাব ২-এ, IAP-এর মাধ্যমে টানেল করে ক্লায়েন্ট-ভিএম-এ SSH করুন। মনে রাখবেন যে এনভায়রনমেন্ট ভেরিয়েবলগুলো সাথে থাকবে না এবং আপনাকে নিচের কমান্ডে আপনার প্রজেক্ট-আইডি যোগ করতে হবে।
ক্লাউড শেল থেকে
# 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 কী-নেমটি ব্যবহার করে গ্লোবাল KMS API-এর সাথে সংযোগ করুন।
ট্যাব ২ থেকে, ক্লায়েন্ট-ভিএম
# 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
DNS কোথায় KMS এন্ডপয়েন্টটি রিজলভ করছে তা যাচাই করে দেখুন।
ট্যাব২ থেকে, ক্লায়েন্ট-ভিএম
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
ট্যাব২ থেকে, ক্লায়েন্ট-ভিএম
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
গুগল এপিআই-এর ডিফল্ট আচরণ হলো গ্লোবাল এপিআই সার্ভিস এন্ডপয়েন্ট ব্যবহার করা। এই এন্ডপয়েন্টটি পাবলিক আইপি-র একটি তালিকা প্রদান করে। cloudkms.googleapis.com- এর জন্য dig কমান্ডটি এটিই দেখায়। (দ্রষ্টব্য: আপনি যে আইপি অ্যাড্রেসটি দেখছেন, সেটি একটি ভিন্ন এক্সটার্নাল আইপি অ্যাড্রেসও হতে পারে। এটি গুগল এপিআই-এর একটি স্বাভাবিক আচরণ।)
PSC-এর সাথে আঞ্চলিক গুগল এপিআই এন্ডপয়েন্ট ব্যবহার করে, আপনি এপিআই ট্র্যাফিকের জন্য আঞ্চলিক প্রয়োজনীয়তা পূরণ করতে পারেন এবং সেইসাথে রেজোলিউশন পাবলিক থেকে প্রাইভেটে পরিবর্তন করতে পারেন। cloudkms.europe-west9.rep.googleapis.com- এর dig থেকে দেখা যায় যে, এই মুহূর্তে আঞ্চলিক KSM এপিআই এন্ডপয়েন্টের রেজোলিউশন এখনও পাবলিক রয়েছে।
পরবর্তী বিভাগগুলিতে আমরা গ্লোবাল কেএমএস এপিআই এন্ডপয়েন্ট ব্যবহার করা থেকে আঞ্চলিক এন্ডপয়েন্টে স্থানান্তরিত হব এবং পিএসসি ব্যাকএন্ড ব্যবহার করে রেজোলিউশনকে প্রাইভেটে পরিবর্তন করব।
৯. পিএসসি নেগেটিভ এবং লোড ব্যালেন্সার তৈরি করুন
পরবর্তী অংশের জন্য, ক্লাউড শেলের প্রথম ট্যাবে ফিরে যান।
আপনি একটি ইন্টারনাল HTTP(S) লোড ব্যালেন্সার তৈরি করবেন, যার একটি নেটওয়ার্ক এন্ডপয়েন্ট গ্রুপ (NEG) থাকবে এবং যা ব্যাকএন্ড সার্ভিস হিসেবে ইউরোপ রিজিওনাল KMS এন্ডপয়েন্টকে নির্দেশ করবে। লোড ব্যালেন্সারের ফরওয়ার্ডিং রুলটি প্রাইভেট সার্ভিস কানেক্ট (PSC) এন্ডপয়েন্ট হিসেবে কাজ করবে।
প্রাইভেট সার্ভিস কানেক্ট টাইপের এবং europe-west9-cloudkms.example.com টার্গেট সার্ভিস সহ নেটওয়ার্ক এন্ডপয়েন্ট গ্রুপ (NEG) তৈরি করুন।
ক্লাউড শেল থেকে
#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}
লোড ব্যালান্সারের জন্য ব্যাকএন্ড সার্ভিসটি তৈরি করুন।
ক্লাউড শেল থেকে
# 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 যোগ করুন।
ক্লাউড শেল থেকে
gcloud compute backend-services add-backend $BACKEND_SERVICE_NAME \
--network-endpoint-group=${NEG_NAME} \
--region=$REGION
লোড ব্যালান্সারের জন্য ইউআরএল ম্যাপ তৈরি করুন।
ক্লাউড শেল থেকে
gcloud compute url-maps create l7-psc-url-map \ --default-service=l7-psc-kms \ --region=$REGION
এন্ডপয়েন্টটি যে কাস্টম ইউআরএল ব্যবহার করবে, তার জন্য পাথ ম্যাচিং তৈরি করুন।
ক্লাউড শেল থেকে
gcloud compute url-maps add-path-matcher l7-psc-url-map \ --path-matcher-name=example \ --default-service=l7-psc-kms \ --region=$REGION
europe-west9-cloudkms.example.com কাস্টম ইউআরএলটির জন্য হোস্ট রুল তৈরি করুন।
ক্লাউড শেল থেকে
gcloud compute url-maps add-host-rule l7-psc-url-map \ --hosts=europe-west9-cloudkms.example.com \ --path-matcher-name=example \ --region=$REGION
লোড ব্যালান্সারের জন্য টার্গেট HTTPS প্রক্সি তৈরি করুন। এর জন্য একটি আঞ্চলিক SSL সার্টিফিকেট রিসোর্স তৈরি করতে হবে। একটি সেলফ-সাইন্ড সার্টিফিকেট তৈরি করার ধাপগুলো এখানে দেখুন। আমরা openssl ব্যবহার করে একটি সেলফ-সাইন্ড সার্টিফিকেট তৈরি করব এবং সেটি ব্যবহার করে GCP-তে একটি আঞ্চলিক সার্টিফিকেট রিসোর্স তৈরি করব। টার্গেট https প্রক্সি এই সার্টিফিকেটটি ব্যবহার করবে।
ক্লাউড শেল থেকে
# 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}
যে লোড ব্যালান্সারটি প্রাইভেট সার্ভিস কানেক্ট এন্ডপয়েন্ট হিসেবে কাজ করবে, তার জন্য ফরওয়ার্ডিং রুল তৈরি করুন। ফরওয়ার্ডিং রুলের জন্য ব্যবহৃত আইপি অ্যাড্রেসটি অবশ্যই ভিপিসি-র এমন একটি রিজিওনাল সাবনেটের অন্তর্ভুক্ত হতে হবে, যা আপনার অ্যাক্সেস করা এপিআই এন্ডপয়েন্টের অঞ্চলের মধ্যেই অবস্থিত।
ক্লাউড শেল থেকে
# 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
১০. ডিএনএস কনফিগারেশন
এই অংশে আপনি example.com-এর জন্য একটি প্রাইভেট DNS জোন এবং গত ধাপে তৈরি করা ফরওয়ার্ডিং রুলটিকে নির্দেশ করে একটি A রেকর্ড তৈরি করবেন।
ম্যানেজড ডিএনএস প্রাইভেট জোন তৈরি করুন।
ক্লাউড শেল থেকে
# 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}
europe-west9-cloudkms.example.com-এর জন্য একটি A রেকর্ড তৈরি করুন।
ক্লাউড শেল থেকে
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}
১১. PSC-এর মাধ্যমে আঞ্চলিক KMS API-এর সাথে সংযোগ স্থাপন করুন।
সমস্ত সংযোগের বিবরণ দেখতে এবং PSC ব্যাকএন্ডের মাধ্যমে আঞ্চলিক KMS এন্ডপয়েন্টের সংযোগগুলি পরীক্ষা করতে , ট্যাব ২-এ থাকা ক্লায়েন্ট-ভিএম-এ ফিরে গিয়ে tcpdump চালান।
sudo tcpdump -i any net 10.0.0.100 or port 53 -n
ক্লাউড শেলে একটি তৃতীয় ট্যাব খুলুন এবং ক্লায়েন্ট-ভিএম-এ SSH করুন।
# 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
ট্যাব ২ উইন্ডোতে ফিরে যান এবং tcpdump তথ্য পরীক্ষা করুন। আপনি দেখতে পাবেন যে, আপনার তৈরি করা PSC এন্ডপয়েন্টের মাধ্যমে আপনি ক্লাউড KMS রিজিওনাল এন্ডপয়েন্টটি অ্যাক্সেস করতে পেরেছেন এবং europe-west9 রিজিওনাল এন্ডপয়েন্টটি আপনার তৈরি করা ম্যানেজড ক্লাউড 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 (এটি লোড ব্যালেন্সার আইপি-তে HTTPS সংযোগের জন্য TCP হ্যান্ডশেক দেখাচ্ছে)
ট্যাব ৩-এ, ক্লায়েন্ট-ভিএম
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 কমান্ডের আউটপুট থেকে দেখা যায় যে, europe-west9-cloudkms.example.com-এর জন্য আমাদের তৈরি করা কাস্টম URL-টি সঠিকভাবে 10.0.0.100-এ রিজলভ হচ্ছে, যা হলো আপনার ইন্টারনাল লোড ব্যালান্সারের IP। europe-west9-cloudkms.example.com-এ পাঠানো রিকোয়েস্টগুলো আপনার ইন্টারনাল লোড ব্যালান্সারে পাঠানো হবে, যা পরবর্তীতে প্রাইভেট সার্ভিস কানেক্টের মাধ্যমে সেগুলোকে KMS রিজিওনাল এন্ডপয়েন্টে ফরওয়ার্ড করে দেবে।
আপনি এখন ক্লায়েন্ট-ভিএম-এর উভয় SSH ট্যাব বন্ধ করতে পারেন।
১২. পরিষ্কার করার পদক্ষেপ
একটিমাত্র ক্লাউড শেল টার্মিনাল থেকে ল্যাবের উপাদানগুলো মুছে ফেলুন
# 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
১৩. অভিনন্দন!
কোডল্যাবটি সম্পন্ন করার জন্য অভিনন্দন।