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

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 ก่อนตัดสินใจว่าจะจัดเก็บไว้ในรีจิสทรีหรือไม่

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

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

  • สร้างอิมเมจด้วย 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 Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ซึ่งโดยปกติแล้วคุณไม่จำเป็นต้องสนใจว่าสตริงนั้นคืออะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยปกติจะระบุเป็น 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 จะต้องมีสิทธิ์เข้าถึง 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 จะทริกเกอร์โดยอัตโนมัติทุกครั้งที่คุณพุชอิมเมจใหม่ไปยัง Artifact Registry หรือ Container Registry เราจะอัปเดตข้อมูลช่องโหว่อย่างต่อเนื่องเมื่อพบช่องโหว่ใหม่ ในส่วนนี้ คุณจะตรวจสอบอิมเมจที่เพิ่งสร้างและพุชไปยัง Artifact Registry รวมถึงดูผลการค้นหาช่องโหว่

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

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

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

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

361be7b3bf293fca.png

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

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 จะต้องมีสิทธิ์เข้าถึง 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

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

ตรวจสอบรูปภาพที่ดีใน Artifact Registry

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

8. ยินดีด้วย

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

สิ่งที่เราได้พูดถึงไปแล้ว

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

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

ล้างข้อมูล

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

การลบโปรเจ็กต์

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

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