Bảo vệ công trình xây dựng vùng chứa

1. Giới thiệu

ead1609267034bf7.png

Lỗ hổng phần mềm là những điểm yếu có thể gây ra sự cố hệ thống ngoài ý muốn hoặc cung cấp cho những kẻ xấu phương tiện để xâm phạm phần mềm của bạn. Công cụ Phân tích vùng chứa cung cấp hai kiểu quét hệ điều hành để tìm các lỗ hổng bảo mật trong vùng chứa:

  • API quét theo yêu cầu cho phép bạn quét hình ảnh vùng chứa theo cách thủ công để tìm lỗ hổng hệ điều hành, trên máy tính của bạn hoặc từ xa trong Container Registry (Cơ sở lưu trữ vùng chứa) hoặc Artifact Registry (Cơ sở lưu trữ cấu phần phần mềm).
  • API Quét vùng chứa cho phép bạn tự động phát hiện lỗ hổng bảo mật trên hệ điều hành, quét mỗi lần bạn đẩy một hình ảnh lên Sổ đăng ký vùng chứa hoặc Sổ đăng ký cấu phần phần mềm (Artifact Registry). Việc bật API này cũng cho phép quét gói ngôn ngữ để tìm lỗ hổng bảo mật Go và Java.

API Quét theo yêu cầu cho phép bạn quét hình ảnh được lưu trữ cục bộ trên máy tính hoặc từ xa trong Container Registry (Kho lưu trữ vùng chứa) hoặc Artifact Registry (Kho lưu trữ cấu phần phần mềm). Điều này cho phép bạn kiểm soát chi tiết các vùng chứa mà bạn muốn quét để phát hiện các lỗ hổng bảo mật. Bạn có thể sử dụng tính năng Quét theo yêu cầu để quét hình ảnh trong quy trình CI/CD trước khi quyết định xem có lưu trữ các hình ảnh đó trong sổ đăng ký hay không.

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

Trong phòng thí nghiệm này, bạn sẽ:

  • Tạo hình ảnh bằng Cloud Build
  • Sử dụng Registry Artifact cho vùng chứa
  • Sử dụng tính năng tự động quét lỗ hổng
  • Định cấu hình tính năng quét theo yêu cầu
  • Thêm tính năng quét hình ảnh trong CICD trên Cloud Build

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 một dự án mới hoặc sử dụng lại một 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ị cho 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 trên 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 thì bạn không cần quan tâm đến chuỗi này. 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 (thường được xác định là PROJECT_ID). Nếu không thích mã được tạo, bạn có thể tạo một mã ngẫu nhiên khác. Ngoài ra, bạn có thể thử dùng tên của riêng mình để xem tên đó có được chấp nhận hay không. Bạn không thể thay đổi thông tin này sau bước này và thông tin này sẽ được giữ nguyên trong suốt thời gian thực hiện 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.
  1. Tiếp theo, bạn cần bật tính năng thanh toán trong Cloud Console để sử dụng các tài nguyên/API trên Cloud. 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 để không bị tính phí sau khi hoàn tất hướng dẫn này, bạn có thể xoá các tài nguyê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 

3. Tạo hình ảnh bằng Cloud Build

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 tìm thấy lỗ hổng CRITICAL, công cụ này 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 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 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, trong thực tế, bạn sẽ thêm các hướng dẫn và kiểm thử dành riêng cho ứng dụng ngoài các bước về 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: ['-']


EOF

Chạy quy trình CI

Gửi bản dựng để xử lý

gcloud builds submit

Xem lại Thông tin chi tiết về bản dựng

Sau khi quá trình xây dựng đã bắt đầu, hãy xem xét tiến trình trong trang tổng quan Cloud Build.

  1. Mở Cloud Build trong Cloud Console
  2. Nhấp vào bản dựng để xem nội dung

4. Artifact Registry cho vùng chứa

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

Cập nhật quy trình Cloud Build

Sửa đổi quy trình tạo bản dựng để đẩy hình ảnh kết quả vào 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

Chạy quy trình CI

Gửi bản dựng để xử lý

gcloud builds submit

5. Quét lỗ hổng tự động

Tính năng quét cấu phần phần mềm sẽ tự động kích hoạt mỗi khi bạn đẩy hình ảnh mới vào Cấu phần phần mềm đăng ký hoặc Kho lưu trữ vùng chứa. 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ẽ xem lại hình ảnh mà bạn vừa tạo và đẩy vào Cấu phần phần mềm đăng ký, đồng thời khám phá kết quả về lỗ hổng bảo mật.

Xem lại thông tin chi tiết về hình ảnh

Khi quá trình tạo bản dựng trước đó đã 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.

  1. Mở Registry Artifact (Cơ sở lưu trữ cấu phần phần mềm) trong Cloud Console
  2. Nhấp vào kho lưu trữ quét cấu phần phần mềm để xem nội dung
  3. Nhấp vào thông tin chi tiết về hình ảnh
  4. Nhấp vào thông báo mới nhất về hình ảnh của bạn
  5. 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.

361be7b3bf293fca.png

Tính năng tự động quét được bật theo mặc định. Khám phá phần Cài đặt kho lưu trữ cấu phần phần mềm để xem cách tắt/bật tính năng tự động quét.

6. 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ụ bên dưới, bạn sẽ tạo và phân tích hình ảnh trên máy trước khi xử lý 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. 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ả cá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 trực tiếp sử dụng dữ liệu được lưu trữ 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. Sử dụng các lệnh dưới đây để đọc thông tin chi tiết về báo cáo và ghi lại nếu phát hiện thấy lỗ hổng CRITICAL

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ả của lệnh này sẽ là

Failed vulnerability check for CRITICAL level

7. Quét trong CICD bằng Cloud Build

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"

Cập nhật 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, trong 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 trong trang Nhật ký bản dựng trên Cloud Build

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 phát hiện thấy lỗ hổng có mức độ nghiêm trọng là CRITICAL.

gcloud builds submit

Xem lại bản dựng thành cô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

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

  1. Mở Artifact Registry trong Cloud Console
  2. Nhấp vào kho lưu trữ quét cấu phần phần mềm để xem nội dung
  3. Nhấp vào thông tin chi tiết về hình ảnh
  4. Nhấp vào thông báo mới nhất về hình ảnh của bạn
  5. Nhấp vào thẻ lỗ hổng bảo mật của hình ảnh

8. Xin chúc mừng!

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

Nội dung chúng ta đã đề cập:

  • Xây dựng hình ảnh bằng Cloud Build
  • Cấu phần phần mềm đăng ký cho vùng chứa
  • Tự động quét lỗ hổng
  • Quét theo yêu cầu
  • Quét trong CICD bằng Cloud Build

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ỏ tính năng thanh toán là xoá dự án mà bạn đã tạo cho hướng dẫn này.

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