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

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

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

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

  1. เปิด Artifact Registry ใน Cloud Console
  2. คลิกที่เก็บการสแกนอาร์ติแฟกต์เพื่อดูเนื้อหา
  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 ให้ใช้อิมเมจฐานที่ไม่มีช่องโหว่ CRITICAL

เขียนทับ 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/03/23