Triển khai kiểm soát bằng xác thực nhị phân

1. Giới thiệu

Uỷ quyền nhị phân là một biện pháp kiểm soát bảo mật tại thời điểm triển khai nhằm đảm bảo chỉ triển khai những hình ảnh vùng chứa đáng tin cậy trên Google Kubernetes Engine (GKE) hoặc Cloud Run. Với tính năng Ủy quyền nhị phân, bạn có thể yêu cầu hình ảnh phải có chữ ký của các cơ quan đáng tin cậy trong quá trình phát triển, sau đó thực thi việc xác thực chữ ký khi triển khai. Bằng cách thực thi quy trình xác thực, bạn có thể kiểm soát chặt chẽ hơn môi trường vùng chứa của mình bằng cách đảm bảo chỉ tích hợp những hình ảnh đã xác minh vào quy trình xây dựng và phát hành.

Sơ đồ dưới đây cho thấy các thành phần trong quá trình thiết lập Uỷ quyền nhị phân/Bản dựng đám mây:

Quy trình chứng thực uỷ quyền nhị phân của Cloud Build.**Hình 1.**Quy trình Cloud Build giúp tạo quy trình chứng thực Uỷ quyền nhị phân.

Trong quy trình này:

  1. Mã để tạo hình ảnh vùng chứa sẽ được đẩy đến kho lưu trữ nguồn, chẳng hạn như Cloud Source Repositories.
  2. Cloud Build là một công cụ tích hợp liên tục (CI) tạo và thử nghiệm vùng chứa.
  3. Bản dựng này sẽ đẩy hình ảnh vùng chứa vào Vùng đăng ký vùng chứa hoặc một sổ đăng ký khác lưu trữ hình ảnh đã tạo của bạn.
  4. Dịch vụ quản lý khoá đám mây, cung cấp tính năng quản lý khoá cho cặp khoá mã hoá, ký hình ảnh vùng chứa. Sau đó, chữ ký thu được sẽ được lưu trữ trong một chứng thực mới tạo.
  5. Tại thời điểm triển khai, người chứng thực xác minh quy trình chứng thực bằng cách sử dụng khoá công khai của cặp khoá. Uỷ quyền nhị phân thực thi chính sách này bằng cách yêu cầu chứng thực có chữ ký để triển khai hình ảnh vùng chứa.

Trong phòng thí nghiệm này, bạn sẽ tập trung vào các công cụ và kỹ thuật bảo mật các cấu phần phần mềm đã triển khai. Phòng thí nghiệm này tập trung vào các cấu phần phần mềm (vùng chứa) sau khi được tạo, nhưng không được triển khai cho bất kỳ môi trường cụ thể nào.

Kiến thức bạn sẽ học được

  • Ký hình ảnh
  • Chính sách kiểm soát nhập học
  • Ký hình ảnh đã quét
  • Uỷ quyền hình ảnh đã ký
  • Hình ảnh chưa ký bị chặn

2. Thiết lập và yêu cầu

Thiết lập môi trường theo tiến độ riêng

  1. Đă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.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 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.
  1. 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.

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_IDPROJECT_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

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 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

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.

gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image

3. Ký hình ảnh

Người kiểm chứng là gì

Người chứng thực

  • Người/quy trình này chịu trách nhiệm về một đường liên kết trong chuỗi tin cậy của hệ thống.
  • Họ giữ một khoá mã hoá và ký vào một hình ảnh nếu khoá đó vượt qua quy trình phê duyệt của họ.
  • Mặc dù Người tạo chính sách xác định chính sách theo cách tổng quát và trừu tượng, nhưng Người kiểm chứng có trách nhiệm thực thi cụ thể một số khía cạnh của chính sách.
  • Có thể là người thực, chẳng hạn như người kiểm thử đảm bảo chất lượng hoặc người quản lý, hoặc có thể là bot trong hệ thống CI.
  • Tính bảo mật của hệ thống phụ thuộc vào độ tin cậy, vì vậy, điều quan trọng là các khoá riêng tư của hệ thống phải được bảo mật.

Mỗi vai trò trong số này có thể đại diện cho một cá nhân hoặc một nhóm người trong tổ chức của bạn. Trong môi trường phát hành công khai, các vai trò này nhiều khả năng sẽ được quản lý bằng các dự án Google Cloud Platform (GCP) riêng biệt và quyền truy cập vào các tài nguyên sẽ được chia sẻ giữa các dự án đó theo cách hạn chế thông qua Cloud IAM.

a37eb2ed54b9c2eb.png

Người kiểm chứng trong Ủy quyền nhị phân được triển khai bên trên Cloud Container Analysis API, vì vậy, điều quan trọng là bạn phải mô tả cách hoạt động của quy trình này trước khi tiếp tục. API Phân tích vùng chứa được thiết kế để cho phép bạn liên kết siêu dữ liệu với các hình ảnh vùng chứa cụ thể.

Ví dụ: một Ghi chú có thể được tạo để theo dõi lỗ hổng HeartFlow. Sau đó, các nhà cung cấp dịch vụ bảo mật sẽ tạo một trình quét để kiểm tra hình ảnh vùng chứa để tìm lỗ hổng bảo mật và tạo một Lần xuất hiện liên kết với mỗi vùng chứa bị xâm phạm.

208aa5ebc53ff2b3.pngS

Cùng với việc theo dõi các lỗ hổng bảo mật, công cụ Phân tích vùng chứa được thiết kế để trở thành một API siêu dữ liệu chung. Ủy quyền nhị phân sử dụng Phân tích vùng chứa để liên kết chữ ký với hình ảnh vùng chứa mà họ đang xác minh**.** Ghi chú phân tích vùng chứa được dùng để đại diện cho một người chứng thực và Các lần xuất hiện được tạo và liên kết với mỗi vùng chứa mà người chứng thực đã phê duyệt.

API uỷ quyền nhị phân sử dụng khái niệm "người chứng thực" và "chứng thực", nhưng những chứng thực này được triển khai bằng các Ghi chú và Lần xuất hiện tương ứng trong API Phân tích vùng chứa.

63a701bd0057ea17.pngs

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ý.

919f997db0ffb881.pngS

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}"

Ghi chú của bạn hiện được lưu trong Container Analysis API.

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. Để sử dụng người chứng thực của mình, bạn cũng phải đăng ký ghi chú với Uỷ quyền nhị phân:

ed05d438c79b654d.png

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-attestorbuilt-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

1e3af7c177f7a311.pngS

Trước khi bạn có thể sử dụng trình chứng thực này, cơ quan có thẩm quyền của bạn cần tạo một cặp khoá mã hoá dùng để ký hình ảnh vùng chứa. Bạn có thể làm việc này thông qua Dịch vụ quản lý khoá trên đám mây (KMS) của Google.

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 bạn đã tạo trước đó để ký Hình ảnh vùng chứa mà bạn đang xử lý.

858d7e6feeb6f159.pngs

Chứng thực phải bao gồm chữ ký mật mã để cho biết rằng người chứng thực đã xác minh một hình ảnh vùng chứa cụ thể và an toàn để chạy trên cụm của bạn. Để chỉ định hình ảnh vùng chứa nào cần chứng thực, bạn cần xác định chuỗi đại diện của hình ảnh đó.

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}

4. 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 đã bật tính năng cấp quyền nhị phân:

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

  1. Xem xét chính sách hiện có
gcloud container binauthz policy export
  1. Xin lưu ý rằng chính sách thực thi được đặt thành ALWAYS_ALLOW

evaluationMode: ALWAYS_ALLOW

  1. 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
  1. Xác minh việc triển khai đã hoạt động
kubectl get pods

Bạn sẽ thấy kết quả sau

161db370d99ffb13.pngS

  1. 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.

  1. 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
  1. 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

Chính sách này tương đối đơn giản. Dòng globalPolicyEvaluationMode khai báo rằng chính sách này mở rộng chính sách chung do Google xác định. Việc này cho phép tất cả vùng chứa chính thức của GKE chạy theo mặc định. Ngoài ra, chính sách này còn khai báo defaultAdmissionRule cho biết rằng tất cả các nhóm khác sẽ bị từ chối. Quy tắc tiếp nhận có một dòng enforcementMode, trong đó nêu rõ rằng tất cả các nhóm không tuân thủ quy tắc này sẽ bị chặn chạy trên cụm.

Để biết hướng dẫn về cách xây dựng các chính sách phức tạp hơn, hãy tham khảo tài liệu về Uỷ quyền nhị phân.

657752497e59378c.png.

  1. 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
  1. 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
  1. 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

  1. 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
  1. Áp dụng chính sách hoàn nguyên
gcloud container binauthz policy import policy.yaml

5. Ký hình ảnh đã quét

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

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"

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.

  1. Hãy xem bước ký ở bên dưới.

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'
  1. Viết một tệp Cloudbuild.yaml kèm theo quy trình hoàn chỉnh bên dưới.
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.

6. Uỷ quyền hình ảnh đã ký

Trong phần này, bạn sẽ cập nhật GKE để sử dụng quy trình Uỷ quyền nhị phân nhằm xác thực hình ảnh đã có chữ ký từ quá trình quét Lỗ hổng bảo mật trước khi cho phép chạy hình ảnh.

d5c41bb89e22fd61.png

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

Hiện tại, cụm của bạn đang chạy một chính sách với một quy tắc: cho phép vùng chứa từ các kho lưu trữ chính thức và từ chối tất cả các vùng chứa khác.

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

Bây giờ, bạn sẽ có một tệp mới trên đĩa, tên là updated_policy.yaml. Giờ đây, thay vì quy tắc mặc định từ chối tất cả hình ảnh, trước tiên, quy tắc sẽ kiểm tra người chứng thực của bạn để xác minh.

822240fc0b02408e.png.

Tải chính sách mới lên trang Uỷ quyền nhị phân:

gcloud beta container binauthz policy import binauth_policy.yaml

Triển khai hình ảnh đã ký

Nhận thông báo tổng hợp về hình ảnh phù hợp

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.

7. Hình ảnh chưa ký bị chặn

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:bad .

Đẩy hình ảnh chưa có chữ ký vào kho lưu trữ

docker push us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad

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

8. Xin chúc mừng!

Xin chúc mừng, bạn đã hoàn thành lớp học lập trình!

Những nội dung chúng ta đã đề cập:

  • Ký hình ảnh
  • Chính sách kiểm soát nhập học
  • Ký hình ảnh đã quét
  • Uỷ quyền hình ảnh đã ký
  • Hình ảnh chưa ký bị chặn

Bước tiếp theo:

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.

Lần cập nhật gần đây nhất: 21/3/2023