Wprowadzenie
Podatna biblioteka w obrazie Docker to bomba z opóźnionym zapłonem. Może trafić na produkcję niezauważona i czekać miesiącami — do momentu gdy ktoś ją wykorzysta. Rozwiązaniem jest automatyczne skanowanie każdego obrazu przed deploymentem. Trivy robi to w ciągu kilkudziesięciu sekund i integruje się z każdym popularnym systemem CI/CD.
Co skanuje Trivy?
Trivy skanuje:
├── Obrazy Docker
│ ├── Podatności w pakietach systemowych (apt, rpm, apk)
│ ├── Podatności w bibliotekach aplikacyjnych (pip, npm, gem, go)
│ └── Sekrety i hasła zakodowane na stałe
├── Pliki konfiguracyjne Kubernetes
│ ├── Brak limitów zasobów
│ ├── Kontenery uruchamiane jako root
│ └── Privileged containers
└── Repozytoria Git
└── Sekrety w historii commitów
Integracja z GitLab CI
Podstawowa integracja — blokowanie pipeline’u
variables:
IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
stages:
- build
- security
- deploy
build-image:
stage: build
image: docker:24
services:
- docker:24-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE_NAME .
- docker push $IMAGE_NAME
trivy-scan:
stage: security
image:
name: aquasec/trivy:0.48.3
entrypoint: [""]
variables:
TRIVY_USERNAME: $CI_REGISTRY_USER
TRIVY_PASSWORD: $CI_REGISTRY_PASSWORD
TRIVY_AUTH_URL: $CI_REGISTRY
TRIVY_CACHE_DIR: .trivy-cache
cache:
paths:
- .trivy-cache/
script:
- trivy image
--exit-code 1
--severity CRITICAL,HIGH
--no-progress
$IMAGE_NAME
allow_failure: false
deploy-production:
stage: deploy
needs:
- trivy-scan
script:
- echo "Deploy tylko jeśli trivy-scan przeszedł"
Rozbudowana integracja z raportami
trivy-scan-full:
script:
- trivy image
--format template
--template "@/contrib/gitlab.tpl"
--output gl-container-scanning-report.json
$IMAGE_NAME
- trivy image
--format template
--template "@/contrib/html.tpl"
--output trivy-report.html
$IMAGE_NAME
artifacts:
when: always
reports:
container_scanning: gl-container-scanning-report.json
paths:
- trivy-report.html
Integracja z GitHub Actions
name: Security Scan
on:
push:
branches: [ main, develop ]
jobs:
trivy-scan:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Run Trivy vulnerability scan
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: sarif
output: trivy-results.sarif
severity: CRITICAL,HIGH
exit-code: 1
- name: Upload SARIF to GitHub Security
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: trivy-results.sarif
Wykrywanie sekretów
trivy fs --scanners secret .
# W pipeline:
trivy-secret-scan:
script:
- trivy fs --scanners secret --exit-code 1 --severity CRITICAL,HIGH .
Wyjątki — ignorowanie fałszywych alarmów
# .trivyignore
CVE-2023-12345 # false positive — biblioteka nie jest używana
CVE-2023-67890 # oczekuje na fix upstream
Polityka progów
| Severity | Akcja w pipeline |
|---|---|
| CRITICAL | Blokuj — brak deployu |
| HIGH | Blokuj (zalecane) |
| MEDIUM | Ostrzeżenie |
| LOW | Informacja w raportach |
Podsumowanie
Integracja Trivy z pipeline’em to jeden z najlepszych zwrotów z inwestycji w bezpieczeństwo — kilkanaście linii konfiguracji eliminuje całą klasę podatności. Kluczowe zasady:
- Skanuj każdy obraz przed deploymentem
- Blokuj pipeline na CRITICAL — zawsze
- Używaj cache bazy podatności — przyspiesza skany z ~2min do ~15s
- Integruj raporty z GitLab Security Dashboard lub GitHub Security