Trivy'yi GitLab CI'de kullanmaya başladım, bir güvenlik denetimi container pipeline'ımızdaki eksik SBOM'ları işaretledikten sonra. Hedefim basitti: kritik CVE'ler görünürse derlemeyi başarısız yap ve uyumluluk için makine-okunabilir SBOM üret. Trivy her iki işi de iyi yapıyor ve bayrakları öğrendikten sonra .gitlab-ci.yml'ye entegrasyonu bir saatten kısa sürdü.
Trivy'yi diğer tarayıcılardan tercih etme nedenim
Trivy'ye karar vermeden önce Aqua, Clair ve Grype'i değerlendirdim. Hafif, çalışan bir daemon gerektirmiyor ve varsayılan olarak temiz JSON çıktısı üretiyor. SBOM üretimi için CycloneDX formatı geniş kabul görüyor ve Trivy bu formatı tek bir geçişte güvenlik verileriyle birlikte üretebiliyor. Ortamımda her birleştirme isteği ve ana dal görüntüleri için zamanlanmış gece pipeline'larında taramalar yapıyoruz.
Temel .gitlab-ci.yml kurulumu
İşte kullandığım temel iş. Trivy görüntüsünü çeker, oluşturulan container'ı tarar ve hem SBOM'u hem de güvenlik raporunu manşut olarak kaydeder.
trivy_scan:
image: aquasec/trivy:latest
stage: test
script:
- trivy image --format json --output trivy-results.json $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- trivy image --format cyclonedx --output sbom.json $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
artifacts:
paths:
- trivy-results.json
- sbom.json
expire_in: 7 days
only:
- merge_requests
- main
$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA değişkeni, pipeline'ın önceki adımında oluşturup gönderdiğimiz tam görüntüyü tarar. Derleme işiniz farklı bir etiket kullanıyorsa ona göre ayarlayın.
Kritik sorunlarda taramayı başarısız kılma
Varsayılan olarak, Trivy güvenlik açığı bulsa bile çıkış kodu 0 verir. Derlemeyi kırmak için şiddet eşiği ayarlamalısınız. Ben CRITICAL ve HIGH için --exit-code 1 kullanıyorum, LOW ve MEDIUM'u reddetme listesinde olmayan bir durumda görmezden geliyorum.
- trivy image --severity CRITICAL,HIGH --exit-code 1 --format json --output trivy-results.json $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
Bu sayede tek bir kritik CVE MR pipeline'ını anında başarısız kılar. Geliştiriciler hızlı geri bildirim alır ve bilinen istismar edilebilir hatalarla üretime göndermekten kaçınırız.
Önbellekleme ile tarama hızlandırma
Trivy ilk çalıştığında güvenlik veritabanlarını indirir, bu da 10-20 saniye ekler. Yoğun bir CI sisteminde bu zaman artar. GitLab Runner'ın Docker yapılandırması üzerinden bir önbellek birimi monte ederek Trivy DB'sini işler arasında kalıcı tutuyorum.
/etc/gitlab-runner/config.toml içinde:
[[runners]]
[runners.docker]
volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock:ro"]
Ardından işte:
- trivy image --download-db-only
- trivy image --severity CRITICAL,HIGH --exit-code 1 --format json --output trivy-results.json $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
--download-db-only adımı önbellek yenileme başına bir kez çalışır (günlük yeniliyoruz), bu da tarama süresini görüntü başına ~25 saniyeden ~8 saniyeye düşürüyor.
Karşılaştığım sıkıntılar
İlk olarak, self-hosted GitLab Runner Docker executor kullanıyorsanız, çalıştırıcının registry'den görüntü çekebildiğinden emin olun. Bir kez çalıştırıcı docker login kimlik bilgilerine sahip olmadığı için iş sessizce başarısız oldu — $CI_REGISTRY_PASSWORD ile bir before_script adımı ekleyerek düzelttim.
İkinci olarak, Trivy'nin JSON çıktısı büyük olabilir. Yoğun bir projede --ignore-unfixed veya --ignorefile .trivyignore ile ihtiyacınız olmayan alanları kırparak düşük değerli bulguları atlayabilirsiniz.
Üçüncüsü, --format ile --output arasında karışmamak lazım. Öncesi yapıyı (json, cyclonedx, table) kontrol eder, ikincisi sadece dosya adını verir. Bunları karıştırırsanız boş manşutlar alırsınız.
Manşutların içeriği
trivy-results.json şunları içerir:
- Güvenlik Açığı Kimliği (örn. CVE-2024-XXXX)
- Kurulu sürüm vs. düzeltilmiş sürüm
- Şiddet skoru
- NVD veya satıcı danışmanlığına başlıca link
sbom.json (CycloneDX) şunları listeler:
- Görüntüdeki tüm paketler (OS ve uygulama seviyesi)
- Lisanslar
- Kriptografik özetler (SHA-256) mevcutsa
SBOM'u iç uyumluluk portalımıza geceleyici olarak besliyorum. Denetimlerde işe yaradı — belirli bir görüntü versiyonu için SBOM istendiğinde, GitLab'in manşut deposundan saniyeler içinde çekebiliyorum.
İpucu: Push öncesi yerel görüntüleri tarama
Aynı Trivy komutlarını yerelde çalıştırarak sorunları erken yakalayabilirsiniz:
trivy image --severity CRITICAL,HIGH --exit-code 1 myapp:local-test
Bilinen kritik hatalarla ilgili push'ları engellemek için bunu pre-commit kancasına ekleyebilirsiniz. Beni birden fazla kez kurtardı.
Trivy'nin yetmediği durumlar
Trivy, OS paketleri ve dil bağımlılıklarındaki bilinen CVE'ler için harika ama container'ın root olarak çalışması gibi yapılandırma sorunlarını veya katmanlardaki gizli anahtarları taramaz. Bunun için Hadolint'i Dockerfile kontrolleri için ve Trivy'nin kendi --config taramasını Kubernetes manifestleri için kullanıyorum — ama bu ayrı bir iş.
Çalışma zamanı koruması gerekiyorsa, Falco veya Tetragon gibi araçlar devreye girer. Ancak ön derleme, ön dağıtım hijyeni için Trivy artık pipeline'ımızda müzakere edilemez bir adım.
Kapak görseli: Bernard Spragg · PDM (Openverse / kamu malı) · https://www.flickr.com/photos/88123769@N02/51498704533
