Khởi động nhanh (5 phút): Khởi tạo một instance Harbor chuẩn bảo mật
Các base image chưa được kiểm soát rất dễ lọt vào private registry. Việc đẩy thẳng các bản build chưa qua kiểm định lên một registry không được giám sát sẽ biến cụm cluster của bạn thành mục tiêu béo bở cho các lỗ hổng đã biết.
Harbor sẽ chặn đứng rủi ro này. Harbor bổ sung cho kho lưu trữ OCI registry tiêu chuẩn hệ thống phân quyền chi tiết, cơ chế quét bảo mật Trivy tự động và tính năng ký image tích hợp sẵn. Bạn có thể dựng một instance cục bộ hoàn chỉnh chỉ trong chưa đầy năm phút với Docker Compose.
# Tải bộ cài đặt offline của Harbor
wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz
tar xzvf harbor-offline-installer-v2.10.0.tgz
cd harbor
# Cấu hình các tham số
cp harbor.yml.tmpl harbor.yml
Mở file harbor.yml và chỉnh sửa hostname cùng thông tin đăng nhập ban đầu:
hostname: registry.internal.lan
http:
port: 80
# Với TLS production, hãy bỏ comment khối https và cung cấp đường dẫn cert
harbor_admin_password: "ThayDoi_MatKhau_PhucTap!"
Mỗi khi cấu hình mật khẩu admin hoặc thông tin đăng nhập cơ sở dữ liệu trên máy chủ mới, tôi luôn tránh dùng mật khẩu mặc định yếu và hạn chế nguy cơ lộ mật khẩu qua lịch sử bash. Một công cụ tạo mật khẩu phía client như toolcraft.app/vi/tools/security/password-generator sẽ sinh ra các chuỗi có độ ngẫu nhiên cao (entropy cao) trực tiếp ngay trên trình duyệt. Tuyệt đối không có secret nào bị gửi ra khỏi máy trạm của bạn. Hãy lưu mật khẩu vừa tạo vào trình quản lý mật khẩu, sau đó chạy script cài đặt có kích hoạt bộ quét Trivy:
sudo ./install.sh --with-trivy
Kiểm tra xem các container đã hoạt động hay chưa:
docker compose ps
Đăng nhập vào registry từ giao diện dòng lệnh:
docker login registry.internal.lan -u admin
Phân tích chuyên sâu: Các lỗ hổng Registry và nguyên nhân gốc rễ
Vấn đề: Sự tin tưởng mù quáng vào các Base Image từ upstream
Phần lớn các vấn đề bảo mật registry bắt nguồn từ việc đặt niềm tin sai chỗ. Lập trình viên pull python:3.11-slim hoặc node:20-alpine, đóng gói thêm mã nguồn của công ty rồi push bản build lên. Ba tuần sau, một lỗ hổng glibc hoặc OpenSSL từ thượng nguồn (upstream) bị phát hiện, chẳng hạn như CVE-2023-4863 trong libwebp. Giờ đây, cluster của bạn đang chạy các binary chứa lỗ hổng mà chẳng một ai hay biết.
Nguyên nhân gốc rễ: Quét tĩnh và Artifact có thể bị ghi đè
Hai điểm mù lớn khiến các image chứa lỗ hổng lọt vào môi trường production gồm:
- Quét tại một thời điểm cố định trong pipeline: Việc chỉ quét image trong quá trình chạy CI tạo ra cảm giác an toàn ảo. Nếu một image nằm trong kho lưu trữ 20 ngày trước khi được triển khai, nó sẽ bỏ lọt mọi CVE mới được công bố sau thời điểm build.
- Tag có thể thay đổi và nguồn gốc không được xác thực: Các floating tag như
:latesthay:v1.2có thể bị ghi đè bởi bất kỳ ai có quyền push. Nếu không có bước kiểm tra chữ ký, kẻ tấn công hoặc một script pipeline lỗi có thể ghi đè các layer chứa mã độc lên image đáng tin cậy.
Giải pháp: Cơ chế phòng thủ ba lớp của Harbor
Harbor thiết lập chốt chặn Zero Trust tự động thông qua ba cơ chế liên kết chặt chẽ:
- Quét nền liên tục: Trivy quét các lượt push mới ngay lập tức, đồng thời quét lại các image đang lưu trữ theo lịch cron định kỳ hàng đêm.
- Xác thực mật mã học với Cosign: Sigstore Cosign xác nhận rằng image bắt nguồn từ các CI runner được cấp quyền và không hề bị chỉnh sửa.
- Kiểm soát truy cập trước khi Pull (Pre-Pull Admission Controls): Harbor từ chối các yêu cầu pull image bất cứ khi nào số lượng hoặc mức độ lỗ hổng vượt quá ngưỡng nghiêm trọng đã định.
Sử dụng nâng cao: Quét tự động, ký Cosign và chặn Pull
1. Bật tính năng Scan-on-Push và lên lịch quét định kỳ
Việc quét thủ công rất dễ bị quên do phụ thuộc vào con người. Thay vào đó, hãy áp dụng quy trình kiểm tra lỗ hổng tự động ở cấp độ project:
- Đăng nhập vào giao diện console của Harbor.
- Vào mục Projects → Chọn project của bạn (ví dụ:
backend-services) → Configuration. - Tích chọn Automatically scan images on push.
- Tại mục Vulnerability, tích chọn Prevent vulnerable images from running và chọn ngưỡng là High hoặc Critical.
Để kịp thời phát hiện các CVE mới công bố trên những image hiện có, hãy vào Administration → Interrogation Services → Vulnerability. Thiết lập lịch quét lại vào 2:00 AM UTC mỗi đêm:
0 0 2 * * *
2. Ký Image bằng Cosign
Tag có thể bị ghi đè, nhưng chữ ký số thì không. Cosign cho phép ký các OCI artifact trực tiếp trên Harbor mà không cần dựng riêng một máy chủ Notary.
# Cài đặt Cosign
curl -O -L "https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64"
sudo mv cosign-linux-amd64 /usr/local/bin/cosign
sudo chmod +x /usr/local/bin/cosign
# Tạo cặp khóa cho CI pipeline runner
cosign generate-key-pair
Lưu trữ cosign.key trong kho lưu trữ secret của hệ thống CI (chẳng hạn như HashiCorp Vault hoặc GitHub Secrets). Sau khi push image, hãy ký ngay vào digest của image đó:
# Build và push image
docker build -t registry.internal.lan/backend-services/api:1.0.4 .
docker push registry.internal.lan/backend-services/api:1.0.4
# Ký image
COSIGN_PASSWORD="mat-khau-private-key-cua-ban" cosign sign \
--key cosign.key \
registry.internal.lan/backend-services/api:1.0.4
Cosign sẽ đẩy artifact chứa chữ ký trực tiếp lên Harbor. Harbor sẽ tự động nhận diện và hiển thị huy hiệu xác minh (verified badge) màu xanh lá cạnh digest của image.
3. Bắt buộc Content Trust trong Harbor
Trong phần cài đặt project của Harbor, mở thẻ Configuration và tích chọn Only allow signed images to be pulled. Bất kỳ nỗ lực tải xuống một image chưa được ký nào đều sẽ bị chặn ngay tại tầng registry:
$ docker pull registry.internal.lan/backend-services/api:unsigned-test
Error response from daemon: unknown: Image chưa được ký bởi Cosign hoặc Notary và không thể pull.
4. Thực thi kiểm tra chữ ký trong Kubernetes bằng Kyverno
Cơ chế chặn ở tầng registry bảo vệ các endpoint của bạn, nhưng chính admission controller mới là thành phần đảm bảo sự tuân thủ bên trong cụm cluster. Bạn có thể kết hợp Harbor với Kyverno để từ chối các Pod chưa được ký trước khi chúng được schedule:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signature
spec:
validationFailureAction: Enforce
rules:
- name: verify-cosign
match:
resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "registry.internal.lan/backend-services/*"
key: |-
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7p+YV6bEx...
-----END PUBLIC KEY-----
Kinh nghiệm thực chiến khi vận hành Harbor trong môi trường Production
- Khóa chặt các SemVer Tag: Bật Tag Immutability Rules trong phần cài đặt project. Áp dụng biểu thức regex như
v[0-9]+\.[0-9]+\.[0-9]+để ngăn script pipeline hoặc sơ suất của con người ghi đè lên các bản release đã phát hành. - Dọn dẹp các Blob mồ côi hàng tuần: CI runner tạo ra hàng chục layer không được gắn tag trong mỗi sprint. Một team gồm 30 lập trình viên có thể dễ dàng tạo ra tới 250 GB layer image mồ côi mỗi tháng. Hãy lên lịch dọn rác (garbage collection) trong Administration → Clean Up, và nhớ chạy thử nghiệm với Dry Run trước.
- Phân tách Robot Account: Tuyệt đối không chia sẻ thông tin đăng nhập quản trị viên với hệ thống CI/CD. Hãy tạo các Robot Account riêng biệt với quyền hạn được giới hạn rõ ràng—cấp quyền
Push/Pullcho CI builder, và chỉ cấp quyền chỉ đọcPullcho image pull secret của cụm Kubernetes. - Sử dụng CVE Allowlist có thời hạn: Các cảnh báo zero-day như CVE-2023-38545 trong curl đôi khi chưa có bản vá ngay từ phía nhà cung cấp upstream. Đừng vội tắt chốt chặn kiểm soát triển khai. Hãy thêm mã CVE cụ thể đó vào CVE Allowlist ở cấp project với thời hạn hết hạn 14 ngày để không làm gián đoạn tiến độ release trong lúc chờ bản vá.
