การรักษาความปลอดภัยให้บิลด์คอนเทนเนอร์

การรักษาความปลอดภัยให้บิลด์คอนเทนเนอร์

เกี่ยวกับ Codelab นี้

subjectอัปเดตล่าสุดเมื่อ มี.ค. 23, 2023
account_circleเขียนโดย Christopher Grant

1 บทนำ

ead1609267034bf7.png

ช่องโหว่ของซอฟต์แวร์คือจุดอ่อนที่อาจทำให้ระบบทำงานล้มเหลวโดยไม่ตั้งใจ หรือทำให้ซอฟต์แวร์ของคุณถูกบุกรุก Container Analysis มีการสแกนระบบปฏิบัติการ 2 ประเภทเพื่อค้นหาช่องโหว่ในคอนเทนเนอร์ ได้แก่

  • On-Demand Scanning API ช่วยให้คุณสแกนอิมเมจคอนเทนเนอร์เพื่อหาช่องโหว่ของระบบปฏิบัติการด้วยตนเองได้ ทั้งจากในเครื่องคอมพิวเตอร์หรือจากระยะไกลใน Container Registry หรือ Artifact Registry
  • Container Scanning API ช่วยให้คุณสามารถตรวจหาช่องโหว่ของระบบปฏิบัติการโดยอัตโนมัติ โดยจะสแกนทุกครั้งที่คุณพุชอิมเมจไปยัง Container Registry หรือ Artifact Registry การเปิดใช้ API นี้จะเปิดใช้การสแกนแพ็กเกจภาษาเพื่อหาช่องโหว่ของ Go และ Java ด้วย

On-Demand Scanning API ช่วยให้คุณสแกนอิมเมจที่จัดเก็บไว้ในเครื่องคอมพิวเตอร์ของคุณ หรือจากระยะไกลใน Container Registry หรือ Artifact Registry ซึ่งจะช่วยให้คุณควบคุมคอนเทนเนอร์ที่ต้องการสแกนหาช่องโหว่ได้อย่างละเอียด คุณสามารถใช้การสแกนแบบออนดีมานด์เพื่อสแกนรูปภาพในไปป์ไลน์ CI/CD ก่อนตัดสินใจว่าจะจัดเก็บไว้ในรีจิสทรีหรือไม่

สิ่งที่คุณจะได้เรียนรู้

ในห้องทดลองนี้ คุณจะทำสิ่งต่อไปนี้ได้

  • สร้างรูปภาพด้วย Cloud Build
  • ใช้ Artifact Registry สำหรับคอนเทนเนอร์
  • ใช้การสแกนช่องโหว่อัตโนมัติ
  • กำหนดค่าการสแกนตามคำขอ
  • เพิ่มการสแกนอิมเมจใน CICD ใน Cloud Build

2 การตั้งค่าและข้อกำหนด

การตั้งค่าสภาพแวดล้อมด้วยตนเอง

  1. ลงชื่อเข้าใช้ Google Cloud Console และสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • ชื่อโปรเจ็กต์คือชื่อที่แสดงสำหรับผู้เข้าร่วมโปรเจ็กต์นี้ ซึ่งเป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ โดยคุณจะอัปเดตได้ทุกเมื่อ
  • รหัสโปรเจ็กต์จะซ้ำกันไม่ได้ในโปรเจ็กต์ Google Cloud ทั้งหมดและจะเปลี่ยนแปลงไม่ได้ (เปลี่ยนแปลงไม่ได้หลังจากตั้งค่าแล้ว) คอนโซล Cloud จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ซึ่งปกติแล้วคุณไม่จำเป็นต้องสนใจว่าสตริงนั้นจะเป็นอะไร ในโค้ดแล็บส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยปกติจะระบุเป็น PROJECT_ID) หากไม่ชอบรหัสที่สร้างขึ้น คุณก็สร้างรหัสอื่นแบบสุ่มได้ หรือคุณจะลองดำเนินการเองแล้วดูว่าพร้อมให้บริการหรือไม่ และไม่สามารถเปลี่ยนแปลงได้หลังจากขั้นตอนนี้และจะยังคงอยู่ตลอดระยะเวลาของโปรเจ็กต์
  • โปรดทราบว่ามีค่าที่ 3 ซึ่งเป็นหมายเลขโปรเจ็กต์ที่ API บางรายการใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 ค่าได้ในเอกสารประกอบ
  1. ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของ Cloud การใช้งาน Codelab นี้น่าจะไม่มีค่าใช้จ่ายใดๆ หากมี หากต้องการปิดทรัพยากรเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ คุณสามารถลบทรัพยากรที่คุณสร้างหรือลบทั้งโปรเจ็กต์ได้ ผู้ใช้ใหม่ของ Google Cloud จะมีสิทธิ์เข้าร่วมโปรแกรมทดลองใช้ฟรี$300 USD

การตั้งค่าสภาพแวดล้อม

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

3 การสร้างอิมเมจด้วย Cloud Build

ในส่วนนี้ คุณจะต้องสร้างไปป์ไลน์การสร้างอัตโนมัติที่จะสร้างอิมเมจคอนเทนเนอร์ สแกน แล้วประเมินผลลัพธ์ หากไม่พบช่องโหว่ร้ายแรง ระบบจะพุชอิมเมจไปยังที่เก็บ หากพบช่องโหว่ที่สำคัญ บิลด์จะล้มเหลวและออก

ให้สิทธิ์เข้าถึงบัญชีบริการ Cloud Build

Cloud Build จะต้องมีสิทธิ์เข้าถึง On-Demand Scanning API ให้สิทธิ์เข้าถึงด้วยคําสั่งต่อไปนี้

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"

สร้างและเปลี่ยนเป็นไดเรกทอรีงาน

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

คำสั่งต่อไปนี้จะสร้างไฟล์ 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
: ['-']


EOF

เรียกใช้ไปป์ไลน์ CI

ส่งบิลด์ให้ระบบประมวลผล

gcloud builds submit

ตรวจสอบรายละเอียดบิลด์

เมื่อกระบวนการบิลด์ได้เริ่มตรวจสอบความคืบหน้าในแดชบอร์ด Cloud Build แล้ว

  1. เปิด Cloud Build ใน Cloud Console
  2. คลิกที่บิลด์เพื่อดูเนื้อหา

4 Artifact Registry สำหรับคอนเทนเนอร์

สร้างที่เก็บ Artifact Registry

ในห้องทดลองนี้ คุณจะใช้ Artifact Registry เพื่อจัดเก็บและสแกนรูปภาพ สร้างที่เก็บด้วยคำสั่งต่อไปนี้

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

กำหนดค่า Docker ให้ใช้ข้อมูลเข้าสู่ระบบ gcloud เมื่อเข้าถึง Artifact Registry

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

อัปเดตไปป์ไลน์ Cloud Build

แก้ไขไปป์ไลน์บิลด์เพื่อพุชอิมเมจที่ได้ไปยัง Artifact Registry

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
: ['-']

# push 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']

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

เรียกใช้ไปป์ไลน์ CI

ส่งบิลด์เพื่อประมวลผล

gcloud builds submit

5 การสแกนช่องโหว่อัตโนมัติ

การสแกนอาร์ติแฟกต์จะทริกเกอร์โดยอัตโนมัติทุกครั้งที่คุณพุชอิมเมจใหม่ไปยัง Artifact Registry หรือ Container Registry ข้อมูลช่องโหว่จะอัปเดตอย่างต่อเนื่องเมื่อมีการตรวจพบช่องโหว่ใหม่ๆ ในส่วนนี้ คุณจะได้ตรวจสอบอิมเมจที่คุณเพิ่งสร้างขึ้นและพุชไปยัง Artifact Registry และสำรวจผลลัพธ์ของช่องโหว่

ตรวจสอบรายละเอียดรูปภาพ

เมื่อกระบวนการสร้างก่อนหน้านี้เสร็จสมบูรณ์แล้ว ให้ตรวจสอบผลลัพธ์ของช่องโหว่และรูปภาพในหน้าแดชบอร์ด Artifact Registry

  1. เปิด Artifact Registry ใน Cloud Console
  2. คลิกที่ artifact-scanning-repo เพื่อดูเนื้อหา
  3. คลิกดูรายละเอียดของรูปภาพ
  4. คลิกข้อมูลสรุปล่าสุดของรูปภาพ
  5. เมื่อสแกนเสร็จแล้ว ให้คลิกแท็บช่องโหว่ของรูปภาพ

จากแท็บช่องโหว่ คุณจะเห็นผลการสแกนอัตโนมัติสำหรับรูปภาพที่คุณเพิ่งสร้าง

361be7b3bf293fca.png

ระบบจะเปิดใช้การสแกนอัตโนมัติโดยค่าเริ่มต้น สำรวจการตั้งค่ารีจิสทรีอาร์ติแฟกต์เพื่อดูวิธีปิด/เปิดการสแกนอัตโนมัติ

6 การสแกนตามคำขอ

คุณอาจต้องสแกนก่อนที่จะพุชอิมเมจไปยังที่เก็บในสถานการณ์ต่างๆ ตัวอย่างเช่น นักพัฒนาคอนเทนเนอร์อาจสแกนอิมเมจและแก้ปัญหาก่อนพุชโค้ดไปยังตัวควบคุมแหล่งที่มา ในตัวอย่างด้านล่าง คุณจะได้สร้างและวิเคราะห์รูปภาพในเครื่องก่อนที่จะดำเนินการกับผลลัพธ์

สร้างอิมเมจ

ในขั้นตอนนี้ คุณจะใช้ Docker ในเครื่องเพื่อสร้างอิมเมจไปยังแคชในเครื่อง

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

7 การสแกนใน CICD ด้วย Cloud Build

ให้สิทธิ์เข้าถึงสำหรับบัญชีบริการ Cloud Build

Cloud Build จะต้องมีสิทธิ์เข้าถึง On-Demand Scanning API ให้สิทธิ์เข้าถึงด้วยคำสั่งต่อไปนี้

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

เรียกใช้ไปป์ไลน์ CI

ส่งบิลด์เข้ารับการประมวลผลเพื่อยืนยันว่าบิลด์ใช้งานไม่ได้เมื่อพบช่องโหว่ที่มีความรุนแรงร้ายแรง

gcloud builds submit

การตรวจสอบการสร้างล้มเหลว

บิลด์ที่คุณเพิ่งส่งจะล้มเหลวเนื่องจากอิมเมจมีช่องโหว่ร้ายแรง

ตรวจสอบการบิลด์ที่ไม่สําเร็จในหน้าประวัติ Cloud Build

แก้ไขช่องโหว่

อัปเดต Dockerfile เพื่อใช้อิมเมจฐานที่ไม่มีช่องโหว่ร้ายแรง

เขียนทับ Dockerfile เพื่อใช้อิมเมจ Debian 10 ด้วยคำสั่งต่อไปนี้

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

เรียกใช้กระบวนการ CI ด้วยรูปภาพที่ถูกต้อง

ส่งบิลด์เพื่อประมวลผลเพื่อยืนยันว่าบิลด์จะดำเนินการสำเร็จเมื่อไม่พบช่องโหว่ที่มีความรุนแรงร้ายแรง

gcloud builds submit

ตรวจสอบความสำเร็จของบิลด์

บิลด์ที่คุณเพิ่งส่งจะสำเร็จเนื่องจากอิมเมจที่อัปเดตไม่มีช่องโหว่ที่ร้ายแรง

ตรวจสอบความสำเร็จของบิลด์ในหน้าประวัติ Cloud Build

ตรวจสอบผลการสแกน

ตรวจสอบรูปภาพที่ดีในรีจิสทรีอาร์ติแฟกต์

  1. เปิด Artifact Registry ใน Cloud Console
  2. คลิกที่เก็บการสแกนอาร์ติแฟกต์เพื่อดูเนื้อหา
  3. คลิกดูรายละเอียดของรูปภาพ
  4. คลิกข้อมูลสรุปล่าสุดของรูปภาพ
  5. คลิกแท็บช่องโหว่ของรูปภาพ

8 ยินดีด้วย

ยินดีด้วย คุณทำ Codelab เสร็จแล้ว

สิ่งที่เราได้พูดคุยกันมีดังนี้

  • การสร้างรูปภาพด้วย Cloud Build
  • Artifact Registry สำหรับคอนเทนเนอร์
  • การสแกนช่องโหว่อัตโนมัติ
  • การสแกนตามคำขอ
  • การสแกนใน CICD ด้วย Cloud Build

ขั้นตอนต่อไปที่ทำได้

ล้างข้อมูล

โปรดลบโปรเจ็กต์ที่มีทรัพยากรดังกล่าวหรือเก็บโปรเจ็กต์ไว้และลบทรัพยากรแต่ละรายการเพื่อเลี่ยงไม่ให้เกิดการเรียกเก็บเงินกับบัญชี Google Cloud สำหรับทรัพยากรที่ใช้ในบทแนะนำนี้

กำลังลบโปรเจ็กต์

วิธีที่ง่ายที่สุดในการยกเลิกการเรียกเก็บเงินคือการลบโปรเจ็กต์ที่คุณสร้างไว้สำหรับบทแนะนำ

อัปเดตล่าสุด: 21/3/23