bởi Jorge Castillo, Joseph Rodríguez, và Monika Vu Minh | vào ngày 22 tháng 12 năm 2023 |
AWS Signer là một dịch vụ ký mã quản lý hoàn toàn để giúp đảm bảo sự tin cậy và tính toàn vẹn của mã của bạn. Nó giúp bạn xác minh rằng mã đến từ một nguồn đáng tin cậy và một bên không được ủy quyền đã không truy cập vào nó. AWS Signer quản lý các chứng chỉ ký mã và các khóa công khai và riêng tư, điều này có thể giảm bớt công việc quản lý cơ sở hạ tầng khóa công khai (PKI) của bạn. Nó cũng cung cấp một bộ tính năng để đơn giản hóa quản lý vòng đời của các khóa và chứng chỉ của bạn để bạn có thể tập trung vào việc ký và xác minh mã của mình.
Vào tháng 6 năm 2023, AWS đã công bố Container Image Signing với AWS Signer và Amazon EKS, một tính năng mới mang lại hỗ trợ AWS nguyên bản cho việc ký và xác minh hình ảnh container được lưu trữ trong Amazon Elastic Container Registry (Amazon ECR).
Containers và các chức năng AWS Lambda là các giải pháp tính toán không máy chủ phổ biến cho các ứng dụng được xây dựng trên đám mây. Bằng cách sử dụng AWS Signer, bạn có thể xác minh rằng phần mềm chạy trong các khối công việc này xuất phát từ một nguồn đáng tin cậy.
Trong bài đăng trên blog này, bạn sẽ tìm hiểu về các lợi ích của việc ký mã cho nhu cầu bảo mật, quản trị và tuân thủ phần mềm. Tích hợp liên tục và phát hành liên tục (CI/CD) linh hoạt, quản lý các danh tính ký và tích hợp nguyên bản với các dịch vụ AWS khác có thể giúp bạn đơn giản hóa bảo mật mã thông qua tự động hóa.
Nền tảng
Ký mã là một phần quan trọng của chuỗi cung ứng phần mềm. Nó giúp đảm bảo rằng mã không bị thay đổi và đến từ một nguồn được phê duyệt.
Để tự động hóa các luồng công việc phát triển phần mềm, các tổ chức thường triển khai một đường ống CI/CD để đẩy, kiểm tra và triển khai mã một cách hiệu quả. Bạn có thể tích hợp ký mã vào luồng công việc để giúp ngăn chặn mã không tin cậy được triển khai, như được hiển thị trong Hình 1. Việc ký mã trong đường ống có thể cung cấp cho bạn các loại thông tin khác nhau, tùy thuộc vào cách bạn quyết định sử dụng chức năng này. Ví dụ, bạn có thể tích hợp ký mã vào giai đoạn xây dựng để chứng thực rằng mã đã được quét để phát hiện lỗ hổng, SBOM phần mềm của nó đã được phê duyệt nội bộ và đã trải qua kiểm tra đơn vị và tích hợp. Bạn cũng có thể sử dụng ký mã để xác minh ai đã đẩy hoặc xuất bản mã, như một nhà phát triển, nhóm hoặc tổ chức. Bạn có thể xác minh từng bước này một cách riêng lẻ bằng cách bao gồm nhiều giai đoạn ký trong đường ống. Để biết thêm thông tin về giá trị mà việc ký hình ảnh container mang lại, xem Ký mã Mật mã cho Containers.
Hình 1: Bảo mật TRONG đường ống
Trong phần tiếp theo, chúng tôi sẽ hướng dẫn bạn thông qua một cách triển khai đơn giản của ký hình ảnh và việc xác minh nó cho việc triển khai Amazon Elastic Kubernetes Service (Amazon EKS). Chữ ký chứng nhận rằng hình ảnh container đã đi qua đường ống và đến từ một nguồn đáng tin cậy. Bạn có thể sử dụng quy trình này trong các tình huống phức tạp hơn bằng cách thêm nhiều giai đoạn ký mã CodeBuild của AWS sử dụng các hồ sơ ký mã Signer khác nhau.
Các Dịch Vụ và Công Cụ
Trong phần này, chúng tôi thảo luận về các dịch vụ AWS và công cụ bên thứ ba khác nhau mà bạn cần cho giải pháp này.
Các dịch vụ CI/CD
Đối với đường ống CI/CD, bạn sẽ sử dụng các dịch vụ AWS sau đây:
AWS CodePipeline — một dịch vụ giao hàng liên tục quản lý hoàn toàn mà bạn có thể sử dụng để tự động hóa các đường ống phát hành của mình để cập nhật ứng dụng và cơ sở hạ tầng một cách nhanh chóng và đáng tin cậy.
AWS CodeCommit — một dịch vụ kiểm soát nguồn quản lý hoàn toàn mà lưu trữ các kho chứa dựa trên Git một cách an toàn.
AWS Signer — một dịch vụ ký mã quản lý hoàn toàn mà bạn có thể sử dụng để giúp đảm bảo sự tin cậy và tính toàn vẹn của mã của bạn.
AWS CodeBuild — Một dịch vụ tích hợp liên tục quản lý hoàn toàn mà biên dịch mã nguồn, chạy các bài kiểm tra, và tạo ra các gói phần mềm đã sẵn sàng triển khai.
Các dịch vụ container
Bạn sẽ sử dụng các dịch vụ AWS sau đây cho containers trong quá trình này:
Amazon EKS — một dịch vụ quản lý Kubernetes để chạy Kubernetes trong Đám Mây AWS và trong các trung tâm dữ liệu trên toàn cầu.
Amazon ECR — một kho chứa container quản lý hoàn toàn để lưu trữ đồng bộ cao, để bạn có thể triển khai hình ảnh và tài liệu ứng dụng một cách đáng tin cậy ở mọi nơi.
Công cụ xác minh
Dưới đây là các công cụ xác minh ký hiệu công cộng có sẵn mà chúng tôi đã tích hợp vào đường ống cho bài đăng này, nhưng bạn có thể tích hợp các công cụ khác phù hợp với yêu cầu cụ thể của bạn.
Notation — Một dự án Notary công cộng có sẵn trong Cloud Native Computing Foundation (CNCF). Với sự đóng góp từ AWS và những người khác, Notary là một tiêu chuẩn mở và triển khai khách hàng cho phép các plugin cụ thể của nhà cung cấp cho quản lý khóa và các tích hợp khác. AWS Signer quản lý các khóa ký, xoay khóa và quản lý PKI cho bạn, và được tích hợp với Notation thông qua một plugin được chọn lọc cung cấp một luồng làm việc dựa trên khách hàng đơn giản.
Kyverno — Một công cụ động cơ chính sách công cộng có sẵn được thiết kế cho Kubernetes.
Tổng Quan về Giải Pháp
Hình 2: Kiến trúc giải pháp
Dưới đây là cách giải pháp hoạt động, như được hiển thị trong Hình 2:
- Các nhà phát triển đẩy Dockerfiles và mã ứng dụng lên CodeCommit. Mỗi lần đẩy đến CodeCommit sẽ khởi chạy một đường ống được lưu trữ trên CodePipeline.
- CodeBuild đóng gói quá trình xây dựng, tạo hình ảnh container cho ứng dụng và lưu trữ hình ảnh trong kho ECR.
- CodeBuild truy xuất một phiên bản cụ thể của hình ảnh đã được đẩy trước đó lên Amazon ECR. AWS Signer và Notation ký mã hình ảnh bằng cách sử dụng hồ sơ ký đã được thiết lập trước đó, như được mô tả chi tiết trong Hình 3.
Hình 3: Mô tả việc ký hình ảnh
- AWS Signer và Notation xác minh phiên bản hình ảnh đã được ký và sau đó triển khai nó lên một cụm Amazon EKS.
Nếu hình ảnh chưa được ký đúng cách trước đó, nhật ký CodeBuild sẽ hiển thị một đầu ra tương tự như sau:
Error: signature verification failed: no signature is associated with “<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/hello-server@<DIGEST>” , make sure the artifact was signed successfully
Nếu có sự không khớp chữ ký, nhật ký của CodeBuild sẽ hiển thị một đầu ra tương tự như sau:
Error: signature verification failed for all the signatures associated with <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/hello-server@<DIGEST>
Kyverno xác minh chữ ký của hình ảnh container để sử dụng trong cụm Amazon EKS.
Hình 4 hiển thị các bước 4 và 5 chi tiết hơn.
Hình 4: Xác minh chữ ký của hình ảnh cho Kubernetes
Yêu cầu
Trước khi bắt đầu, đảm bảo rằng bạn có các yêu cầu tiên quyết sau:
- Một cụm Amazon EKS được cung cấp.
- Một kho ECR Amazon cho các hình ảnh container của bạn.
- Một kho CodeCommit với mã ứng dụng của bạn. Để biết thêm thông tin, xem Tạo một kho AWS CodeCommit.
- Một đường ống CodePipeline triển khai với kho CodeCommit làm nguồn mã và bốn giai đoạn CodeBuild: Xây dựng, ApplicationSigning, ApplicationDeployment, và VerifyContainerSign. Đường ống CI/CD nên trông giống như trong Hình 5.
Hình 5: Đường ống CI/CD với CodePipeline
Hướng dẫn
Bạn có thể tạo một hồ sơ ký bằng cách sử dụng Giao diện Dòng Lệnh AWS (AWS CLI), Bảng điều khiển Quản lý AWS hoặc API AWS Signer. Trong phần này, chúng tôi sẽ hướng dẫn bạn cách ký hình ảnh bằng cách sử dụng AWS CLI.
Để ký hình ảnh (AWS CLI)
Tạo một hồ sơ ký cho mỗi danh tính
# Create an AWS Signer signing profile with default validity period
$ aws signer put-signing-profile \
–profile-name build_signer \
–platform-id Notation-OCI-SHA384-ECDSA
To sign the image from the CodeBuild build, your buildspec.yaml configuration file should include the following steps:
version: 0.2
phases:
pre_build:
commands:
– aws ecr get-login-password –region $AWS_REGION | docker login –username AWS –password-stdin $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com
– REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr. $AWS_REGION.amazonaws.com/hello-server
– COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
– IMAGE_TAG=${COMMIT_HASH:=latest}
– DIGEST=$(docker manifest inspect $AWS_ACCOUNT_ID.dkr.ecr. $AWS_REGION.amazonaws.com/hello-server:$IMAGE_TAG -v | jq -r ‘.Descriptor.digest’)
– echo $DIGEST
– sudo rpm -U aws-signer-notation-cli_amd64.rpm
– notation version
– notation plugin ls
build:
commands:
– notation sign $REPOSITORY_URI@$DIGEST –plugin com.amazonaws.signer.notation.plugin –id arn:aws:signer: $AWS_REGION:$AWS_ACCOUNT_ID:/signing-profiles/notation_container_signing
– notation inspect $AWS_ACCOUNT_ID.dkr.ecr. $AWS_REGION.amazonaws.com/hello-server@$DIGEST
– notation verify $AWS_ACCOUNT_ID.dkr.ecr. $AWS_REGION.amazonaws.com/hello-server@$DIGEST
post_build:
commands:
– printf ‘[{“name”:”hello-server”,”imageUri”:”%s”}]’ $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json
- Các lệnh trong tệp cấu hình buildspec.yaml thực hiện các hành động sau:
- Đăng nhập vào Amazon ECR để làm việc với các hình ảnh Docker.
- Tham chiếu đến hình ảnh cụ thể sẽ được ký bằng cách sử dụng mã hash commit (hoặc một chiến lược phiên bản khác mà tổ chức của bạn sử dụng). Điều này nhận được bản tóm tắt (digest).
- Ký hình ảnh container bằng cách sử dụng lệnh notation sign. Lệnh này sử dụng bản tóm tắt hình ảnh container, thay vì thẻ hình ảnh.
- Cài đặt Notation CLI. Trong ví dụ này, bạn sử dụng trình cài đặt cho Linux. Để biết danh sách các trình cài đặt cho các hệ điều hành khác nhau, xem Hướng dẫn Phát triển AWS Signer,
- Ký hình ảnh bằng cách sử dụng lệnh notation sign.
- Kiểm tra hình ảnh đã ký để đảm bảo rằng nó đã được ký thành công bằng cách sử dụng lệnh notation inspect.
- Để xác minh hình ảnh đã ký, sử dụng lệnh notation verify. Đầu ra sẽ giống như sau:
- Kết quả sẽ giống như sau: <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/hello-server@<DIGEST>
(Thông Tin Tùy Chọn) Để sửa chữa sự cố, in ra chính sách notation từ chính đường ống để kiểm tra xem nó hoạt động như mong đợi bằng cách chạy lệnh notation policy show:
notation policy show
Để thực hiện điều này, bạn có thể thêm lệnh trong giai đoạn pre_build sau lệnh notation version trong tệp cấu hình buildspec.yaml. Sau khi lệnh notation policy show chạy, nhật ký của CodeBuild sẽ hiển thị một đầu ra tương tự như sau:
{
“version”: “1.0”,
“trustPolicies”: [
{
“name”: “aws-signer-tp”,
“registryScopes”: [
“<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/hello-server”
],
“signatureVerification”: {
“level”: “strict”
},
“trustStores”: [
“signingAuthority:aws-signer-ts”
],
“trustedIdentities”: [
“arn:aws:signer:<AWS_REGION>:<AWS_ACCOUNT_ID>:/signing-profiles/notation_test”
]
}
]
}
Để xác minh hình ảnh trong Kubernetes, thiết lập cả Kyverno và Kyverno-notation-AWS Signer trong cụm EKS của bạn. Để bắt đầu với giải pháp Kyverno và Kyverno-notation-AWS Signer, hãy xem hướng dẫn cài đặt.
Sau khi bạn cài đặt Kyverno và Kyverno-notation-AWS Signer, hãy xác minh rằng bộ điều khiển đang chạy – STATUS nên hiển thị Running:
$ kubectl get pods -n kyverno-notation-aws -w
NAME READY STATUS RESTARTS AGE
kyverno-notation-aws-75b7ddbcfc-kxwjh 1/1 Running 0 6h58m
Cấu hình tệp cấu hình buildspec.yaml của CodeBuild để xác minh rằng các hình ảnh triển khai trong cụm đã được ký trước đó. Bạn có thể sử dụng mã sau để cấu hình tệp buildspec.yaml.
version: 0.2
phases:
pre_build:
commands:
– echo Logging in to Amazon ECR…
– aws –version
– REPOSITORY_URI=${REPO_ECR}
– COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
– IMAGE_TAG=${COMMIT_HASH:=latest}
– curl -LO “https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl”
– curl -LO “https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256”
– echo “$(cat kubectl.sha256) kubectl” | sha256sum –check
— chmod +x kubectl
– mv ./kubectl /usr/local/bin/kubectl
– kubectl version –client
build:
commands:
– echo Build started on `date`
– aws eks update-kubeconfig -—name ${EKS_NAME} —-region ${AWS_DEFAULT_REGION}
– echo Deploying Application
– sed -i ‘/image:\ image/image:\ ‘\”${REPOSITORY_URI}:${IMAGE_TAG}\”‘/g’ deployment.yaml
– kubectl apply -f deployment.yaml
– KYVERNO_NOTATION_POD=$(kubectl get pods –no-headers -o custom-columns=”:metadata.name” -n kyverno-notation-aws)
– STATUS=$(kubectl logs –tail=1 kyverno-notation-aws-75b7ddbcfc-kxwjh -n kyverno-notation-aws | grep $IMAGE_TAG | grep ERROR)
– |
if [[ $STATUS ]]; then
echo “There is an error”
exit 1
else
echo “No Error”
fi
post_build:
commands:
– printf ‘[{“name”:”hello-server”,”imageUri”:”%s”}]’ $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json
- Các lệnh trong tệp cấu hình buildspec.yaml thực hiện các công việc sau:
- Thiết lập các biến môi trường, như URI kho ECR và mã hash Commit, để xây dựng thẻ hình ảnh. Công cụ kubectl sẽ sử dụng điều này sau để tham chiếu đến hình ảnh container sẽ được triển khai với các đối tượng Kubernetes.
- Sử dụng kubectl để kết nối với cụm EKS và chèn tham chiếu hình ảnh container vào tệp deployment.yaml.
- Sau khi container được triển khai, bạn có thể quan sát bộ điều khiển kyverno-notation-aws và truy cập vào nhật ký của nó. Bạn có thể kiểm tra xem hình ảnh được triển khai đã được ký chưa. Nếu nhật ký chứa một lỗi, dừng quá trình chạy của đường ống với một mã lỗi, thực hiện cuộc quay lại đến một phiên bản trước đó hoặc xóa triển khai nếu bạn phát hiện ra rằng hình ảnh không được ký.
Vô hiệu hóa các tài nguyên AWS
Nếu bạn không còn cần các tài nguyên mà bạn đã cung cấp cho bài viết này, thực hiện các bước sau để xóa chúng.
Để dọn dẹp các tài nguyên
- Xóa cụm EKS và xóa hình ảnh ECR.
- Xóa các vai trò IAM và các chính sách mà bạn đã sử dụng cho cấu hình các vai trò IAM cho các tài khoản dịch vụ.
- Thu hồi hồ sơ ký AWS Signer mà bạn đã tạo và sử dụng cho quy trình ký bằng cách chạy lệnh sau trong AWS CLI:
$ aws signer revoke-signing-profile
- Xóa các chữ ký từ kho ECR Amazon. Đảm bảo thay thế <AWS_ACCOUNT_ID> và <AWS_REGION> bằng thông tin của bạn.
# Use oras CLI, with Amazon ECR Docker Credential Helper, to delete signature
- $ oras manifest delete <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/pause@sha256:ca78e5f730f9a789ef8c63bb55275ac12dfb9e8099e6a0a64375d8a95ed501c4
Lưu ý: Sử dụng ứng dụng oras của dự án ORAS, bạn có thể xóa các chữ ký và các loại tài nguyên tham chiếu khác. Nó thực hiện việc xóa bằng cách trước tiên loại bỏ tham chiếu từ một chỉ mục, và sau đó xóa bản vật.
Kết luận
Trong bài viết này, bạn đã học cách triển khai việc ký hình ảnh container trong một đường ống CI/CD bằng cách sử dụng các dịch vụ AWS như CodePipeline, CodeBuild, Amazon ECR và AWS Signer cùng với các công cụ công khai như Notary và Kyverno. Bằng cách triển khai việc ký hình ảnh bắt buộc trong các đường ống của bạn, bạn có thể xác nhận rằng chỉ các hình ảnh container đã được xác minh và được ủy quyền mới được triển khai vào sản xuất. Tự động hóa quy trình ký và xác minh chữ ký là rất quan trọng để giúp triển khai các container một cách an toàn ở quy mô lớn. Bạn cũng đã học cách xác minh hình ảnh đã ký cả trong quá trình triển khai và khi chạy trong Kubernetes. Bài viết này cung cấp thông tin quý giá cho bất kỳ ai muốn thêm khả năng ký hình ảnh vào các đường ống CI/CD của mình trên AWS để đảm bảo an ninh chuỗi cung ứng. Sự kết hợp giữa các dịch vụ được quản lý bởi AWS và các công cụ công khai cung cấp một cài đặt mạnh mẽ.
Về tác giả
Jorge Castillo
Jorge là Kiến trúc sư giải pháp tại AWS cho khu vực công có trụ sở tại Santiago, Chile. Ông tập trung vào bảo mật và tuân thủ và làm việc với nhiều cơ quan chính phủ.
Joseph Rodríguez
Joseph là Kiến trúc sư giải pháp tại AWS cho khu vực công có trụ sở tại Chile. Joseph đã cộng tác với nhiều tổ chức khu vực công về việc áp dụng công nghệ đám mây, tập trung vào vùng chứa. Trước đây ông từng làm Kiến trúc sư phần mềm tại các tổ chức dịch vụ tài chính.
Monika Vũ Minh
Monika là Chuyên gia tư vấn bảo mật ProServe tại AWS có trụ sở tại London. Cô làm việc với các khách hàng sử dụng dịch vụ tài chính để giúp họ tuân theo các biện pháp bảo mật tốt nhất trên AWS. Khi rảnh rỗi, cô thích vẽ tranh, nấu ăn và đi du lịch.