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

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

เกี่ยวกับ 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 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