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

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