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 lỗi hệ thống do vô tình hoặc tạo điều kiện cho các đối tượng xấu xâm nhập phần mềm của bạn. Container Analysis cung cấp 2 loại hoạt động quét hệ điều hành để tìm các lỗ hổng bảo mật trong vùng chứa:

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

On-Demand Scanning API 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 hoặc Artifact Registry. Nhờ đó, bạn có thể kiểm soát thật chi tiết hơn những vùng chứa mà bạn muốn quét để tìm 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 có nên lưu trữ hình ảnh đó trong một sổ đăng ký hay không.

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

Trong lớp học lập trình này, bạn sẽ:

  • Tạo hình ảnh bằng Cloud Build
  • Sử dụng Artifact Registry cho các vùng chứa
  • Sử dụng tính năng quét lỗ hổng bảo mật tự độ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 vào CICD trong Cloud Build

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

Thiết lập môi trường theo tốc độ của riêng bạn

  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ị của những người tham gia dự án này. Đây là một chuỗi ký tự mà các API của Google không 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à mã duy nhất trên tất cả các dự án trên Google Cloud và không thể thay đổi (bạn không thể thay đổi mã này 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ã nhận dạng được tạo, bạn có thể tạo một mã nhận dạng ngẫu nhiên khác. Hoặc bạn có thể thử tên người dùng của riêng mình để xem tên đó có dùng được 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ẽ giữ nguyên trong suốt thời gian diễn ra dự án.
  • Để bạn biết, có một giá trị thứ ba là Số dự án mà một số API sử dụng. Tìm hiểu thêm về cả 3 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 thực hiện lớp học lập trình này sẽ không tốn nhiều chi phí, nếu có. Để tắt các tài nguyên nhằm tránh phát sinh phí thanh toán ngoài 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í trị giá 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 các giá trị này 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 các dịch vụ

Bật tất cả cá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 tự động để tạo hình ảnh vùng chứa, quét hình ảnh đó rồi đánh giá kết quả. Nếu không tìm thấy lỗ hổng NGHIÊM TRỌNG, thì 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à chuyển sang 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 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 là main.py với nội dung sau

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. Đối với ví dụ này, các bước chỉ giới hạn ở 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 của 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 thông tin chi tiết về bản dựng

Sau khi quy trình xây dựng bắt đầu, hãy xem 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 các 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. 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 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 để đẩ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. Tự động quét lỗ hổng bảo mật

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 chuyển một hình ảnh mới sang Artifact Registry hoặc Container Registry. Thông tin về lỗ hổng bảo mật được cập nhật liên tục khi 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à chuyển đến Artifact Registry, đồng thời khám phá các kết quả về lỗ hổng bảo mật.

Xem chi tiết về hình ảnh

Sau khi hoàn tất quy trình xây dựng trước đó, hãy xem xét hình ảnh và kết quả về Lỗ hổng bảo mật trong trang tổng quan Artifact Registry.

  1. Mở Artifact Registry trong Cloud Console
  2. Nhấp vào artifact-scanning-repo để xem nội dung
  3. Nhấp vào phần chi tiết hình ảnh
  4. Nhấp vào bản tóm tắt mới nhất về hình ảnh của bạn
  5. Sau khi quét xong, hãy nhấp vào thẻ lỗ hổng bảo mật cho hình ảnh

Trong thẻ lỗ hổng bảo mật, bạn sẽ thấy kết quả quét tự động cho hình ảnh mà bạn vừa tạo.

361be7b3bf293fca.png

Tính năng tự động hoá quy trình quét được bật theo mặc định. Khám phá phần Cài đặt Artifact Registry để xem cách bạn có thể tắt/bật tính năng tự động quét.

6. Quét theo yêu cầu

Có nhiều trường hợp bạn có thể cần thực hiện quét trước khi đẩy hình ảnh vào một kho lưu trữ. Ví dụ: nhà phát triển vùng chứa có thể quét một hình ảnh và khắc phục các vấn đề trước khi đẩy mã vào tính năng 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 cục bộ trước khi thực hiện hành động dựa trên kết quả.

Tạo hình ảnh

Trong bước này, bạn sẽ dùng docker cục bộ để tạo hình ảnh cho 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 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ột 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 tệp đầu ra

Dành chút thời gian để xem xét đầu ra 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 kết quả quét chi tiết

Để xem kết quả thực tế của quá trình quét, hãy dùng lệnh list-vulnerabilities tại vị trí báo cáo được ghi trong tệp đầu ra.

gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt) 

Kết quả đầu ra chứa một lượng đáng kể dữ liệu về tất cả các lỗ hổng trong hình ảnh.

Gắn cờ vấn đề nghiêm trọng

Con người hiếm khi sử dụng trực tiếp dữ liệu được lưu trữ trong báo cáo. Thông thường, kết quả được dùng trong một quy trình tự động. Sử 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 tìm thấy lỗ hổng BẢO MẬT NGHIÊM TRỌNG

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. Đối với ví dụ này, các bước chỉ giới hạn ở 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 của 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 bản dựng bị lỗi khi phát hiện thấy lỗ hổng bảo mật có mức độ nghiêm trọng LÀM HỎNG.

gcloud builds submit

Xem lại lỗi khi tạo

Bản dựng mà bạn vừa gửi sẽ không thành công vì 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 Nhật ký Cloud Build

Khắc phục lỗ hổng

Cập nhật Dockerfile để sử dụng một hình ảnh cơ sở không chứa các lỗ hổng NGHIÊM TRỌNG.

Ghi đè Dockerfile để 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 với 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 nào ở mức NGHIÊM TRỌNG.

gcloud builds submit

Xem lại kết quả của bản dựng

Bản dựng mà bạn vừa gửi sẽ thành công vì hình ảnh đã cập nhật không chứa lỗ hổng NGHIÊM TRỌNG.

Xem lại trạng thái thành công của bản dựng trên trang Nhật ký Cloud Build

Xem kết quả quét

Xem lại hình ảnh hợp lệ trong Artifact Registry

  1. Mở Artifact Registry trong Cloud Console
  2. Nhấp vào artifact-scanning-repo để xem nội dung
  3. Nhấp vào phần chi tiết hình ảnh
  4. Nhấp vào bản tóm tắt 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 cho 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ày!

Nội dung đã đề cập:

  • Tạo hình ảnh bằng Cloud Build
  • Artifact Registry cho các vùng chứa
  • Tự động quét lỗ hổng bảo mật
  • 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 bị tính phí vào tài khoản Google Cloud của bạn cho các tài nguyên được dùng trong hướng dẫn này, hãy xoá dự án chứa các tài nguyên đó hoặc giữ lại dự án rồi xoá từng tài nguyên.

Xoá dự án

Cách dễ nhất để loại bỏ phí 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/2023