1. บทนำ
การให้สิทธิ์แบบไบนารีคือการควบคุมความปลอดภัยเวลาทำให้ใช้งานได้ซึ่งดูแลให้มีเพียงการทำให้อิมเมจคอนเทนเนอร์ที่เชื่อถือได้ใช้งานได้บน Google Kubernetes Engine (GKE) หรือ Cloud Run เท่านั้น เมื่อใช้การให้สิทธิ์แบบไบนารี คุณจะกำหนดให้รูปภาพต้องลงชื่อจากหน่วยงานที่เชื่อถือได้ในกระบวนการพัฒนา จากนั้นบังคับใช้การตรวจสอบลายเซ็นเมื่อทำให้ใช้งานได้ การบังคับใช้การตรวจสอบจะช่วยให้ควบคุมสภาพแวดล้อมของคอนเทนเนอร์ได้อย่างเข้มงวดยิ่งขึ้นด้วยการตรวจสอบให้แน่ใจว่าได้รวมเฉพาะอิมเมจที่ยืนยันแล้วในกระบวนการสร้างและเปิดตัว
แผนภาพต่อไปนี้แสดงคอมโพเนนต์ในการตั้งค่าการให้สิทธิ์แบบไบนารี/Cloud Build
**รูปที่ 1.**ไปป์ไลน์ของ Cloud Build ที่สร้างเอกสารรับรองการให้สิทธิ์แบบไบนารี
ในไปป์ไลน์นี้
- โค้ดสำหรับสร้างอิมเมจคอนเทนเนอร์จะพุชไปยังที่เก็บต้นทาง เช่น Cloud Source Repositories
- Cloud Build สร้างและทดสอบคอนเทนเนอร์โดยใช้เครื่องมือการผสานรวมอย่างต่อเนื่อง (CI)
- บิลด์จะพุชอิมเมจคอนเทนเนอร์ไปยัง Container Registry หรือรีจิสทรีอื่นที่จัดเก็บอิมเมจที่คุณสร้าง
- Cloud Key Management Service ซึ่งให้บริการการจัดการคีย์สำหรับคู่คีย์การเข้ารหัสจะลงนามอิมเมจคอนเทนเนอร์ จากนั้นระบบจะจัดเก็บลายเซ็นที่ได้ไว้ในเอกสารรับรองที่สร้างขึ้นใหม่
- เมื่อถึงเวลาใช้งาน ผู้รับรองจะยืนยันเอกสารรับรองโดยใช้คีย์สาธารณะจากคู่คีย์ การให้สิทธิ์แบบไบนารีบังคับใช้นโยบายโดยกำหนดให้มีเอกสารรับรองที่ลงชื่อเพื่อให้อิมเมจคอนเทนเนอร์ใช้งานได้
ในห้องทดลองนี้ คุณจะมุ่งเน้นที่เครื่องมือและเทคนิคในการรักษาความปลอดภัยให้กับอาร์ติแฟกต์ที่ติดตั้งใช้งาน ห้องทดลองนี้จะเน้นที่อาร์ติแฟกต์ (คอนเทนเนอร์) หลังจากที่สร้างขึ้นแต่ไม่ได้ติดตั้งใช้งานในสภาพแวดล้อมบางอย่าง
สิ่งที่คุณจะได้เรียนรู้
- การเซ็นชื่อบนรูปภาพ
- นโยบายควบคุมการเข้าชม
- การรับรองรูปภาพที่สแกน
- กำลังให้สิทธิ์รูปภาพที่ลงนาม
- บล็อกรูปภาพที่ไม่ได้ลงนาม
2. การตั้งค่าและข้อกำหนด
การตั้งค่าสภาพแวดล้อมตามเวลาที่สะดวก
- ลงชื่อเข้าใช้ Google Cloud Console และสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี
- ชื่อโครงการคือชื่อที่แสดงของผู้เข้าร่วมโปรเจ็กต์นี้ เป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ โดยคุณจะอัปเดตได้ทุกเมื่อ
- รหัสโปรเจ็กต์จะไม่ซ้ำกันในทุกโปรเจ็กต์ของ Google Cloud และจะเปลี่ยนแปลงไม่ได้ (เปลี่ยนแปลงไม่ได้หลังจากตั้งค่าแล้ว) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ปกติแล้วคุณไม่สนว่าอะไรเป็นอะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยปกติจะระบุเป็น
PROJECT_ID
) หากคุณไม่ชอบรหัสที่สร้างขึ้น คุณสามารถสร้างรหัสแบบสุ่มอื่นได้ หรือคุณจะลองดำเนินการเองแล้วดูว่าพร้อมให้บริการหรือไม่ และไม่สามารถเปลี่ยนแปลงได้หลังจากขั้นตอนนี้และจะยังคงอยู่ตลอดระยะเวลาของโปรเจ็กต์ - สำหรับข้อมูลของคุณ ค่าที่ 3 คือหมายเลขโปรเจ็กต์ที่ API บางตัวใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 ค่าได้ในเอกสารประกอบ
- ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน 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
สร้างที่เก็บ 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
สร้างและเปลี่ยนเป็นไดเรกทอรีงาน
mkdir vuln-scan && cd vuln-scan
กำหนดรูปภาพตัวอย่าง
สร้างไฟล์ชื่อ Dockerfile โดยใช้เนื้อหาต่อไปนี้
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
สร้างไฟล์ชื่อ 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
สร้างและพุชรูปภาพไปยัง AR
ใช้ Cloud Build เพื่อสร้างและพุชคอนเทนเนอร์ไปยัง Artifact Registry โดยอัตโนมัติ
gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
3. การเซ็นชื่อบนรูปภาพ
ผู้รับรองคืออะไร
ผู้รับรอง
- บุคคล/กระบวนการนี้เป็นผู้รับผิดชอบลิงก์หนึ่งในห่วงโซ่ความน่าเชื่อถือของระบบ
- ซึ่งถือคีย์การเข้ารหัสและลงนามรูปภาพหากผ่านกระบวนการอนุมัติ
- แม้ว่าผู้สร้างนโยบายจะกำหนดนโยบายในระดับสูงแบบนามธรรม แต่ผู้รับรองจะรับผิดชอบในการบังคับใช้นโยบายบางประการที่เป็นรูปธรรม
- อาจเป็นบุคคลที่มีตัวตนจริง เช่น ผู้ทดสอบ QA หรือผู้จัดการ หรืออาจเป็นบ็อตในระบบ CI
- ความปลอดภัยของระบบขึ้นอยู่กับความน่าเชื่อถือของคนอื่น ดังนั้นคีย์ส่วนตัวของคีย์ดังกล่าวจึงต้องได้รับการเก็บรักษาไว้อย่างปลอดภัย
แต่ละบทบาทสามารถเป็นตัวแทนของบุคคลหรือทีมบุคคลในองค์กร ในสภาพแวดล้อมการใช้งานจริง บทบาทเหล่านี้มีแนวโน้มที่จะได้รับการจัดการโดยโปรเจ็กต์ Google Cloud Platform (GCP) แยกต่างหาก และจะมีการแชร์การเข้าถึงทรัพยากรระหว่างบทบาทเหล่านี้ในแบบที่จำกัดโดยใช้ Cloud IAM
ระบบจะใช้งานผู้รับรองในการให้สิทธิ์แบบไบนารีบน Cloud Container Analysis API ดังนั้นคุณควรอธิบายถึงวิธีการทำงานดังกล่าวก่อนที่จะดำเนินการต่อไป Container Analysis API ได้รับการออกแบบมาเพื่อช่วยให้คุณเชื่อมโยงข้อมูลเมตากับอิมเมจคอนเทนเนอร์ที่ระบุ
ตัวอย่างเช่น ระบบอาจสร้างหมายเหตุเพื่อติดตามช่องโหว่ Heartbleed จากนั้นผู้ให้บริการด้านความปลอดภัยจะสร้างเครื่องสแกนเพื่อทดสอบหาช่องโหว่ของอิมเมจคอนเทนเนอร์ แล้วสร้างรายการที่เกี่ยวข้องกับคอนเทนเนอร์ที่ถูกบุกรุกแต่ละรายการ
นอกจากการติดตามช่องโหว่แล้ว Container Analysis ยังออกแบบมาให้เป็น API ข้อมูลเมตาทั่วไป การให้สิทธิ์แบบไบนารีใช้การวิเคราะห์คอนเทนเนอร์เพื่อเชื่อมโยงลายเซ็นกับอิมเมจคอนเทนเนอร์ที่กำลังยืนยัน**** บันทึก Container Analysis จะใช้เพื่อแสดงถึงผู้รับรองรายเดียว จากนั้นจะมีการสร้างรายการและเชื่อมโยงกับแต่ละคอนเทนเนอร์ที่ผู้รับรองอนุมัติ
API การให้สิทธิ์แบบไบนารีใช้แนวคิดของ "ผู้รับรอง" และ "เอกสารรับรอง" แต่จะใช้งานโดยใช้บันทึกและรายการที่เกี่ยวข้องใน Container Analysis API
สร้างบันทึกของผู้รับรอง
หมายเหตุของผู้รับรองเป็นข้อมูลส่วนเล็กๆ ที่ทำหน้าที่เป็นป้ายกำกับสำหรับประเภทลายเซ็นที่ใช้ เช่น โน้ตรายการหนึ่งอาจระบุถึงการสแกนช่องโหว่ ในขณะที่อีกรายการหนึ่งอาจใช้สำหรับการลงชื่อ QA โดยจะมีการอ้างอิงหมายเหตุในระหว่างกระบวนการลงนาม
สร้างโน้ต
cat > ./vulnz_note.json << EOM
{
"attestation": {
"hint": {
"human_readable_name": "Container Vulnerabilities attestation authority"
}
}
}
EOM
เก็บโน้ต
NOTE_ID=vulnz_note
curl -vvv -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @./vulnz_note.json \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
ยืนยันหมายเหตุ
curl -vvv \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
ตอนนี้ระบบได้บันทึกหมายเหตุไว้ใน Container Analysis API แล้ว
กำลังสร้างผู้รับรอง
ระบบจะใช้ผู้รับรองเพื่อดำเนินการลงนามในรูปภาพจริง และจะแนบรายการหมายเหตุไปกับรูปภาพสำหรับการยืนยันในภายหลัง หากต้องการใช้ผู้รับรอง คุณต้องลงทะเบียนหมายเหตุกับการให้สิทธิ์แบบไบนารีด้วย ดังนี้
สร้างผู้รับรอง
ATTESTOR_ID=vulnz-attestor
gcloud container binauthz attestors create $ATTESTOR_ID \
--attestation-authority-note=$NOTE_ID \
--attestation-authority-note-project=${PROJECT_ID}
ยืนยันผู้รับรอง
gcloud container binauthz attestors list
โปรดทราบว่าบรรทัดสุดท้ายจะระบุว่า NUM_PUBLIC_KEYS: 0
คุณจะระบุคีย์ในขั้นตอนถัดไป
โปรดทราบว่า Cloud Build จะสร้างผู้รับรอง built-by-cloud-build
ในโปรเจ็กต์ของคุณโดยอัตโนมัติเมื่อคุณเรียกใช้บิลด์ที่สร้างอิมเมจ ดังนั้นคำสั่งด้านบนจะแสดงผลผู้รับรอง 2 รายการ คือ vulnz-attestor
และ built-by-cloud-build
หลังจากสร้างอิมเมจเรียบร้อยแล้ว Cloud Build จะลงนามและสร้างเอกสารรับรองให้กับอิมเมจโดยอัตโนมัติ
กำลังเพิ่มบทบาท IAM
บัญชีบริการการให้สิทธิ์แบบไบนารีจะต้องมีสิทธิ์ดูหมายเหตุในเอกสารรับรอง ให้สิทธิ์เข้าถึงด้วยการเรียก API ต่อไปนี้
PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")
BINAUTHZ_SA_EMAIL="service-${PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
cat > ./iam_request.json << EOM
{
'resource': 'projects/${PROJECT_ID}/notes/${NOTE_ID}',
'policy': {
'bindings': [
{
'role': 'roles/containeranalysis.notes.occurrences.viewer',
'members': [
'serviceAccount:${BINAUTHZ_SA_EMAIL}'
]
}
]
}
}
EOM
ใช้ไฟล์ดังกล่าวเพื่อสร้างนโยบาย IAM
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @./iam_request.json \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"
การเพิ่มคีย์ KMS
ก่อนที่คุณจะใช้ผู้รับรองนี้ได้ สิทธิ์ของคุณจำเป็นต้องสร้างคู่คีย์การเข้ารหัสที่สามารถใช้เพื่อลงนามอิมเมจคอนเทนเนอร์ ซึ่งดำเนินการผ่าน Google Cloud Key Management Service (KMS)
ก่อนอื่นให้เพิ่มตัวแปรสภาพแวดล้อมเพื่ออธิบายคีย์ใหม่
KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1
สร้างคีย์ริงเพื่อเก็บชุดคีย์
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
สร้างคู่คีย์การลงนามแบบอสมมาตรใหม่สำหรับผู้รับรอง
gcloud kms keys create "${KEY_NAME}" \
--keyring="${KEYRING}" --location="${KEY_LOCATION}" \
--purpose asymmetric-signing \
--default-algorithm="ec-sign-p256-sha256"
คุณควรเห็นคีย์ปรากฏบนหน้า KMS ของ Google Cloud Console
จากนั้นเชื่อมโยงคีย์กับผู้รับรองผ่านคำสั่ง gcloud binauthz ดังนี้
gcloud beta container binauthz attestors public-keys add \
--attestor="${ATTESTOR_ID}" \
--keyversion-project="${PROJECT_ID}" \
--keyversion-location="${KEY_LOCATION}" \
--keyversion-keyring="${KEYRING}" \
--keyversion-key="${KEY_NAME}" \
--keyversion="${KEY_VERSION}"
หากคุณพิมพ์รายชื่อหน่วยงานอีกครั้ง คุณจะเห็นคีย์ที่ลงทะเบียนแล้ว
gcloud container binauthz attestors list
การสร้างเอกสารรับรองที่ลงชื่อ
ในจุดนี้ คุณได้กำหนดค่าคุณลักษณะที่ทำให้คุณสามารถใส่เครื่องหมายในรูปภาพได้ ใช้ผู้รับรองที่สร้างไว้ก่อนหน้านี้เพื่อลงนามอิมเมจคอนเทนเนอร์ที่ใช้งานอยู่
เอกสารรับรองต้องมีลายเซ็นแบบเข้ารหัสเพื่อระบุว่าผู้รับรองได้ยืนยันอิมเมจคอนเทนเนอร์หนึ่งๆ และทำงานบนคลัสเตอร์ได้อย่างปลอดภัย หากต้องการระบุอิมเมจคอนเทนเนอร์ที่จะรับรอง คุณต้องระบุไดเจสต์ของคอนเทนเนอร์
CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:latest \
--format='get(image_summary.digest)')
ตอนนี้คุณใช้ gcloud เพื่อสร้างเอกสารรับรองได้แล้ว คำสั่งจะใส่รายละเอียดของคีย์ที่คุณต้องการใช้สำหรับลงชื่อ และอิมเมจคอนเทนเนอร์เฉพาะที่คุณต้องการอนุมัติ
gcloud beta container binauthz attestations sign-and-create \
--artifact-url="${CONTAINER_PATH}@${DIGEST}" \
--attestor="${ATTESTOR_ID}" \
--attestor-project="${PROJECT_ID}" \
--keyversion-project="${PROJECT_ID}" \
--keyversion-location="${KEY_LOCATION}" \
--keyversion-keyring="${KEYRING}" \
--keyversion-key="${KEY_NAME}" \
--keyversion="${KEY_VERSION}"
ในข้อกำหนดของ Container Analysis การดำเนินการนี้จะสร้างรายการใหม่ และแนบกับบันทึกของผู้รับรอง คุณระบุเอกสารรับรองได้เพื่อให้แน่ใจว่าทุกอย่างทำงานตามที่คาดไว้
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
4. นโยบายควบคุมการเข้าชม
การให้สิทธิ์แบบไบนารีเป็นฟีเจอร์ใน GKE และ Cloud Run ที่มอบความสามารถในการตรวจสอบกฎก่อนที่จะอนุญาตให้อิมเมจคอนเทนเนอร์ทำงาน การตรวจสอบจะดำเนินการตามคำขอเพื่อเรียกใช้อิมเมจทั้งจากไปป์ไลน์ CI/CD ที่เชื่อถือได้ หรือเมื่อผู้ใช้พยายามทำให้อิมเมจใช้งานได้ด้วยตนเอง ซึ่งความสามารถนี้จะช่วยให้คุณรักษาความปลอดภัยของสภาพแวดล้อมรันไทม์ได้อย่างมีประสิทธิภาพมากกว่าการตรวจสอบไปป์ไลน์ CI/CD เพียงอย่างเดียว
หากต้องการทำความเข้าใจความสามารถนี้ คุณจะต้องแก้ไขนโยบาย GKE เริ่มต้นเพื่อบังคับใช้กฎการให้สิทธิ์ที่เข้มงวด
สร้างคลัสเตอร์ GKE
สร้างคลัสเตอร์ GKE ที่เปิดใช้การให้สิทธิ์แบบไบนารี
gcloud beta container clusters create binauthz \
--zone us-central1-a \
--binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
อนุญาตให้ Cloud Build ทำให้ใช้งานได้กับคลัสเตอร์นี้:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/container.developer"
อนุญาตนโยบายทั้งหมด
ก่อนอื่นให้ยืนยันสถานะนโยบายเริ่มต้นและความสามารถในการทำให้อิมเมจใดก็ได้ใช้งานได้
- อ่านนโยบายที่มีอยู่
gcloud container binauthz policy export
- โปรดทราบว่านโยบายการบังคับใช้ตั้งค่าเป็น
ALWAYS_ALLOW
evaluationMode: ALWAYS_ALLOW
- ทำให้ตัวอย่างใช้งานได้เพื่อยืนยันว่าคุณสามารถติดตั้งใช้งานได้ทุกอย่าง
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- ยืนยันว่าการทำให้ใช้งานได้ใช้งานได้
kubectl get pods
คุณจะเห็นเอาต์พุตต่อไปนี้
- ลบการทำให้ใช้งานได้
kubectl delete pod hello-server
ปฏิเสธนโยบายทั้งหมด
จากนั้นให้อัปเดตนโยบายเพื่อไม่อนุญาตรูปภาพทั้งหมด
- ส่งออกนโยบายปัจจุบันไปยังไฟล์ที่แก้ไขได้
gcloud container binauthz policy export > policy.yaml
- เปลี่ยนนโยบาย
ในเครื่องมือแก้ไขข้อความ ให้เปลี่ยนโหมดการประเมินจาก ALWAYS_ALLOW เป็น ALWAYS_DENY
edit policy.yaml
ไฟล์ YAML ของนโยบายควรปรากฏดังนี้
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_DENY enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
นโยบายนี้ค่อนข้างเรียบง่าย บรรทัด globalPolicyEvaluationMode ประกาศว่านโยบายนี้จะขยายนโยบายส่วนกลางที่ Google กําหนด การดำเนินการนี้จะอนุญาตให้คอนเทนเนอร์ GKE อย่างเป็นทางการทั้งหมดทำงานโดยค่าเริ่มต้น นอกจากนี้ นโยบายจะประกาศ defaultAdmissionRule ที่ระบุว่าพ็อดอื่นๆ ทั้งหมดจะถูกปฏิเสธ กฎการเข้าร่วมมีบรรทัด enforcementMode ที่ระบุว่าควรบล็อกพ็อดทั้งหมดที่ไม่สอดคล้องกับกฎนี้ไม่ให้ทำงานในคลัสเตอร์
สำหรับวิธีการสร้างนโยบายที่ซับซ้อนมากขึ้น โปรดดูเอกสารการให้สิทธิ์แบบไบนารี
- เปิดเทอร์มินัลแล้วใช้นโยบายใหม่และรอสักครู่เพื่อให้การเปลี่ยนแปลงมีผล
gcloud container binauthz policy import policy.yaml
- ลองทำให้ภาระงานตัวอย่างใช้งานได้
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- การทำให้ใช้งานได้ล้มเหลวโดยมีข้อความต่อไปนี้
Error from server (VIOLATES_POLICY): admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image gcr.io/google-samples/hello-app:1.0 denied by Binary Authorization default admission rule. Denied by always_deny admission rule
เปลี่ยนกลับนโยบายเพื่ออนุญาตทั้งหมด
ก่อนไปยังส่วนถัดไป โปรดตรวจสอบว่าได้เปลี่ยนกลับการเปลี่ยนแปลงนโยบายแล้ว
- เปลี่ยนนโยบาย
ในเครื่องมือแก้ไขข้อความ ให้เปลี่ยนโหมดการประเมินจาก ALWAYS_DENY เป็น ALWAYS_ALLOW
edit policy.yaml
ไฟล์ YAML ของนโยบายควรปรากฏดังนี้
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_ALLOW enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- ใช้นโยบายที่เปลี่ยนกลับ
gcloud container binauthz policy import policy.yaml
5. การรับรองรูปภาพที่สแกน
คุณได้เปิดใช้การรับรองรูปภาพและใช้ผู้รับรองเพื่อลงนามรูปภาพตัวอย่างด้วยตนเอง ในทางปฏิบัติ คุณควรใช้เอกสารรับรองในระหว่างกระบวนการอัตโนมัติ เช่น ไปป์ไลน์ CI/CD
ในส่วนนี้ คุณจะได้กำหนดค่า Cloud Build เพื่อยืนยันอิมเมจโดยอัตโนมัติ
บทบาท
เพิ่มบทบาทผู้ดูผู้รับรองการให้สิทธิ์แบบไบนารีในบัญชีบริการ Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
เพิ่มบทบาทผู้ลงนาม/ผู้รับรอง Cloud KMS CryptoKey ในบัญชีบริการ Cloud Build (การลงชื่อที่ใช้ KMS)
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
เพิ่มบทบาทผู้แนบบันทึก Container Analysis ไปยังบัญชีบริการ Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/containeranalysis.notes.attacher
ให้สิทธิ์เข้าถึงบัญชีบริการ 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 สำหรับบิลด์ที่กำหนดเอง
คุณจะใช้ขั้นตอนบิลด์ที่กำหนดเองใน Cloud Build เพื่อทำให้กระบวนการรับรองง่ายขึ้น Google มีขั้นตอนการสร้างที่กําหนดเองนี้ซึ่งมีฟังก์ชันตัวช่วยที่จะเพิ่มประสิทธิภาพให้กับกระบวนการ ก่อนใช้งาน คุณต้องสร้างโค้ดสำหรับขั้นตอนบิลด์ที่กำหนดเองในคอนเทนเนอร์และพุชไปยัง Cloud Build โดยเรียกใช้คำสั่งต่อไปนี้
git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
cd cloud-builders-community/binauthz-attestation
gcloud builds submit . --config cloudbuild.yaml
cd ../..
rm -rf cloud-builders-community
เพิ่มขั้นตอนการลงนามใน cloudbuild.yaml
ในขั้นตอนนี้ คุณจะเพิ่มขั้นตอนเอกสารรับรองลงในไปป์ไลน์ Cloud Build
- ตรวจสอบขั้นตอนการลงนามที่ด้านล่าง
รีวิวเท่านั้น ไม่คัดลอก
#Sign the image only if the previous severity check passes - id: 'create-attestation' name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest' args: - '--artifact-url' - 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image' - '--attestor' - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID' - '--keyversion' - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
- เขียนไฟล์ 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']
#Sign the image only if the previous severity check passes
- id: 'create-attestation'
name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
args:
- '--artifact-url'
- 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good'
- '--attestor'
- 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID'
- '--keyversion'
- 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
images:
- us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good
EOF
เรียกใช้บิลด์
gcloud builds submit
ตรวจสอบบิลด์ในประวัติ Cloud Build
เปิด Cloud Console ไปที่หน้าประวัติ Cloud Build แล้วตรวจสอบบิลด์ล่าสุดและการดำเนินการตามขั้นตอนของบิลด์ได้สำเร็จ
6. กำลังให้สิทธิ์รูปภาพที่ลงนาม
ในส่วนนี้ คุณจะอัปเดต GKE เพื่อใช้การให้สิทธิ์แบบไบนารีในการตรวจสอบความถูกต้องของอิมเมจมีลายเซ็นจากการสแกนช่องโหว่ก่อนที่จะอนุญาตให้อิมเมจทำงาน
อัปเดตนโยบาย GKE เพื่อต้องมีเอกสารรับรอง
ผู้รับรองต้องลงชื่ออิมเมจโดยการเพิ่มคลัสเตอร์AdmissionRules ต่างๆ ในนโยบาย GKE BinAuth
ขณะนี้คลัสเตอร์ของคุณกำลังใช้นโยบายที่มีกฎเดียวคือ อนุญาตคอนเทนเนอร์จากที่เก็บอย่างเป็นทางการ และปฏิเสธคอนเทนเนอร์อื่นๆ ทั้งหมด
เขียนทับนโยบายด้วยการกำหนดค่าที่อัปเดตแล้วโดยใช้คำสั่งด้านล่าง
COMPUTE_ZONE=us-central1-a
cat > binauth_policy.yaml << EOM
defaultAdmissionRule:
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
evaluationMode: ALWAYS_DENY
globalPolicyEvaluationMode: ENABLE
clusterAdmissionRules:
${COMPUTE_ZONE}.binauthz:
evaluationMode: REQUIRE_ATTESTATION
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
requireAttestationsBy:
- projects/${PROJECT_ID}/attestors/vulnz-attestor
EOM
ตอนนี้คุณควรมีไฟล์ใหม่บนดิสก์ที่ชื่อ updated_policy.yaml ตอนนี้ระบบจะตรวจสอบผู้รับรองเพื่อยืนยันก่อน แทนที่จะใช้กฎเริ่มต้นที่จะปฏิเสธอิมเมจทั้งหมด
อัปโหลดนโยบายใหม่ไปยังการให้สิทธิ์แบบไบนารี
gcloud beta container binauthz policy import binauth_policy.yaml
ทำให้รูปภาพที่ลงนามใช้งานได้
รับสรุปรูปภาพสำหรับรูปภาพที่ดี
CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:good \
--format='get(image_summary.digest)')
ใช้ไดเจสต์ในการกำหนดค่า Kubernetes
cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
name: deb-httpd
spec:
selector:
app: deb-httpd
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deb-httpd
spec:
replicas: 1
selector:
matchLabels:
app: deb-httpd
template:
metadata:
labels:
app: deb-httpd
spec:
containers:
- name: deb-httpd
image: ${CONTAINER_PATH}@${DIGEST}
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
EOM
ทำให้แอปใช้งานได้กับ GKE
kubectl apply -f deploy.yaml
ตรวจสอบภาระงานในคอนโซลและบันทึกการนำอิมเมจไปใช้งานได้สำเร็จ
7. บล็อกรูปภาพที่ไม่ได้เซ็นชื่อแล้ว
สร้างอิมเมจ
ในขั้นตอนนี้ คุณจะใช้ Docker ในเครื่องเพื่อสร้างอิมเมจไปยังแคชในเครื่อง
docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad .
พุชอิมเมจที่ไม่มีการรับรองไปยังที่เก็บ
docker push us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
รับสรุปรูปภาพสำหรับรูปภาพที่ไม่ดี
CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:bad \
--format='get(image_summary.digest)')
ใช้ไดเจสต์ในการกำหนดค่า Kubernetes
cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
name: deb-httpd
spec:
selector:
app: deb-httpd
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deb-httpd
spec:
replicas: 1
selector:
matchLabels:
app: deb-httpd
template:
metadata:
labels:
app: deb-httpd
spec:
containers:
- name: deb-httpd
image: ${CONTAINER_PATH}@${DIGEST}
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
EOM
พยายามทำให้แอปใช้งานได้กับ GKE
kubectl apply -f deploy.yaml
ตรวจสอบภาระงานในคอนโซล และสังเกตข้อผิดพลาดที่ระบุว่าการทำให้ใช้งานได้ถูกปฏิเสธ
No attestations found that were valid and signed by a key trusted by the attestor
8. ยินดีด้วย
ยินดีด้วย คุณศึกษา Codelab จบแล้ว
สิ่งที่เราได้พูดคุยกันมีดังนี้
- การเซ็นชื่อบนรูปภาพ
- นโยบายควบคุมการเข้าชม
- การรับรองรูปภาพที่สแกน
- กำลังให้สิทธิ์รูปภาพที่ลงนาม
- บล็อกรูปภาพที่ไม่ได้ลงนาม
ขั้นตอนต่อไปที่ทำได้
- การรักษาความปลอดภัยการทำให้อิมเมจใช้งานได้กับ Cloud Run และ Google Kubernetes Engine | เอกสารประกอบ Cloud Build
- การเริ่มต้นอย่างรวดเร็ว: กำหนดค่านโยบายการให้สิทธิ์แบบไบนารีด้วย GKE | Google Cloud
ล้างข้อมูล
เพื่อหลีกเลี่ยงไม่ให้เกิดการเรียกเก็บเงินกับบัญชี Google Cloud สำหรับทรัพยากรที่ใช้ในบทแนะนำนี้ โปรดลบโปรเจ็กต์ที่มีทรัพยากรดังกล่าวหรือเก็บโปรเจ็กต์ไว้และลบทรัพยากรแต่ละรายการ
กำลังลบโปรเจ็กต์
วิธีที่ง่ายที่สุดในการยกเลิกการเรียกเก็บเงินคือการลบโปรเจ็กต์ที่คุณสร้างไว้สำหรับบทแนะนำ
—
อัปเดตครั้งล่าสุด: 21/03/23