Bảo mật Container trước khi đưa lên môi trường Production
Hầu hết các lập trình viên coi Docker image như những “chiếc hộp đen”. Bạn chọn một base image, cài đặt các phụ thuộc (dependencies) và đẩy nó lên registry. Tuy nhiên, base image đó có thể chứa hàng trăm lỗ hổng bảo mật đã biết (CVE) ngay cả trước khi bạn viết dòng code đầu tiên. Nếu một trong những lỗ hổng đó cho phép thực thi mã từ xa (RCE), ứng dụng của bạn sẽ gặp nguy hiểm ngay từ thời điểm nó bắt đầu hoạt động.
Sau khi máy chủ của tôi bị tấn công brute-force qua SSH vào lúc nửa đêm, tôi luôn ưu tiên vấn đề bảo mật ngay từ khi thiết lập ban đầu. Trải nghiệm đó đã dạy tôi rằng tin tặc không đợi bạn sẵn sàng; chúng tìm kiếm bất kỳ cánh cửa nào đang mở. Một thư viện có lỗ hổng bên trong container Docker chính là loại cửa mà chúng yêu thích. Đây là lúc Trivy phát huy tác dụng—nó đóng vai trò như một người gác cổng, đảm bảo rằng chỉ những image “sạch” mới được đưa vào môi trường production của bạn.
So sánh các phương pháp quét Image
Có nhiều cách để xử lý bảo mật container. Việc chọn đúng phương pháp phụ thuộc vào quy trình làm việc và mức độ kiểm soát mà bạn cần.
1. Quét thủ công
Cách này bao gồm việc chạy quét trên máy cục bộ trước khi đẩy image lên. Mặc dù có còn hơn không, nhưng nó phụ thuộc vào trí nhớ của con người. Nếu lập trình viên quên quét, một image có lỗ hổng sẽ lọt qua.
2. Quét phía Registry
Các nền tảng như Docker Hub, AWS ECR hoặc GitHub Container Registry thường có trình quét tích hợp sẵn. Những công cụ này rất tuyệt vì chúng chạy tự động, nhưng chúng lại diễn ra sau khi image đã được đẩy lên. Nếu phát hiện lỗ hổng, bạn phải quay lại, sửa lỗi và đẩy lại một lần nữa.
3. Quét trong Pipeline CI/CD (Phương pháp Shift-Left)
Đây là phương pháp hiệu quả nhất. Bằng cách tích hợp một công cụ như Trivy trực tiếp vào pipeline CI/CD, quá trình build sẽ thất bại nếu image chứa các lỗ hổng nghiêm trọng. Bạn sẽ phát hiện ra vấn đề trước khi image rời khỏi build server. Điều này “dịch chuyển” (shift) bảo mật sang bên trái (sớm hơn trong quá trình phát triển).
Ưu và nhược điểm khi sử dụng Trivy
Trivy đã nhanh chóng trở thành tiêu chuẩn trong ngành về quét lỗ hổng mã nguồn mở. Dưới đây là lý do tại sao nó nổi bật, cùng với một vài đánh đổi.
Ưu điểm
- Nhanh và nhẹ: Trivy không yêu cầu daemon chạy ngầm nặng nề hay thiết lập cơ sở dữ liệu phức tạp. Nó tải về một database metadata nhỏ trong lần chạy đầu tiên và cập nhật liên tục sau đó.
- Toàn diện: Nó không chỉ quét các gói hệ điều hành (như apt hoặc yum); nó còn quét các phụ thuộc của từng ngôn ngữ (Python, Node.js, Go, v.v.) và thậm chí kiểm tra cả lỗi cấu hình trong Dockerfiles.
- Dễ dàng tích hợp: Vì nó là một file thực thi duy nhất (single binary), bạn có thể chạy nó trong bất kỳ môi trường Linux nào, bao gồm GitHub Actions, GitLab CI và Jenkins.
- Không yêu cầu tài khoản: Không giống như một số công cụ thương mại, bạn không cần đăng ký hoặc cung cấp API key để bắt đầu quét.
Nhược điểm
- Cảnh báo sai (False Positives): Giống như bất kỳ trình quét nào, Trivy thỉnh thoảng có thể đánh dấu một lỗ hổng thực tế không ảnh hưởng đến cấu hình cụ thể của bạn. Bạn cần học cách sử dụng file
.trivyignoređể quản lý chúng. - Tiêu tốn tài nguyên: Quét các image rất lớn với hàng ngàn phụ thuộc có thể gây tốn CPU cho các CI runner cấu hình thấp.
Thiết lập khuyến nghị cho lập trình viên mới
Nếu bạn mới bắt đầu, thiết lập tốt nhất là sử dụng Trivy tại máy cục bộ để kiểm tra và sau đó thêm một GitHub Action đơn giản vào repository của mình. Điều này đảm bảo rằng mọi Pull Request đều được kiểm tra lỗi bảo mật trước khi được merge.
Đối với máy cục bộ, bạn có thể cài đặt Trivy bằng một script đơn giản hoặc trình quản lý gói. Trên Ubuntu/Debian, các bước như sau:
sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/dabest/public.key | sudo apt-key add -
echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy
Hướng dẫn triển khai từng bước
Bước 1: Chạy quét lần đầu trên máy cục bộ
Chọn một image bạn thường xuyên sử dụng. Ví dụ, hãy xem xét image Python chính thức. Chạy lệnh sau in terminal của bạn:
trivy image python:3.9-slim
Trivy sẽ xuất ra một bảng hiển thị Thư viện (Library), mã CVE, Mức độ nghiêm trọng (Low, Medium, High, Critical) và liệu đã có bản vá hay chưa. Việc nhìn thấy một danh sách dài các lỗ hổng “Critical” trong một base image tiêu chuẩn thường là lời cảnh tỉnh cho hầu hết các lập trình viên.
Bước 2: Lọc kết quả
Thông thường bạn không muốn xem các lỗ hổng mức “Low” hoặc “Medium” khi kiểm tra nhanh. Bạn có thể lọc đầu ra để chỉ tập trung vào những gì quan trọng:
trivy image --severity HIGH,CRITICAL python:3.9-slim
Nếu bạn chỉ muốn xem các lỗ hổng thực sự đã có bản vá (để không lãng phí thời gian vào những vấn đề chưa thể sửa được), hãy sử dụng lệnh này:
trivy image --ignore-unfixed --severity HIGH,CRITICAL python:3.9-slim
Bước 3: Tích hợp vào GitHub Actions
Đây là lúc điều kỳ diệu xảy ra. Chúng ta muốn pipeline CI của mình bị dừng lại nếu phát hiện lỗ hổng nghiêm trọng. Hãy tạo một file tại .github/workflows/security.yml trong project của bạn:
name: Quét bảo mật
on: [push, pull_request]
jobs:
trivy-scan:
runs-on: ubuntu-latest
steps:
- name: Kiểm tra mã nguồn (Checkout code)
uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t my-app:${{ github.sha }} .
- name: Chạy trình quét lỗ hổng Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: 'my-app:${{ github.sha }}'
format: 'table'
exit-code: '1' # Lệnh này làm build thất bại nếu tìm thấy lỗ hổng
ignore-unfixed: true
severity: 'CRITICAL,HIGH'
Trong cấu hình này, exit-code: '1' là phần quan trọng nhất. Nó báo cho CI runner rằng nếu Trivy tìm thấy lỗ hổng HIGH hoặc CRITICAL, nó nên trả về trạng thái thất bại. Điều này làm dừng pipeline, ngăn không cho image được triển khai lên production.
Bước 4: Xử lý cảnh báo sai với .trivyignore
Đôi khi bạn có thể gặp một lỗ hổng mà bạn biết chắc chắn không thể bị khai thác trong môi trường của mình. Thay vì bỏ qua tất cả cảnh báo, hãy tạo một file .trivyignore ở thư mục gốc và thêm các mã CVE bạn muốn bỏ qua:
# Bỏ qua CVE cụ thể không ảnh hưởng đến ứng dụng của chúng tôi
CVE-2023-12345
# Bỏ qua một mã khác đã có cách xử lý tạm thời
CVE-2024-99999
Trivy sẽ bỏ qua những mã này trong quá trình quét, giúp pipeline CI của bạn vẫn ở trạng thái “xanh” trong khi vẫn bảo vệ bạn khỏi những mối đe dọa khác.
Lời kết
Thiết lập Trivy tốn chưa đầy 15 phút, nhưng nó có thể cứu bạn khỏi một vụ vi phạm bảo mật thảm khốc. Kể từ khi bắt đầu sử dụng, tôi đã phát hiện ra hàng chục base image lỗi thời mà trước đây tôi cứ ngỡ là an toàn. Bảo mật không phải là công việc làm một lần; đó là một thói quen. Bằng cách đưa việc quét lỗ hổng vào quy trình tự động, bạn đảm bảo rằng môi trường production của mình luôn là một pháo đài vững chắc, ngay cả khi bạn đang ngủ.

