1. Giới thiệu
Công cụ Phân tích vùng chứa cung cấp tính năng quét lỗ hổng bảo mật và lưu trữ siêu dữ liệu cho các vùng chứa. Dịch vụ quét lỗ hổng bảo mật sẽ quét các hình ảnh trong Artifact Registry và Container Registry, sau đó lưu trữ siêu dữ liệu kết quả và cung cấp siêu dữ liệu để sử dụng thông qua một API. Bộ nhớ siêu dữ liệu giúp bạn lưu trữ thông tin từ nhiều nguồn, trong đó có hoạt động quét lỗ hổng bảo mật, các dịch vụ của Google Cloud và các nhà cung cấp bên thứ ba.
Quá trình quét lỗ hổng có thể diễn ra tự động hoặc theo yêu cầu:
- Khi tính năng tự động quét được bật, quá trình quét sẽ tự động kích hoạt mỗi khi bạn đẩy một hình ảnh mới lên Artifact Registry hoặc Container Registry. Thông tin về lỗ hổng được cập nhật liên tục khi các lỗ hổng bảo mật mới được phát hiện.
- Khi tính năng Quét theo yêu cầu được bật, bạn phải chạy một lệnh để quét hình ảnh trên máy hoặc một hình ảnh trong Artifact Registry hoặc Sổ đăng ký vùng chứa. Tính năng quét theo yêu cầu cho phép bạn linh hoạt quét các vùng chứa. Ví dụ: bạn có thể quét một hình ảnh được tạo cục bộ và khắc phục các lỗ hổng trước khi lưu trữ hình ảnh đó vào sổ đăng ký. Kết quả quét có sẵn trong tối đa 48 giờ sau khi quá trình quét hoàn tất và thông tin về lỗ hổng bảo mật không được cập nhật sau khi quét.
Khi tích hợp tính năng Phân tích vùng chứa vào quy trình CI/CD, bạn có thể đưa ra quyết định dựa trên siêu dữ liệu đó. Ví dụ: bạn có thể sử dụng chế độ Uỷ quyền nhị phân để tạo các chính sách triển khai chỉ cho phép triển khai những hình ảnh tuân thủ từ tổ chức quản lý tên miền đáng tin cậy.
Kiến thức bạn sẽ học được
- Cách bật tính năng tự động quét
- Cách thực hiện quét theo yêu cầu
- Cách tích hợp tính năng quét trong quy trình tạo bản dựng
- Cách ký hình ảnh được phê duyệt
- Cách sử dụng bộ điều khiển nhập vào GKE để chặn hình ảnh
- Cách định cấu hình GKE để chỉ cho phép những hình ảnh đã được phê duyệt có chữ ký
2. Thiết lập và yêu cầu
Thiết lập môi trường theo tiến độ riêng
- Đăng nhập vào Google Cloud Console rồi tạo dự án mới hoặc sử dụng lại dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.
- Tên dự án là tên hiển thị của những người tham gia dự án này. Đây là một chuỗi ký tự không được API của Google sử dụng. Bạn có thể cập nhật thông tin này bất cứ lúc nào.
- Mã dự án là duy nhất trong tất cả các dự án Google Cloud và không thể thay đổi (không thể thay đổi sau khi đã đặt). Cloud Console sẽ tự động tạo một chuỗi duy nhất; thường bạn không quan tâm đến sản phẩm đó là gì. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham chiếu đến Mã dự án (mã này thường được xác định là
PROJECT_ID
). Nếu không thích mã đã tạo, bạn có thể tạo một mã nhận dạng ngẫu nhiên khác. Ngoài ra, bạn có thể thử phương pháp của riêng mình và xem có được cung cấp hay không. Bạn không thể thay đổi thông tin này sau bước này và thông báo đó sẽ vẫn tồn tại trong thời gian của dự án. - Đối với thông tin của bạn, có giá trị thứ ba, Project Number (Số dự án) mà một số API sử dụng. Tìm hiểu thêm về cả ba giá trị này trong tài liệu này.
- Tiếp theo, bạn sẽ phải bật tính năng thanh toán trong Cloud Console để sử dụng API/tài nguyên trên đám mây. Việc chạy qua lớp học lập trình này sẽ không tốn nhiều chi phí. Để tắt các tài nguyên nhằm tránh bị tính phí ngoài hướng dẫn này, bạn có thể xoá các tài nguyên bạn đã tạo hoặc xoá toàn bộ dự án. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí 300 USD.
Khởi động Cloudshell Editor
Phòng thí nghiệm này được thiết kế và thử nghiệm để sử dụng với Google Cloud Shell Editor. Để truy cập vào trình chỉnh sửa,
- truy cập vào dự án google của bạn tại https://console.cloud.google.com.
- Ở góc trên cùng bên phải, hãy nhấp vào biểu tượng trình chỉnh sửa vỏ đám mây
- Một ngăn mới sẽ mở ra ở cuối cửa sổ
Thiết lập môi trường
Trong Cloud Shell, hãy đặt mã dự án và số dự án cho dự án của bạn. Lưu chúng dưới dạng biến PROJECT_ID
và PROJECT_ID
.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
--format='value(projectNumber)')
Bật dịch vụ
Bật tất cả dịch vụ cần thiết:
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
Tạo kho lưu trữ Artifact Registry
Trong phòng thí nghiệm này, bạn sẽ sử dụng Artifact Registry để lưu trữ và quét hình ảnh của mình. Tạo kho lưu trữ bằng lệnh sau.
gcloud artifacts repositories create artifact-scanning-repo \
--repository-format=docker \
--location=us-central1 \
--description="Docker repository"
Định cấu hình docker để sử dụng thông tin đăng nhập gcloud của bạn khi truy cập vào Artifact Registry.
gcloud auth configure-docker us-central1-docker.pkg.dev
3. Quét tự động
Quá trình quét phần mềm tự động kích hoạt mỗi khi bạn đẩy một hình ảnh mới sang Artifact Registry hoặc Container Registry. Thông tin về lỗ hổng được cập nhật liên tục khi các lỗ hổng bảo mật mới được phát hiện. Trong phần này, bạn sẽ đẩy một hình ảnh vào Artifact Registry và khám phá kết quả.
Tạo và thay đổi thành thư mục công việc
mkdir vuln-scan && cd vuln-scan
Xác định hình ảnh mẫu
Tạo một tệp có tên là Dockerfile với các nội dung sau.
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
Tạo một tệp có tên main.py với nội dung sau đây
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
Tạo và đẩy hình ảnh lên thực tế tăng cường
Sử dụng Cloud Build để tạo và tự động đẩy vùng chứa của bạn vào Artifact Registry. Hãy ghi lại thẻ bad
trên hình ảnh. Thông tin này sẽ giúp bạn xác định địa chỉ đó cho các bước sau.
gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
Xem lại thông tin về hình ảnh
Khi quá trình xây dựng đã hoàn tất, hãy xem xét hình ảnh và kết quả về Lỗ hổng bảo mật trên trang tổng quan của Artifact Registry.
- Mở Artifact Registry trong Cloud Console
- Nhấp vào kho lưu trữ quét cấu phần phần mềm để xem nội dung
- Nhấp vào thông tin chi tiết của hình ảnh
- Nhấp vào thông báo mới nhất về hình ảnh của bạn
- Sau khi quét xong, nhấp vào thẻ lỗ hổng bảo mật trên hình ảnh
Từ tab lỗ hổng bảo mật, bạn sẽ thấy kết quả của quá trình quét tự động cho hình ảnh bạn vừa tạo.
Tính năng tự động quét được bật theo mặc định. Khám phá Cài đặt của Artifact Registry để xem cách bạn có thể tắt/bật tự động quét.
4. Quét theo yêu cầu
Trong nhiều trường hợp, bạn có thể phải quét trước khi đẩy hình ảnh vào kho lưu trữ. Ví dụ: nhà phát triển vùng chứa có thể quét hình ảnh và khắc phục vấn đề trước khi đẩy mã lên phần kiểm soát nguồn. Trong ví dụ dưới đây, bạn sẽ xây dựng và phân tích hình ảnh cục bộ trước khi thao tác trên kết quả.
Tạo hình ảnh
Trong bước này, bạn sẽ sử dụng Docker cục bộ để tạo hình ảnh vào bộ nhớ đệm cục bộ.
docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image .
Quét hình ảnh
Sau khi tạo xong hình ảnh, hãy yêu cầu quét hình ảnh. Kết quả quét được lưu trữ trong máy chủ siêu dữ liệu. Công việc hoàn tất với vị trí của kết quả trong máy chủ siêu dữ liệu.
gcloud artifacts docker images scan \
us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
--format="value(response.scan)" > scan_id.txt
Xem lại tệp đầu ra
Hãy dành chút thời gian để xem lại kết quả của bước trước đó đã được lưu trữ trong tệp scan_id.txt. Hãy lưu ý vị trí báo cáo của kết quả quét trong máy chủ siêu dữ liệu.
cat scan_id.txt
Xem lại kết quả quét chi tiết
Để xem kết quả thực tế của quá trình quét, hãy sử dụng lệnh list-vulnerabilities
trên vị trí báo cáo được ghi chú trong tệp đầu ra.
gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt)
Dữ liệu đầu ra chứa một lượng dữ liệu đáng kể về tất cả lỗ hổng bảo mật trong hình ảnh.
Gắn cờ vấn đề nghiêm trọng
Con người hiếm khi sử dụng dữ liệu được lưu trữ trực tiếp trong báo cáo. Thông thường, kết quả được sử dụng bởi một quy trình tự động. Hãy dùng các lệnh bên dưới để đọc thông tin chi tiết về báo cáo và ghi nhật ký nếu phát hiện thấy bất kỳ lỗ hổng nghiêm trọng nào
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
Kết quả từ lệnh này sẽ là
Failed vulnerability check for CRITICAL level
5. Quét quy trình xây dựng
Trong phần này, bạn sẽ tạo một quy trình tạo bản dựng tự động. Quy trình này sẽ tạo hình ảnh vùng chứa của bạn, quét hình ảnh này rồi đánh giá kết quả. Nếu không phát hiện lỗ hổng bảo mật Nghiêm trọng nào, chúng tôi sẽ đẩy hình ảnh đó vào kho lưu trữ. Nếu phát hiện thấy các lỗ hổng nghiêm trọng, bản dựng sẽ không thành công và thoát.
Cấp quyền truy cập cho tài khoản dịch vụ Cloud Build
Cloud Build sẽ cần có quyền truy cập vào API quét theo yêu cầu. Cấp quyền truy cập bằng các lệnh sau.
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"
Tạo quy trình Cloud Build
Lệnh sau đây sẽ tạo một tệp Cloudbuild.yaml trong thư mục của bạn. Tệp này sẽ được dùng cho quy trình tự động. Trong ví dụ này, các bước được giới hạn trong quy trình xây dựng vùng chứa. Tuy nhiên, trên thực tế, bạn sẽ đưa vào các hướng dẫn và bài kiểm thử dành riêng cho ứng dụng ngoài các bước dành cho vùng chứa.
Tạo tệp bằng lệnh sau.
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
Chạy quy trình CI
Gửi bản dựng để xử lý nhằm xác minh lỗi của bản dựng khi phát hiện thấy một lỗ hổng bảo mật nghiêm trọng.
gcloud builds submit
Xem lại lỗi bản dựng
Bản dựng bạn vừa gửi sẽ không thành công do hình ảnh chứa các lỗ hổng nghiêm trọng.
Xem lại lỗi bản dựng trên trang Cloud Build History
Khắc phục lỗ hổng bảo mật
Cập nhật Dockerfile để sử dụng hình ảnh cơ sở không chứa các lỗ hổng nghiêm trọng.
Ghi đè Dockerfile để sử dụng hình ảnh Debian 10 bằng lệnh sau
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
Chạy quy trình CI bằng hình ảnh phù hợp
Gửi bản dựng để xử lý nhằm xác minh rằng bản dựng sẽ thành công khi không tìm thấy lỗ hổng bảo mật nghiêm trọng nào.
gcloud builds submit
Đánh giá thành công của bản dựng
Bản dựng bạn vừa gửi sẽ thành công vì hình ảnh được cập nhật không có lỗ hổng bảo mật Nghiêm trọng.
Xem xét thành công của bản dựng trên trang Cloud Build History (Nhật ký bản dựng trên đám mây)
Xem lại kết quả quét
Xem xét hình ảnh phù hợp trong Sổ đăng ký cấu phần phần mềm
- Mở Artifact Registry trong Cloud Console
- Nhấp vào kho lưu trữ quét cấu phần phần mềm để xem nội dung
- Nhấp vào thông tin chi tiết của hình ảnh
- Nhấp vào thông báo mới nhất về hình ảnh của bạn
- Nhấp vào thẻ lỗ hổng bảo mật để tìm hình ảnh
6. Ký hình ảnh
Tạo Ghi chú của người chứng thực
Ghi chú của người kiểm chứng chỉ đơn giản là một dữ liệu nhỏ đóng vai trò là nhãn cho loại chữ ký đang được áp dụng. Ví dụ: một ghi chú có thể chỉ ra quá trình quét lỗ hổng bảo mật, trong khi một ghi chú khác có thể được dùng cho quá trình đăng xuất đảm bảo chất lượng. Ghi chú sẽ được tham chiếu trong quá trình ký.
Tạo ghi chú
cat > ./vulnz_note.json << EOM
{
"attestation": {
"hint": {
"human_readable_name": "Container Vulnerabilities attestation authority"
}
}
}
EOM
Lưu trữ ghi chú
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}"
Xác minh ghi chú
curl -vvv \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
Tạo Người kiểm chứng
Người chứng thực được sử dụng để thực hiện quy trình ký hình ảnh thực tế và sẽ đính kèm một bản ghi chú vào hình ảnh để xác minh sau. Tạo trình chứng thực để sử dụng sau này.
Tạo người chứng thực
ATTESTOR_ID=vulnz-attestor
gcloud container binauthz attestors create $ATTESTOR_ID \
--attestation-authority-note=$NOTE_ID \
--attestation-authority-note-project=${PROJECT_ID}
Xác minh người chứng thực
gcloud container binauthz attestors list
Xin lưu ý rằng dòng cuối cùng cho biết NUM_PUBLIC_KEYS: 0
bạn sẽ cung cấp khoá ở bước sau
Ngoài ra, xin lưu ý rằng Cloud Build sẽ tự động tạo trình chứng thực built-by-cloud-build
trong dự án khi bạn chạy một bản dựng có tạo hình ảnh. Vì vậy, lệnh trên trả về hai trình chứng thực, vulnz-attestor
và built-by-cloud-build
. Sau khi hình ảnh được tạo thành công, Cloud Build sẽ tự động ký và tạo lời chứng thực cho hình ảnh đó.
Thêm vai trò IAM
Tài khoản dịch vụ Uỷ quyền nhị phân sẽ cần có quyền xem ghi chú chứng thực. Cung cấp quyền truy cập bằng lệnh gọi API sau đây
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
Sử dụng tệp này để tạo chính sách 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"
Thêm khoá KMS
Người kiểm chứng cần các khoá mật mã để đính kèm ghi chú và cung cấp các chữ ký có thể xác minh. Ở bước này, bạn sẽ tạo và lưu trữ khoá trong KMS để Cloud Build có thể truy cập sau này.
Trước tiên, hãy thêm một số biến môi trường để mô tả khoá mới
KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1
Tạo một chiếc móc khoá để lưu giữ một bộ khoá
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
Tạo một cặp khoá ký bất đối xứng mới cho người chứng thực
gcloud kms keys create "${KEY_NAME}" \
--keyring="${KEYRING}" --location="${KEY_LOCATION}" \
--purpose asymmetric-signing \
--default-algorithm="ec-sign-p256-sha256"
Bạn sẽ thấy khoá của mình xuất hiện trên trang KMS của Google Cloud Console.
Bây giờ, hãy liên kết khoá với người chứng thực của bạn thông qua lệnh 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}"
Nếu in lại danh sách đơn vị quản lý, giờ đây, bạn sẽ thấy một khoá được đăng ký:
gcloud container binauthz attestors list
Tạo chứng thực có chữ ký
Tại thời điểm này, bạn đã định cấu hình các tính năng cho phép bạn ký hình ảnh. Sử dụng Người kiểm chứng mà bạn đã tạo trước đây để ký Hình ảnh vùng chứa mà bạn đang xử lý
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)')
Giờ đây, bạn có thể dùng gcloud để tạo chứng thực của mình. Lệnh này chỉ lấy thông tin chi tiết của khoá bạn muốn sử dụng để ký và hình ảnh vùng chứa cụ thể mà bạn muốn phê duyệt
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}"
Trong điều khoản Phân tích vùng chứa, thao tác này sẽ tạo ra một lần xuất hiện mới và đính kèm lần xuất hiện này vào ghi chú của người chứng thực. Để đảm bảo mọi thứ hoạt động như mong đợi, bạn có thể liệt kê các chứng thực của mình
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
7. Ký bằng Cloud Build
Bạn đã bật tính năng Ký hình ảnh và sử dụng Người kiểm chứng để ký hình ảnh mẫu của mình theo cách thủ công. Trên thực tế, bạn nên áp dụng Chứng thực trong các quy trình tự động, chẳng hạn như quy trình CI/CD.
Trong phần này, bạn sẽ định cấu hình Cloud Build để tự động Chứng thực hình ảnh
Vai trò
Thêm vai trò Người xem của người kiểm chứng uỷ quyền nhị phân vào tài khoản dịch vụ Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
Thêm vai trò Người ký/Người xác minh mã khoá của Cloud KMS vào Tài khoản dịch vụ Cloud Build (Ký dựa trên KMS):
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
Thêm vai trò Người đính kèm ghi chú phân tích vùng chứa vào tài khoản dịch vụ Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/containeranalysis.notes.attacher
Chuẩn bị Bước tạo bản dựng Cloud Build tuỳ chỉnh
Bạn sẽ sử dụng một bước của Bản dựng tuỳ chỉnh trong Cloud Build để đơn giản hoá quy trình chứng thực. Google cung cấp bước Bản dựng tuỳ chỉnh này. Bước này chứa các chức năng trợ giúp để đơn giản hoá quy trình. Trước khi sử dụng, mã cho bước bản dựng tuỳ chỉnh phải được tích hợp vào một vùng chứa và đẩy lên Cloud Build. Để thực hiện việc này, hãy chạy các lệnh sau:
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
Thêm một bước ký vào Cloudbuild.yaml
Ở bước này, bạn sẽ thêm bước chứng thực vào quy trình Cloud Build mà bạn đã xây dựng trước đó.
- Xem lại bước mới mà bạn sẽ thêm.
Chỉ xem xét. Không sao chép
#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'
- Ghi đè tệp Cloudbuild.yaml bằng quy trình hoàn chỉnh đã cập nhật.
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
Chạy bản dựng
gcloud builds submit
Xem lại bản dựng trong Cloud Build History
Mở Cloud Console để truy cập vào trang Cloud Build Nhật ký và xem lại bản dựng mới nhất đó cũng như thực hiện thành công các bước xây dựng.
8. Chính sách kiểm soát nhập học
Uỷ quyền nhị phân là một tính năng trong GKE và Cloud Run. Tính năng này cho phép xác thực các quy tắc trước khi cho phép chạy hình ảnh vùng chứa. Quy trình xác thực sẽ thực thi đối với mọi yêu cầu chạy hình ảnh, từ một quy trình CI/CD đáng tin cậy hoặc một người dùng đang tìm cách triển khai hình ảnh theo cách thủ công. Tính năng này cho phép bạn bảo vệ môi trường thời gian chạy hiệu quả hơn so với việc chỉ kiểm tra quy trình CI/CD.
Để hiểu rõ chức năng này, bạn cần sửa đổi chính sách mặc định của GKE để thực thi một quy tắc cấp phép nghiêm ngặt.
Tạo cụm GKE
Tạo cụm GKE:
gcloud beta container clusters create binauthz \
--zone us-central1-a \
--binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
Cho phép Cloud Build triển khai cho cụm này:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/container.developer"
Cho phép tất cả chính sách
Trước tiên, hãy xác minh trạng thái chính sách mặc định và khả năng triển khai bất kỳ hình ảnh nào
- Xem xét chính sách hiện có
gcloud container binauthz policy export
- Xin lưu ý rằng chính sách thực thi được đặt thành
ALWAYS_ALLOW
evaluationMode: ALWAYS_ALLOW
- Triển khai Mẫu để xác minh rằng bạn có thể triển khai mọi thứ
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- Xác minh việc triển khai đã hoạt động
kubectl get pods
Bạn sẽ thấy kết quả sau
- Xoá quá trình triển khai
kubectl delete pod hello-server
Từ chối tất cả chính sách
Bây giờ, hãy cập nhật chính sách để không cho phép tất cả hình ảnh.
- Xuất chính sách hiện tại sang một tệp có thể chỉnh sửa
gcloud container binauthz policy export > policy.yaml
- Thay đổi chính sách
Trong trình chỉnh sửa văn bản, hãy thay đổi đánh giáMode từ ALWAYS_ALLOW thành ALWAYS_DENY.
edit policy.yaml
Tệp YAML của chính sách sẽ xuất hiện như sau:
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_DENY enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- Mở cửa sổ dòng lệnh rồi áp dụng chính sách mới, rồi đợi vài giây để thay đổi có hiệu lực
gcloud container binauthz policy import policy.yaml
- Thử triển khai khối lượng công việc mẫu
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- Triển khai không thành công với thông báo sau
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
Huỷ bỏ chính sách này để cho phép tất cả
Trước khi chuyển sang phần tiếp theo, hãy nhớ huỷ bỏ các thay đổi về chính sách
- Thay đổi chính sách
Trong trình chỉnh sửa văn bản, hãy thay đổi đánh giáMode từ ALWAYS_DENY thành ALWAYS_ALLOW.
edit policy.yaml
Tệp YAML của chính sách sẽ xuất hiện như sau:
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_ALLOW enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- Áp dụng chính sách hoàn nguyên
gcloud container binauthz policy import policy.yaml
9. Chặn lỗ hổng bảo mật trong GKE
Trong phần này, bạn sẽ kết hợp những điều đã tìm hiểu từ trước đến nay bằng cách triển khai quy trình CI/CD với Cloud Build. Quy trình này có thể quét hình ảnh, sau đó kiểm tra các lỗ hổng bảo mật trước khi ký hình ảnh và cố gắng triển khai. GKE sẽ sử dụng chế độ Cấp quyền nhị phân để xác thực hình ảnh đã có chữ ký từ quy trình quét lỗ hổng bảo mật trước khi cho phép chạy hình ảnh.
Cập nhật chính sách GKE để yêu cầu chứng thực
Bắt buộc phải có hình ảnh phải có chữ ký của Attestor bằng cách thêmClusterAdmissionRules vào Chính sách BinAuth của GKE của bạn
Ghi đè chính sách này bằng cấu hình đã cập nhật bằng lệnh bên dưới.
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
Áp dụng chính sách
gcloud beta container binauthz policy import binauth_policy.yaml
Cố gắng triển khai hình ảnh chưa được ký
Tạo chỉ số mô tả triển khai cho ứng dụng bạn đã xây dựng trước đó bằng lệnh sau. Hình ảnh dùng ở đây là hình ảnh bạn đã tạo trước đó. Hình ảnh này có chứa các lỗ hổng bảo mật nghiêm trọng và KHÔNG chứa chứng thực có chữ ký.
Nhân viên kiểm soát nhập vào GKE cần phải biết chính xác hình ảnh cần triển khai để xác thực chữ ký một cách nhất quán. Để thực hiện điều này, bạn cần sử dụng chuỗi đại diện hình ảnh thay vì một thẻ đơn giản.
Nhận thông báo tổng hợp về hình ảnh có hình ảnh không hợp lệ
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)')
Sử dụng chuỗi đại diện trong cấu hình 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
Cố gắng triển khai ứng dụng cho GKE
kubectl apply -f deploy.yaml
Xem lại khối lượng công việc trong bảng điều khiển và lưu ý lỗi cho biết quá trình triển khai đã bị từ chối:
No attestations found that were valid and signed by a key trusted by the attestor
Triển khai hình ảnh đã ký
Nhận thông báo tổng hợp về hình ảnh có hình ảnh không hợp lệ
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)')
Sử dụng chuỗi đại diện trong cấu hình 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
Triển khai ứng dụng cho GKE
kubectl apply -f deploy.yaml
Xem lại khối lượng công việc trong bảng điều khiển và ghi lại việc triển khai hình ảnh thành công.
10. Xin chúc mừng!
Xin chúc mừng, bạn đã hoàn thành lớp học lập trình!
Nội dung chúng ta đã đề cập:
- Cách bật tính năng tự động quét
- Cách thực hiện quét theo yêu cầu
- Cách tích hợp tính năng quét trong quy trình tạo bản dựng
- Cách ký hình ảnh được phê duyệt
- Cách sử dụng bộ điều khiển nhập vào GKE để chặn hình ảnh
- Cách định cấu hình GKE để chỉ cho phép những hình ảnh đã được phê duyệt có chữ ký
Bước tiếp theo:
- Bảo mật quy trình triển khai hình ảnh cho Cloud Run và Google Kubernetes Engine | Tài liệu về Cloud Build
- Bắt đầu nhanh: Thiết lập chính sách Uỷ quyền nhị phân với GKE | Google Cloud
Dọn dẹp
Để tránh làm phát sinh chi phí cho các tài nguyên được sử dụng trong hướng dẫn này trong tài khoản Google Cloud của bạn, hãy xoá dự án chứa các tài nguyên đó, hoặc giữ lại dự án và xoá từng tài nguyên riêng lẻ.
Xoá dự án
Cách dễ nhất để loại bỏ việc thanh toán là xoá dự án bạn đã tạo cho phần hướng dẫn.