Tích hợp Notary để ký mã hóa và xác thực nguồn gốc container image
1. Khởi động và cấu hình Notary Server trong Harbor
Harbor đã tích hợp sẵn Notary Server, nhưng cần kích hoạt trong file cấu hình chính để container Notary có thể chạy và giao tiếp với Harbor Core.
Mở file cấu hình của Harbor, thường nằm ở /etc/harbor/harbor.yml trên máy chủ Harbor.
Sửa phần notary để đặt trạng thái thành true và cấu hình thông tin chứng thư SSL cho Notary Server. Notary cần một chứng thư riêng biệt hoặc dùng chung với Harbor, ở đây ta dùng chứng thư tự ký (self-signed) được Harbor quản lý để đơn giản hóa quy trình.
notary:
enabled: true
notary_host: notary
notary_port: 4443
# Cấu hình chứng thư (Harbor tự động tạo nếu chưa có)
ca_secret: ca.pem
tls_secret: tls.pem
tls_key: tls.key
Khởi động lại Harbor để áp dụng thay đổi. Command này sẽ rebuild các container liên quan đến Notary.
docker-compose -f /opt/harbor/docker-compose.yml up -d notary-server notary-signer
Kết quả mong đợi: Hai container notary-server và notary-signer chuyển sang trạng thái Up. Log không báo lỗi về chứng thư SSL hoặc kết nối database.
2. Tạo Cặp Khóa (Key Pair) và Chứng thư cho tổ chức
Để ký image, bạn cần tạo một cặp khóa riêng (Private Key) và công khai (Public Key) cho tổ chức hoặc nhóm phát triển. Harbor cung cấp công cụ CLI harbor-cli hoặc dùng trực tiếp notary client.
Trước tiên, cần tạo một tổ chức (organization) trong Notary để quản lý các repository. Command này sẽ tạo một "root key" cho tổ chức my-org.
docker run --rm -e NOTARY_HOST=notary:4443 \
-v $(pwd):/notary \
-e NOTARY_GUN=my-org \
-e NOTARY_CA=/notary/ca.pem \
harbor/notary \
key generate root
Trong command trên, NOTARY_GUN là "Globally Unique Name" (tên tổ chức), định dạng domain/repo hoặc org-name. Bạn sẽ được yêu cầu nhập mật khẩu (Passphrase) cho private key. Hãy ghi lại mật khẩu này cẩn thận.
Sau khi tạo Root Key, bạn cần tạo một "Delegation Key" (tránh để Root Key bị lộ khi ký hàng ngày). Key này sẽ được dùng để ký các image cụ thể.
docker run --rm -e NOTARY_HOST=notary:4443 \
-v $(pwd):/notary \
-e NOTARY_GUN=my-org \
-e NOTARY_CA=/notary/ca.pem \
harbor/notary \
key generate delegation
Chọn tên key (ví dụ: signing-key) và nhập passphrase. Kết quả mong đợi: File cấu hình ~/.notary/ (hoặc thư mục mount) chứa các file root.key, root.pub, signing-key.key, signing-key.pub.
3. Cấu hình Workflow: Build, Sign, và Push Image
Quy trình chuẩn là: Build image -> Push lên Harbor -> Sign image trên Harbor. Việc ký phải diễn ra sau khi image đã tồn tại trên registry.
Đầu tiên, build và push image Docker thông thường vào Harbor.
docker build -t harbor.mycompany.com/my-org/my-app:v1.0 .
docker push harbor.mycompany.com/my-org/my-app:v1.0
Thực hiện ký image (Sign) sử dụng Notary Client. Command này sẽ tạo một chữ ký số gắn liền với tag v1.0 của image.
docker run --rm -e NOTARY_HOST=notary:4443 \
-e NOTARY_GUN=harbor.mycompany.com/my-org/my-app \
-e NOTARY_CA=/notary/ca.pem \
-v $(pwd):/notary \
harbor/notary \
sign v1.0
Trong quá trình chạy, Notary sẽ yêu cầu nhập passphrase của key bạn đã tạo ở bước 2. Đảm bảo NOTARY_GUN khớp chính xác với tên repository đã push (bao gồm cả namespace).
Kết quả mong đợi: Notary xuất thông báo Successfully signed .... Trong Harbor UI, khi vào chi tiết image, bạn sẽ thấy biểu tượng "Verified" hoặc "Signed" xuất hiện.
4. Xác minh chữ ký Notary khi Pull Image trên Cluster đích
Trên các cluster đích (Kubernetes/OpenShift), cần cấu hình để client chỉ pull image đã được ký. Có hai cách: dùng Docker daemon với Notary plugin hoặc cấu hình Kubernetes ImagePullSecrets với policy.
Để test thủ công, cấu hình Docker daemon để yêu cầu xác minh Notary khi pull. Sửa file /etc/docker/daemon.json trên node đích.
{
"registry-mirrors": [],
"insecure-registries": [],
"features": {
"buildKit": true
},
"notary": {
"enabled": true,
"host": "notary.mycompany.com:4443",
"tls": {
"ca_file": "/etc/docker/notary/ca.pem"
}
}
}
Copy file ca.pem của Notary Server sang /etc/docker/notary/ca.pem trên node đích và đặt quyền đọc cho root. Sau đó khởi động lại Docker.
cp /path/to/ca.pem /etc/docker/notary/ca.pem
chmod 644 /etc/docker/notary/ca.pem
systemctl restart docker
Thử pull image đã ký. Nếu image chưa ký, Docker sẽ báo lỗi manifest unknown hoặc signature verification failed (tùy version).
docker pull harbor.mycompany.com/my-org/my-app:v1.0
Kết quả mong đợi: Docker pull thành công và hiển thị thông báo xác thực: Verified signature for .... Nếu pull image chưa ký, quá trình sẽ bị từ chối ngay lập tức.
5. Quản lý vòng đời Key và xử lý khi Key bị lộ
Trong môi trường sản xuất, key có thể bị lộ hoặc hết hạn. Notary hỗ trợ cơ chế Rotate (xoay vòng) và Revoke (thu hồi).
Khi phát hiện key bị lộ (ví dụ: signing-key), bạn cần tạo một key mới và thu hồi key cũ ngay lập tức.
docker run --rm -e NOTARY_HOST=notary:4443 \
-e NOTARY_GUN=my-org \
-e NOTARY_CA=/notary/ca.pem \
-v $(pwd):/notary \
harbor/notary \
key generate delegation --key-name new-signing-key
Sau khi tạo key mới, dùng command revoke để đánh dấu key cũ là không hợp lệ. Notary sẽ cập nhật "trust bundle" để từ chối mọi chữ ký từ key cũ.
docker run --rm -e NOTARY_HOST=notary:4443 \
-e NOTARY_GUN=my-org \
-e NOTARY_CA=/notary/ca.pem \
-v $(pwd):/notary \
harbor/notary \
revoke signing-key
Trong command trên, signing-key là tên key bị lộ. Bạn sẽ được hỏi xác nhận. Sau khi revoke, bạn cần ký lại các image quan trọng bằng new-signing-key.
docker run --rm -e NOTARY_HOST=notary:4443 \
-e NOTARY_GUN=harbor.mycompany.com/my-org/my-app \
-e NOTARY_CA=/notary/ca.pem \
-v $(pwd):/notary \
harbor/notary \
sign v1.0
Khi ký lại, Notary sẽ thêm chữ ký mới vào bundle, đồng thời giữ nguyên trạng thái "revoked" của key cũ. Client pull sẽ chỉ chấp nhận chữ ký từ key mới.
Để kiểm tra trạng thái của các key trong Notary, dùng command trust.
docker run --rm -e NOTARY_HOST=notary:4443 \
-e NOTARY_GUN=harbor.mycompany.com/my-org/my-app \
-e NOTARY_CA=/notary/ca.pem \
harbor/notary \
trust list
Kết quả mong đợi: Danh sách các key hiển thị trạng thái valid hoặc revoked. Key bị lộ sẽ hiển thị trạng thái revoked.
Verify kết quả toàn bộ quy trình
Thực hiện kiểm tra cuối cùng bằng cách pull image từ một máy chủ mới (chưa có cache) để đảm bảo cơ chế xác thực hoạt động.
docker pull harbor.mycompany.com/my-org/my-app:v1.0
Quan sát output của Docker. Nếu thấy dòng Verified signature for ..., quy trình Notary đã tích hợp thành công. Nếu không thấy dòng này hoặc bị lỗi, hãy kiểm tra lại cấu hình daemon.json và chứng thư ca.pem trên node đích.
Điều hướng series:
Mục lục: Series: Series: Xây dựng nền tảng Secure Multi-Cloud Container Registry với Harbor, Notary và Policy Engine để kiểm soát phân phối artifact an toàn
« Phần 3: Cấu hình Harbor Multi-Cloud Replication để đồng bộ artifact an toàn
Phần 5: Triển khai Policy Engine (Trivy/Clair) để quét lỗ hổng bảo mật artifact »