सुरक्षित बिल्ड & Cloud Build, Artifact Registry, और GKE (जीकेई) के साथ डिप्लॉय करना

1. परिचय

कंटेनर विश्लेषण की सुविधा, कंटेनर के लिए कमियों का पता लगाने और मेटाडेटा स्टोर करने की सुविधा देती है. स्कैनिंग सेवा, Artifact Registry और Container Registry में मौजूद इमेज की सुरक्षा से जुड़ी समस्याओं का पता लगाती है. इसके बाद, उससे मिलने वाले मेटाडेटा को सेव करती है और एपीआई के ज़रिए उसे इस्तेमाल के लिए उपलब्ध कराती है. मेटाडेटा स्टोरेज की मदद से, अलग-अलग सोर्स से जानकारी सेव की जा सकती है. जैसे, जोखिम की जांच, Google Cloud की सेवाएं, और तीसरे पक्ष की कंपनियां.

जोखिम की आशंका का पता लगाने वाला स्कैन, अपने-आप या मांग पर किया जा सकता है:

  • अपने-आप स्कैन होने की सुविधा चालू होने पर, Artifact Registry या Container Registry में नई इमेज को पुश करने पर, स्कैनिंग अपने-आप ट्रिगर हो जाती है. नई जोखिम की आशंकाएं मिलने पर, उनसे जुड़ी जानकारी को लगातार अपडेट किया जाता है.
  • ऑन-डिमांड स्कैनिंग की सुविधा चालू होने पर, आपको स्थानीय इमेज या Artifact Registry या Container Registry में मौजूद इमेज को स्कैन करने के लिए कोई कमांड चलाना होगा. मांग पर स्कैन करने की सुविधा की मदद से, कंटेनर को कभी भी स्कैन किया जा सकता है. उदाहरण के लिए, स्थानीय तौर पर बनाई गई इमेज को रजिस्ट्री में सेव करने से पहले, उसे स्कैन किया जा सकता है और उसमें मौजूद कमजोरियों को ठीक किया जा सकता है. स्कैन पूरा होने के बाद, स्कैन के नतीजे 48 घंटे तक उपलब्ध रहते हैं. साथ ही, स्कैन के बाद, जोखिम की जानकारी अपडेट नहीं की जाती.

Container Analysis को अपनी CI/CD पाइपलाइन में इंटिग्रेट करने पर, उस मेटाडेटा के आधार पर फ़ैसले लिए जा सकते हैं. उदाहरण के लिए, डिप्लॉयमेंट की ऐसी नीतियां बनाने के लिए बाइनरी अनुमति का इस्तेमाल किया जा सकता है जो सिर्फ़ भरोसेमंद रजिस्ट्री से मिली, नीतियों का पालन करने वाली इमेज के लिए डिप्लॉयमेंट की अनुमति देती हैं.

आपको इनके बारे में जानकारी मिलेगी

  • अपने-आप स्कैन होने की सुविधा चालू करने का तरीका
  • मांग पर स्कैन करने की सुविधा को इस्तेमाल करने का तरीका
  • स्कैनिंग को बिल्ड पाइपलाइन में इंटिग्रेट करने का तरीका
  • अनुमति वाली इमेज पर हस्ताक्षर करने का तरीका
  • इमेज ब्लॉक करने के लिए, GKE ऐडमिशन कंट्रोलर का इस्तेमाल करने का तरीका
  • सिर्फ़ हस्ताक्षर की गई और मंज़ूरी वाली इमेज को अनुमति देने के लिए, GKE को कॉन्फ़िगर करने का तरीका

2. सेटअप और ज़रूरी शर्तें

अपने हिसाब से एनवायरमेंट सेट अप करना

  1. Google Cloud Console में साइन इन करें और नया प्रोजेक्ट बनाएं या किसी मौजूदा प्रोजेक्ट का फिर से इस्तेमाल करें. अगर आपके पास पहले से कोई Gmail या Google Workspace खाता नहीं है, तो आपको एक खाता बनाना होगा.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • प्रोजेक्ट का नाम, इस प्रोजेक्ट में हिस्सा लेने वाले लोगों के लिए डिसप्ले नेम होता है. यह एक वर्ण स्ट्रिंग है, जिसका इस्तेमाल Google API नहीं करते. इसे कभी भी अपडेट किया जा सकता है.
  • प्रोजेक्ट आईडी, Google Cloud के सभी प्रोजेक्ट के लिए यूनीक होता है. साथ ही, इसे सेट करने के बाद बदला नहीं जा सकता. Cloud Console, अपने-आप एक यूनीक स्ट्रिंग जनरेट करता है. आम तौर पर, आपको यह जानने की ज़रूरत नहीं होती कि यह स्ट्रिंग क्या है. ज़्यादातर कोडलैब में, आपको प्रोजेक्ट आईडी का रेफ़रंस देना होगा. आम तौर पर, इसे PROJECT_ID के तौर पर पहचाना जाता है. अगर आपको जनरेट किया गया आईडी पसंद नहीं आता है, तो कोई दूसरा आईडी जनरेट किया जा सकता है. इसके अलावा, आपके पास खुद से भी यह पता लगाने का विकल्प है कि यह सुविधा उपलब्ध है या नहीं. इस चरण के बाद, इसे बदला नहीं जा सकता. यह प्रोजेक्ट के दौरान बना रहेगा.
  • आपकी जानकारी के लिए बता दें कि तीसरी वैल्यू, प्रोजेक्ट नंबर होती है. इसका इस्तेमाल कुछ एपीआई करते हैं. दस्तावेज़ में इन तीनों वैल्यू के बारे में ज़्यादा जानें.
  1. इसके बाद, आपको Cloud के संसाधनों/एपीआई का इस्तेमाल करने के लिए, Cloud Console में बिलिंग की सुविधा चालू करनी होगी. इस कोडलैब को चलाने में ज़्यादा खर्च नहीं आता. इस ट्यूटोरियल के बाद, आपसे कोई शुल्क न लिया जाए, इसके लिए संसाधनों को बंद किया जा सकता है. इसके लिए, आपने जो संसाधन बनाए हैं उन्हें मिटाएं या पूरा प्रोजेक्ट मिटाएं. Google Cloud के नए उपयोगकर्ता, 300 डॉलर के मुफ़्त ट्रायल वाले कार्यक्रम में शामिल हो सकते हैं.

Cloudshell Editor शुरू करना

इस लैब को Google Cloud Shell एडिटर के साथ इस्तेमाल करने के लिए डिज़ाइन और टेस्ट किया गया था. एडिटर को ऐक्सेस करने के लिए,

  1. https://console.cloud.google.com पर जाकर, अपना Google प्रोजेक्ट ऐक्सेस करें.
  2. सबसे ऊपर दाएं कोने में, Cloud Shell एडिटर आइकॉन पर क्लिक करें

8560cc8d45e8c112.png

  1. आपकी विंडो के सबसे नीचे एक नया पैनल खुलेगा

एनवायरमेंट सेटअप करना

Cloud Shell में, अपने प्रोजेक्ट के लिए प्रोजेक्ट आईडी और प्रोजेक्ट नंबर सेट करें. उन्हें PROJECT_ID और PROJECT_ID वैरिएबल के तौर पर सेव करें.

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
    --format='value(projectNumber)')

सेवाएं चालू करना

सभी ज़रूरी सेवाएं चालू करें:

gcloud services enable \
  cloudkms.googleapis.com \
  cloudbuild.googleapis.com \
  container.googleapis.com \
  containerregistry.googleapis.com \
  artifactregistry.googleapis.com \
  containerscanning.googleapis.com \
  ondemandscanning.googleapis.com \
  binaryauthorization.googleapis.com 

Artifact Registry का डेटा स्टोर करने की जगह बनाना

इस लैब में, आपको अपनी इमेज को सेव और स्कैन करने के लिए, आर्टफ़ैक्ट रजिस्ट्री का इस्तेमाल करना होगा. यहां दिए गए कमांड की मदद से, रिपॉज़िटरी बनाएं.

gcloud artifacts repositories create artifact-scanning-repo \
  --repository-format=docker \
  --location=us-central1 \
  --description="Docker repository"

Artifact Registry को ऐक्सेस करते समय, अपने gcloud क्रेडेंशियल का इस्तेमाल करने के लिए, Docker को कॉन्फ़िगर करें.

gcloud auth configure-docker us-central1-docker.pkg.dev

3. अपने-आप स्कैन होने की सुविधा

आर्टफ़ैक्ट की स्कैनिंग की सुविधा, हर बार Artifact Registry या Container Registry में नई इमेज डालने पर अपने-आप ट्रिगर होती है. नई जोखिम की आशंकाएं मिलने पर, जोखिम की जानकारी को लगातार अपडेट किया जाता है. इस सेक्शन में, आपको आर्टफ़ैक्ट रजिस्ट्री में एक इमेज को पुश करना होगा और नतीजों को एक्सप्लोर करना होगा.

वर्क डायरेक्ट्री बनाना और उसमें बदलाव करना

mkdir vuln-scan && cd vuln-scan

सैंपल इमेज तय करना

यहां दिए गए कॉन्टेंट के साथ Dockerfile नाम की फ़ाइल बनाएं.

cat > ./Dockerfile << EOF
FROM gcr.io/google-appengine/debian9@sha256:ebffcf0df9aa33f342c4e1d4c8428b784fc571cdf6fbab0b31330347ca8af97a

# System
RUN apt update && apt install python3-pip -y

# App
WORKDIR /app
COPY . ./

RUN pip3 install Flask==1.1.4
RUN pip3 install gunicorn==20.1.0

CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

EOF

main.py नाम की फ़ाइल बनाएं और उसमें यह कॉन्टेंट डालें

cat > ./main.py << EOF
import os
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    name = os.environ.get("NAME", "Worlds")
    return "Hello {}!".format(name)

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
EOF

इमेज को एआर में बनाना और उसे पुश करना

Cloud Build का इस्तेमाल करके, अपने कंटेनर को Artifact Registry में अपने-आप पॉश करने के लिए बनाएं. इमेज पर मौजूद टैग bad पर ध्यान दें. इससे आपको बाद के चरणों में, उस फ़ाइल की पहचान करने में मदद मिलेगी.

gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad

इमेज की जानकारी की समीक्षा करना

बिल्ड प्रोसेस पूरी होने के बाद, Artifact Registry के डैशबोर्ड में इमेज और जोखिम के नतीजों की समीक्षा करें.

  1. Cloud Console में आर्टफ़ैक्ट रजिस्ट्री खोलें
  2. कॉन्टेंट देखने के लिए, artifact-scanning-repo पर क्लिक करें
  3. इमेज की जानकारी पर क्लिक करें
  4. अपनी इमेज के नए डाइजेस्ट पर क्लिक करें
  5. स्कैन पूरा होने के बाद, इमेज के लिए 'सुरक्षा से जुड़ी समस्याएं' टैब पर क्लिक करें

'सुरक्षा से जुड़ी समस्याएं' टैब में, आपको उस इमेज के लिए अपने-आप स्कैन करने की सुविधा के नतीजे दिखेंगे जिसे आपने अभी बनाया है.

361be7b3bf293fca.png

अपने-आप स्कैन होने की सुविधा डिफ़ॉल्ट रूप से चालू होती है. आर्टफ़ैक्ट रजिस्ट्री की सेटिंग एक्सप्लोर करें और देखें कि अपने-आप स्कैन होने की सुविधा को कैसे बंद/चालू किया जा सकता है.

4. मांग पर स्कैनिंग

कई मामलों में, इमेज को किसी रिपॉज़िटरी में डालने से पहले, आपको स्कैन चलाना पड़ सकता है. उदाहरण के लिए, कोई कंटेनर डेवलपर, सोर्स कंट्रोल में कोड को पुश करने से पहले, किसी इमेज को स्कैन करके उसमें मौजूद समस्याओं को ठीक कर सकता है. नीचे दिए गए उदाहरण में, नतीजों पर कार्रवाई करने से पहले, इमेज को स्थानीय तौर पर बनाया और उसका विश्लेषण किया जाएगा.

इमेज बनाना

इस चरण में, आपको लोकल कैश मेमोरी में इमेज बनाने के लिए, लोकल डॉकर का इस्तेमाल करना होगा.

docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image .

इमेज स्कैन करना

इमेज बन जाने के बाद, इमेज को स्कैन करने का अनुरोध करें. स्कैन के नतीजे, मेटाडेटा सर्वर में सेव किए जाते हैं. मेटाडेटा सर्वर में नतीजों की जगह की जानकारी के साथ, यह प्रोसेस पूरी हो जाती है.

gcloud artifacts docker images scan \
    us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
    --format="value(response.scan)" > scan_id.txt

आउटपुट फ़ाइल की समीक्षा करना

पिछले चरण के आउटपुट की समीक्षा करें. यह आउटपुट, scan_id.txt फ़ाइल में सेव किया गया था. मेटाडेटा सर्वर में, स्कैन के नतीजों की रिपोर्ट की जगह देखें.

cat scan_id.txt

स्कैन के ज़्यादा जानकारी वाले नतीजे देखना

स्कैन के असल नतीजे देखने के लिए, आउटपुट फ़ाइल में बताई गई रिपोर्ट की जगह पर list-vulnerabilities कमांड का इस्तेमाल करें.

gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt) 

आउटपुट में, इमेज में मौजूद सभी कमजोरियों के बारे में काफ़ी डेटा होता है.

गंभीर समस्याओं की शिकायत करना

लोग रिपोर्ट में सेव किए गए डेटा का सीधे तौर पर इस्तेमाल कम ही करते हैं. आम तौर पर, इन नतीजों का इस्तेमाल अपने-आप काम करने वाली प्रोसेस के ज़रिए किया जाता है. रिपोर्ट की जानकारी पढ़ने और कोई गंभीर समस्या मिलने पर उसे लॉग करने के लिए, नीचे दिए गए निर्देशों का इस्तेमाल करें

export SEVERITY=CRITICAL

gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt) --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq ${SEVERITY}; then echo "Failed vulnerability check for ${SEVERITY} level"; else echo "No ${SEVERITY} Vulnerabilities found"; fi

इस कमांड का आउटपुट

Failed vulnerability check for CRITICAL level

5. पाइपलाइन स्कैनिंग बनाना

इस सेक्शन में, आपको अपने-आप काम करने वाली एक बिल्ड पाइपलाइन बनानी होगी. यह आपकी कंटेनर इमेज को बनाएगी, उसे स्कैन करेगी, और फिर नतीजों का आकलन करेगी. अगर कोई गंभीर समस्या नहीं मिलती है, तो यह इमेज को रिपॉज़िटरी में पुश कर देगा. अगर गंभीर जोखिम मिलते हैं, तो बिल्ड पूरा नहीं होगा और प्रोसेस बंद हो जाएगी.

Cloud Build सेवा खाते का ऐक्सेस देना

ऑन-डिमांड स्कैनिंग एपीआई को ऐक्सेस करने के लिए, Cloud Build को अधिकार चाहिए होंगे. नीचे दिए गए निर्देशों की मदद से ऐक्सेस दें.

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/iam.serviceAccountUser"
        
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/ondemandscanning.admin"

Cloud Build पाइपलाइन बनाना

यह कमांड आपकी डायरेक्ट्री में cloudbuild.yaml फ़ाइल बनाएगा. इसका इस्तेमाल, अपने-आप होने वाली प्रोसेस के लिए किया जाएगा. इस उदाहरण में, कंटेनर बनाने की प्रोसेस के चरण ही शामिल किए गए हैं. हालांकि, आम तौर पर आपको कंटेनर के चरणों के अलावा, ऐप्लिकेशन के हिसाब से निर्देश और टेस्ट शामिल करने होंगे.

इस कमांड की मदद से फ़ाइल बनाएं.

cat > ./cloudbuild.yaml << EOF
steps:

# build
- id: "build"
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
  waitFor: ['-']

#Run a vulnerability scan at _SECURITY level
- id: scan
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    (gcloud artifacts docker images scan \
    us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
    --location us \
    --format="value(response.scan)") > /workspace/scan_id.txt

#Analyze the result of the scan
- id: severity check
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
      gcloud artifacts docker images list-vulnerabilities \$(cat /workspace/scan_id.txt) \
      --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq CRITICAL; \
      then echo "Failed vulnerability check for CRITICAL level" && exit 1; else echo "No CRITICAL vulnerability found, congrats !" && exit 0; fi

#Retag
- id: "retag"
  name: 'gcr.io/cloud-builders/docker'
  args: ['tag',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']


#pushing to artifact registry
- id: "push"
  name: 'gcr.io/cloud-builders/docker'
  args: ['push',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']

images:
  - us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
EOF

सीआई पाइपलाइन चलाना

गंभीर समस्या का पता चलने पर, प्रोसेसिंग के लिए बिल्ड सबमिट करें. इससे, बिल्ड के रुकने की पुष्टि की जा सकेगी.

gcloud builds submit

Review Build Failure

आपने जो बिल्ड अभी सबमिट किया है वह काम नहीं करेगा, क्योंकि इमेज में गंभीर कमजोरियां हैं.

Cloud Build का इतिहास पेज पर जाकर, बिल्ड न हो पाने की वजह देखें

जोखिम को ठीक करना

Dockerfile को अपडेट करके, ऐसी बेस इमेज का इस्तेमाल करें जिसमें गंभीर कमजोरियां न हों.

नीचे दिए गए कमांड का इस्तेमाल करके, Debian 10 इमेज का इस्तेमाल करने के लिए Dockerfile को ओवरराइट करें

cat > ./Dockerfile << EOF
from python:3.8-slim  

# App
WORKDIR /app
COPY . ./

RUN pip3 install Flask==2.1.0
RUN pip3 install gunicorn==20.1.0

CMD exec gunicorn --bind :\$PORT --workers 1 --threads 8 main:app

EOF

अच्छी इमेज के साथ सीआई प्रोसेस चलाएं

प्रोसेसिंग के लिए बिल्ड सबमिट करें, ताकि यह पुष्टि की जा सके कि गंभीर समस्याएं न मिलने पर बिल्ड पूरा हो जाएगा.

gcloud builds submit

समीक्षा करें कि बिल्ड पूरा हो गया है या नहीं

आपने जो बिल्ड अभी सबमिट किया है वह पास हो जाएगा, क्योंकि अपडेट की गई इमेज में कोई गंभीर समस्या नहीं है.

Cloud Build का इतिहास पेज पर, बिल्ड की सफलता की समीक्षा करें

स्कैन के नतीजों की समीक्षा करना

आर्टफ़ैक्ट रजिस्ट्री में अच्छी इमेज की समीक्षा करना

  1. Cloud Console में आर्टफ़ैक्ट रजिस्ट्री खोलें
  2. कॉन्टेंट देखने के लिए, artifact-scanning-repo पर क्लिक करें
  3. इमेज की जानकारी पर क्लिक करें
  4. अपनी इमेज के नए डाइजेस्ट पर क्लिक करें
  5. इमेज के लिए, 'सुरक्षा से जुड़ी समस्याएं' टैब पर क्लिक करें

6. इमेज पर हस्ताक्षर करना

पुष्टि करने वाले व्यक्ति का नोट बनाना

पुष्टि करने वाले व्यक्ति का नोट, बस थोड़ा सा डेटा होता है. यह लागू किए जा रहे हस्ताक्षर के टाइप के लिए लेबल के तौर पर काम करता है. उदाहरण के लिए, एक नोट में कमज़ोरी का स्कैन दिख सकता है, जबकि दूसरे नोट का इस्तेमाल क्यूए साइन ऑफ के लिए किया जा सकता है. साइन करने की प्रोसेस के दौरान, नोट का रेफ़रंस दिया जाएगा.

नोट बनाना

cat > ./vulnz_note.json << EOM
{
  "attestation": {
    "hint": {
      "human_readable_name": "Container Vulnerabilities attestation authority"
    }
  }
}
EOM

नोट सेव करना

NOTE_ID=vulnz_note

curl -vvv -X POST \
    -H "Content-Type: application/json"  \
    -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
    --data-binary @./vulnz_note.json  \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"

नोट की पुष्टि करना

curl -vvv  \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"

पुष्टि करने वाला व्यक्ति बनाना

पुष्टि करने वाले लोगों या कंपनियों का इस्तेमाल, इमेज पर हस्ताक्षर करने की असल प्रोसेस को पूरा करने के लिए किया जाता है. साथ ही, बाद में पुष्टि करने के लिए, नोट की एक कॉपी को इमेज में अटैच किया जाएगा. बाद में इस्तेमाल करने के लिए, पुष्टि करने वाला व्यक्ति बनाएं.

पुष्टि करने वाला व्यक्ति बनाना

ATTESTOR_ID=vulnz-attestor

gcloud container binauthz attestors create $ATTESTOR_ID \
    --attestation-authority-note=$NOTE_ID \
    --attestation-authority-note-project=${PROJECT_ID}

पुष्टि करने वाले व्यक्ति की पहचान की पुष्टि करना

gcloud container binauthz attestors list

ध्यान दें कि आखिरी लाइन से पता चलता है कि NUM_PUBLIC_KEYS: 0 आपको बाद के चरण में पासकोड देने होंगे

यह भी ध्यान रखें कि इमेज जनरेट करने वाला कोई बिल्ड चलाने पर, Cloud Build आपके प्रोजेक्ट में built-by-cloud-build अटेस्टर अपने-आप बना देता है. इसलिए, ऊपर दिया गया कमांड दो पुष्टि करने वालों की जानकारी दिखाता है, vulnz-attestor और built-by-cloud-build. इमेज बन जाने के बाद, Cloud Build उनके लिए अपने-आप हस्ताक्षर करता है और पुष्टि करता है.

IAM भूमिका जोड़ना

बाइनरी अनुमति सेवा खाते को, पुष्टि करने वाले नोट देखने के लिए अधिकारों की ज़रूरत होगी. नीचे दिए गए एपीआई कॉल की मदद से ऐक्सेस दें

PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}"  --format="value(projectNumber)")

BINAUTHZ_SA_EMAIL="service-${PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"


cat > ./iam_request.json << EOM
{
  'resource': 'projects/${PROJECT_ID}/notes/${NOTE_ID}',
  'policy': {
    'bindings': [
      {
        'role': 'roles/containeranalysis.notes.occurrences.viewer',
        'members': [
          'serviceAccount:${BINAUTHZ_SA_EMAIL}'
        ]
      }
    ]
  }
}
EOM

IAM नीति बनाने के लिए फ़ाइल का इस्तेमाल करना

curl -X POST  \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    --data-binary @./iam_request.json \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"

केएमएस कुंजी जोड़ना

नोट अटैच करने और पुष्टि किए जा सकने वाले हस्ताक्षर देने के लिए, पुष्टि करने वाले व्यक्ति के पास क्रिप्टोग्राफ़िक कुंजियां होनी चाहिए. इस चरण में, आपको बाद में ऐक्सेस करने के लिए, Cloud Build के लिए केएमएस में कुंजियां बनानी होंगी और उन्हें सेव करना होगा.

नई कुंजी के बारे में बताने के लिए, पहले कुछ एनवायरमेंट वैरिएबल जोड़ें

KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1

चाबियों का सेट रखने के लिए की-रिंग बनाना

gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"

पुष्टि करने वाले व्यक्ति के लिए, असिमेट्रिक साइनिंग पासकोड का नया जोड़ा बनाएं

gcloud kms keys create "${KEY_NAME}" \
    --keyring="${KEYRING}" --location="${KEY_LOCATION}" \
    --purpose asymmetric-signing   \
    --default-algorithm="ec-sign-p256-sha256"

आपको Google Cloud Console के KMS पेज पर अपनी कुंजी दिखेगी.

अब, gcloud binauthz कमांड की मदद से, पासकोड को अपने पुष्टि करने वाले एजेंट से जोड़ें:

gcloud beta container binauthz attestors public-keys add  \
    --attestor="${ATTESTOR_ID}"  \
    --keyversion-project="${PROJECT_ID}"  \
    --keyversion-location="${KEY_LOCATION}" \
    --keyversion-keyring="${KEYRING}" \
    --keyversion-key="${KEY_NAME}" \
    --keyversion="${KEY_VERSION}"

अगर आपने फिर से अधिकारियों की सूची प्रिंट की, तो आपको रजिस्टर की गई एक कुंजी दिखेगी:

gcloud container binauthz attestors list

हस्ताक्षर किया गया एटेस्टेशन बनाना

अब आपके पास इमेज पर हस्ताक्षर करने की सुविधाएं कॉन्फ़िगर हो गई हैं. उस कंटेनर इमेज पर हस्ताक्षर करने के लिए, पहले से बनाए गए Attestor का इस्तेमाल करें जिस पर काम किया जा रहा है

CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image

DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:latest \
    --format='get(image_summary.digest)')

अब, पुष्टि करने के लिए gcloud का इस्तेमाल किया जा सकता है. यह कमांड, उस पासकोड की जानकारी लेता है जिसका इस्तेमाल आपको हस्ताक्षर करने के लिए करना है. साथ ही, उस कंटेनर इमेज की जानकारी भी लेता है जिसे आपको मंज़ूरी देनी है

gcloud beta container binauthz attestations sign-and-create  \
    --artifact-url="${CONTAINER_PATH}@${DIGEST}" \
    --attestor="${ATTESTOR_ID}" \
    --attestor-project="${PROJECT_ID}" \
    --keyversion-project="${PROJECT_ID}" \
    --keyversion-location="${KEY_LOCATION}" \
    --keyversion-keyring="${KEYRING}" \
    --keyversion-key="${KEY_NAME}" \
    --keyversion="${KEY_VERSION}"

कंटेनर विश्लेषण के हिसाब से, इससे एक नई घटना बन जाएगी और उसे आपके पुष्टि करने वाले व्यक्ति के नोट से अटैच कर दिया जाएगा. यह पक्का करने के लिए कि सब कुछ उम्मीद के मुताबिक काम कर रहा है, अपने एटेस्टेशन की सूची बनाई जा सकती है

gcloud container binauthz attestations list \
   --attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}

7. Cloud Build की मदद से साइन इन करना

आपने इमेज साइनिंग की सुविधा चालू की हो और अपनी सैंपल इमेज पर हस्ताक्षर करने के लिए, मैन्युअल रूप से Attestor का इस्तेमाल किया हो. आम तौर पर, आपको अपने-आप काम करने वाली प्रोसेस के दौरान, पुष्टि करने की सुविधाएं लागू करनी होंगी. जैसे, सीआई/सीडी पाइपलाइन.

इस सेक्शन में, आपको Cloud Build को कॉन्फ़िगर करना होगा, ताकि वह इमेज की पुष्टि अपने-आप कर सके

भूमिकाएं

Cloud Build के सेवा खाते में, बाइनरी अनुमति देने वाले व्यक्ति की भूमिका जोड़ें:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/binaryauthorization.attestorsViewer

Cloud Build सेवा खाते में Cloud KMS क्रिप्टोकी साइनर/पुष्टि करने वाले की भूमिका जोड़ें (केएमएस पर आधारित साइनिंग):

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/cloudkms.signerVerifier

Cloud Build के सेवा खाते में, कंटेनर विश्लेषण नोट अटैचर की भूमिका जोड़ें:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/containeranalysis.notes.attacher

कस्टम बिल्ड के लिए Cloud Build का चरण तैयार करना

पुष्टि करने की प्रोसेस को आसान बनाने के लिए, आपको Cloud Build में कस्टम बिल्ड चरण का इस्तेमाल करना होगा. Google, कस्टम बिल्ड का यह चरण उपलब्ध कराता है. इसमें प्रोसेस को आसान बनाने के लिए, सहायक फ़ंक्शन शामिल होते हैं. इस्तेमाल करने से पहले, कस्टम बिल्ड चरण के लिए कोड को कंटेनर में बनाया जाना चाहिए और Cloud Build पर पुश किया जाना चाहिए. ऐसा करने के लिए, ये कमांड चलाएं:

git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
cd cloud-builders-community/binauthz-attestation
gcloud builds submit . --config cloudbuild.yaml
cd ../..
rm -rf cloud-builders-community

अपने cloudbuild.yaml में हस्ताक्षर करने का चरण जोड़ना

इस चरण में, आपको अपनी पहले से बनाई गई Cloud Build पाइपलाइन में पुष्टि करने का चरण जोड़ना होगा.

  1. जो नया चरण जोड़ना है उसकी समीक्षा करें.

सिर्फ़ समीक्षा करने के लिए. कॉपी न करें

#Sign the image only if the previous severity check passes
- id: 'create-attestation'
  name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
  args:
    - '--artifact-url'
    - 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image'
    - '--attestor'
    - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID'
    - '--keyversion'
    - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
  1. अपडेट की गई पूरी पाइपलाइन के साथ, अपनी cloudbuild.yaml फ़ाइल को ओवरराइट करें.
cat > ./cloudbuild.yaml << EOF
steps:

# build
- id: "build"
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
  waitFor: ['-']

#Run a vulnerability scan at _SECURITY level
- id: scan
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    (gcloud artifacts docker images scan \
    us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
    --location us \
    --format="value(response.scan)") > /workspace/scan_id.txt

#Analyze the result of the scan
- id: severity check
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
      gcloud artifacts docker images list-vulnerabilities \$(cat /workspace/scan_id.txt) \
      --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq CRITICAL; \
      then echo "Failed vulnerability check for CRITICAL level" && exit 1; else echo "No CRITICAL vulnerability found, congrats !" && exit 0; fi

#Retag
- id: "retag"
  name: 'gcr.io/cloud-builders/docker'
  args: ['tag',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']


#pushing to artifact registry
- id: "push"
  name: 'gcr.io/cloud-builders/docker'
  args: ['push',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']


#Sign the image only if the previous severity check passes
- id: 'create-attestation'
  name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
  args:
    - '--artifact-url'
    - 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good'
    - '--attestor'
    - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID'
    - '--keyversion'
    - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'



images:
  - us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good
EOF

बिल्ड चलाना

gcloud builds submit

Cloud Build के इतिहास में मौजूद बिल्ड की समीक्षा करना

Cloud Console खोलें और Cloud Build का इतिहास वाला पेज देखें. इसके बाद, हाल ही में किए गए बिल्ड और बिल्ड के चरणों को पूरा होने की जानकारी देखें.

8. प्रवेश नियंत्रण से जुड़ी नीतियां

बाइनरी अनुमति, GKE और Cloud Run की एक सुविधा है. इससे, कंटेनर इमेज को चलाने की अनुमति देने से पहले, नियमों की पुष्टि की जा सकती है. पुष्टि करने की प्रोसेस, किसी भी इमेज को चलाने के अनुरोध पर लागू होती है. भले ही, वह अनुरोध किसी भरोसेमंद CI/CD पाइपलाइन से किया गया हो या उपयोगकर्ता ने मैन्युअल तरीके से इमेज को डिप्लॉय करने की कोशिश की हो. इस सुविधा की मदद से, अपने रनटाइम एनवायरमेंट को सिर्फ़ सीआई/सीडी पाइपलाइन की जांच करने की तुलना में ज़्यादा असरदार तरीके से सुरक्षित किया जा सकता है.

इस सुविधा को समझने के लिए, आपको अनुमति के सख्त नियम को लागू करने के लिए, GKE की डिफ़ॉल्ट नीति में बदलाव करना होगा.

GKE क्लस्टर बनाना

GKE क्लस्टर बनाएं:

gcloud beta container clusters create binauthz \
    --zone us-central1-a  \
    --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE

Cloud Build को इस क्लस्टर पर डिप्लॉय करने की अनुमति दें:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/container.developer"

सभी को अनुमति देने की नीति

सबसे पहले, नीति की डिफ़ॉल्ट स्थिति और किसी भी इमेज को डिप्लॉय करने की आपकी क्षमता की पुष्टि करें

  1. मौजूदा नीति की समीक्षा करना
gcloud container binauthz policy export
  1. ध्यान दें कि नीति उल्लंघन ठीक करने का तरीका (एनफ़ोर्समेंट) ALWAYS_ALLOW पर सेट है

evaluationMode: ALWAYS_ALLOW

  1. सैंपल डिप्लॉय करके पुष्टि करना कि आपके पास किसी भी चीज़ को डिप्लॉय करने का विकल्प है
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. पुष्टि करना कि डिप्लॉयमेंट काम कर रहा है
kubectl get pods

आपको यह आउटपुट दिखेगा

161db370d99ffb13.png

  1. डिप्लॉयमेंट मिटाएं
kubectl delete pod hello-server

सभी को अनुमति न दें

अब नीति को अपडेट करके, सभी इमेज दिखाने की अनुमति बंद करें.

  1. मौजूदा नीति को बदलाव की सुविधा वाली फ़ाइल में एक्सपोर्ट करना
gcloud container binauthz policy export  > policy.yaml
  1. नीति बदलें

टेक्स्ट एडिटर में, evaluationMode को ALWAYS_ALLOW से बदलकर ALWAYS_DENY करें.

edit policy.yaml

नीति की YAML फ़ाइल इस तरह दिखनी चाहिए:

globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: ALWAYS_DENY
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy
  1. Terminal खोलें और नई नीति लागू करें. इसके बाद, बदलाव लागू होने के लिए कुछ सेकंड इंतज़ार करें
gcloud container binauthz policy import policy.yaml
  1. सैंपल वर्कलोड को डिप्लॉय करने की कोशिश करना
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. डिप्लॉयमेंट इस मैसेज के साथ पूरा नहीं हो पाता
Error from server (VIOLATES_POLICY): admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image gcr.io/google-samples/hello-app:1.0 denied by Binary Authorization default admission rule. Denied by always_deny admission rule

सभी को अनुमति देने के लिए नीति को पहले जैसा करें

अगले सेक्शन पर जाने से पहले, नीति में किए गए बदलावों को पहले जैसा कर लें

  1. नीति बदलें

टेक्स्ट एडिटर में, evaluationMode को ALWAYS_DENY से बदलकर ALWAYS_ALLOW करें.

edit policy.yaml

नीति की YAML फ़ाइल इस तरह दिखनी चाहिए:

globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: ALWAYS_ALLOW
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy
  1. पहले जैसी नीति लागू करना
gcloud container binauthz policy import policy.yaml

9. GKE में जोखिम की आशंकाओं को ब्लॉक करना

इस सेक्शन में, आपको अब तक जो कुछ भी सीखा है उसे Cloud Build के साथ सीआई/सीडी पाइपलाइन लागू करके जोड़ा जाएगा. यह पाइपलाइन, इमेज को स्कैन करती है. इसके बाद, इमेज पर हस्ताक्षर करने और उसे डिप्लॉय करने से पहले, उसमें मौजूद जोखिमों की जांच करती है. GKE, इमेज को चलाने की अनुमति देने से पहले, बाइनरी अनुमति का इस्तेमाल करके पुष्टि करेगा कि इमेज में, जोखिम की जांच से मिला हस्ताक्षर है या नहीं.

d5c41bb89e22fd61.png

पुष्टि की ज़रूरत के लिए GKE की नीति अपडेट करना

GKE BinAuth नीति में clusterAdmissionRules जोड़कर, यह ज़रूरी करें कि इमेज पर आपके Attester ने हस्ताक्षर किया हो

नीचे दिए गए निर्देश का इस्तेमाल करके, नीति को अपडेट किए गए कॉन्फ़िगरेशन से बदलें.

COMPUTE_ZONE=us-central1-a

cat > binauth_policy.yaml << EOM
defaultAdmissionRule:
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
  evaluationMode: ALWAYS_DENY
globalPolicyEvaluationMode: ENABLE
clusterAdmissionRules:
  ${COMPUTE_ZONE}.binauthz:
    evaluationMode: REQUIRE_ATTESTATION
    enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
    requireAttestationsBy:
    - projects/${PROJECT_ID}/attestors/vulnz-attestor
EOM

नीति लागू करना

gcloud beta container binauthz policy import binauth_policy.yaml

बिना हस्ताक्षर वाली इमेज को डिप्लॉय करने की कोशिश करना

नीचे दिए गए निर्देश का इस्तेमाल करके, पहले बनाए गए ऐप्लिकेशन के लिए डिप्लॉयमेंट डिस्क्रिप्टर बनाएं. यहां इस्तेमाल की गई इमेज, वह इमेज है जिसे आपने पहले बनाया था. इसमें गंभीर कमजोरियां हैं और हस्ताक्षर वाला एटेस्टेशन नहीं है.

GKE के ऐडमिशन कंट्रोलर को यह पता होना चाहिए कि डिप्लॉय की जाने वाली इमेज कौनसी है, ताकि हस्ताक्षर की पुष्टि लगातार की जा सके. ऐसा करने के लिए, आपको किसी सामान्य टैग के बजाय इमेज डाइजेस्ट का इस्तेमाल करना होगा.

खराब इमेज के लिए इमेज डाइजेस्ट पाना

CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image


DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:bad \
    --format='get(image_summary.digest)')

Kubernetes कॉन्फ़िगरेशन में डाइजेस्ट का इस्तेमाल करना

cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
  name: deb-httpd
spec:
  selector:
    app: deb-httpd
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deb-httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deb-httpd
  template:
    metadata:
      labels:
        app: deb-httpd
    spec:
      containers:
      - name: deb-httpd
        image: ${CONTAINER_PATH}@${DIGEST}
        ports:
        - containerPort: 8080
        env:
          - name: PORT
            value: "8080"

EOM

ऐप्लिकेशन को GKE पर डिप्लॉय करने की कोशिश करना

kubectl apply -f deploy.yaml

कंसोल में मौजूद वर्कलोड की समीक्षा करें और डिप्लॉयमेंट अस्वीकार होने की गड़बड़ी पर ध्यान दें:

No attestations found that were valid and signed by a key trusted by the attestor

हस्ताक्षर की गई इमेज को डिप्लॉय करना

खराब इमेज के लिए इमेज डाइजेस्ट पाना

CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image


DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:good \
    --format='get(image_summary.digest)')

Kubernetes कॉन्फ़िगरेशन में डाइजेस्ट का इस्तेमाल करना

cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
  name: deb-httpd
spec:
  selector:
    app: deb-httpd
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deb-httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deb-httpd
  template:
    metadata:
      labels:
        app: deb-httpd
    spec:
      containers:
      - name: deb-httpd
        image: ${CONTAINER_PATH}@${DIGEST}
        ports:
        - containerPort: 8080
        env:
          - name: PORT
            value: "8080"

EOM

ऐप्लिकेशन को GKE पर डिप्लॉय करना

kubectl apply -f deploy.yaml

कंसोल में मौजूद वर्कलोड की समीक्षा करें और इमेज के डिप्लॉय होने की जानकारी देखें.

10. बधाई हो!

बधाई हो, आपने कोडलैब पूरा कर लिया है!

हमने इन विषयों पर जानकारी दी है:

  • अपने-आप स्कैन होने की सुविधा चालू करने का तरीका
  • मांग पर स्कैन करने की सुविधा को इस्तेमाल करने का तरीका
  • स्कैनिंग को बिल्ड पाइपलाइन में इंटिग्रेट करने का तरीका
  • अनुमति वाली इमेज पर हस्ताक्षर करने का तरीका
  • इमेज ब्लॉक करने के लिए, GKE ऐडमिशन कंट्रोलर का इस्तेमाल करने का तरीका
  • सिर्फ़ हस्ताक्षर की गई और मंज़ूरी वाली इमेज इस्तेमाल करने के लिए, GKE को कॉन्फ़िगर करने का तरीका

आगे क्या करना है:

व्यवस्थित करें

इस ट्यूटोरियल में इस्तेमाल किए गए संसाधनों के लिए, आपके Google Cloud खाते से शुल्क न लिया जाए, इसके लिए संसाधनों वाले प्रोजेक्ट को मिटाएं या प्रोजेक्ट को बनाए रखें और अलग-अलग संसाधनों को मिटाएं.

प्रोजेक्ट मिटाना

बिलिंग की सुविधा बंद करने का सबसे आसान तरीका, ट्यूटोरियल के लिए बनाया गया प्रोजेक्ट मिटाना है.