Yazılara geri dön
Yazı

GitLab CI'de Trivy ile Container Görüntülerini SBOM ve CVE Tarama

GitLab CI'de Trivy kullanarak container görüntülerinden SBOM oluşturun ve güvenlik açıkları için tarama yapın. Pratik kurulum, sık karşılaşılan hatalar ve gerçek çıktı örnekleri.

DevopsTrivyGitLab CISBOMcontainer scanning

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