Üç katman kullanacağız: hazır kural setleriyle geniş tarama için Checkov, aynı imzayı tek binary altında toplayan Trivy ve kuruma özgü kuralları yazmak için OPA/Rego + Conftest. Not: tfsec artık bakım almıyor; tüm kontrolleri Trivy'ye taşındı ve AVD-AWS-0086 gibi kontrol kimlikleri birebir korunuyor. Terrascan projesi de arşivlendi, yeni kurulumlar için önerilmez.
Hangi katman neyi yakalar?
| Katman | Araç | Yakaladığı sorun | Çalıştığı yer |
|---|---|---|---|
| Statik kural | Checkov, Trivy | Şifreleme kapalı, port 0.0.0.0/0, log yok | IDE, pre-commit, CI |
| Graf analizi | Checkov 3.x | Kaynaklar arası ilişki hataları | CI |
| Özel politika | OPA / Conftest | Kurum standardı, etiket, bölge, isimlendirme | CI, plan sonrası |
| Plan denetimi | Conftest + terraform plan JSON | Gerçekte ne değişecek | CI, merge öncesi |
| Sır taraması | Trivy, git-secrets | Koda gömülü anahtar ve parola | pre-commit, CI |
| Sürüm kilidi | terraform, provider pin | Beklenmeyen sağlayıcı değişimi | Depo |
Önce temel: güvensiz bir örnek
Aşağıdaki kod çalışır ama üretimde olmamalıdır. Depolama şifrelemesi, erişim kısıtı ve günlükleme eksiktir.
CODE TERMINAL
resource "aws_s3_bucket" "veri" {
bucket = "kurum-rapor-arsivi"
}
resource "aws_security_group_rule" "ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.web.id
}Bu iki kaynak, ilerideki taramalarda referans örneğimiz olacak.
Checkov ile ilk tarama
Checkov, Python ile kurulur ve dizini olduğu gibi tarar. Çıktıyı CI'da işlemek için JSON veya SARIF tercih edin.
CODE TERMINAL
pip install --upgrade checkov
checkov -d . --framework terraform --compact
checkov -d . -o sarif --output-file-path reports/Yukarıdaki örnekte Checkov, açık SSH kuralını ve şifrelemesi tanımlanmamış kovayı raporlar. Belirli bir kontrolü bilinçli olarak kabul ediyorsanız kod içinde gerekçeli atlama kullanın; genel --skip-check bayrağını kalıcı çözüm olarak kullanmayın.
CODE TERMINAL
resource "aws_s3_bucket" "log" {
# checkov:skip=CKV_AWS_18:Erisim logu merkezi hesapta tutuluyor, ticket INF-4412
bucket = "kurum-erisim-log"
}Trivy ile aynı taramayı tek binary'de yapmak
Trivy; yanlış yapılandırma, bağımlılık zafiyeti, sır ve konteyner imajı taramasını tek araçta toplar. tfsec kullanan ekipler için geçiş maliyeti düşüktür.
CODE TERMINAL
trivy config . --severity HIGH,CRITICAL
trivy config . --format sarif --output trivy-iac.sarif
trivy fs . --scanners secret,misconfigCheckov ile Trivy arasında bulgu farkı görürseniz bunu hata saymayın; kural setleri farklı kapsamlara sahiptir. Pratikte ikisini birlikte çalıştırıp bulguları tek SARIF akışında toplamak en geniş kapsamı verir.
Kuruma özgü kurallar: OPA ve Conftest
Hazır kural setleri "şifreleme açık mı" sorusunu yanıtlar; ancak "her kaynakta sahip etiketi var mı", "yalnız eu-central-1 kullanılabilir mi" gibi kurum kuralları yazılmak zorundadır. Rego bunun için uygundur.
CODE TERMINAL
package terraform.etiket
deny contains msg if {
resource := input.resource_changes[_]
startswith(resource.type, "aws_")
not resource.change.after.tags.Owner
msg := sprintf("%s kaynaginda Owner etiketi yok", [resource.address])
}Politikayı gerçek değişiklik üzerinde çalıştırmak için planı JSON'a çevirin. Bu, koda bakmak yerine ne olacağına bakmayı sağlar.
CODE TERMINAL
terraform plan -out=tf.plan
terraform show -json tf.plan > tf.plan.json
conftest test --policy policy/ tf.plan.jsonPlan JSON denetiminin değeri
Statik HCL taraması değişken, modül çıktısı veya uzak veri kaynağından gelen değerleri her zaman çözemez. Plan JSON ise sağlayıcı tarafından hesaplanmış son değerleri içerir. Yıkıcı işlemleri merge öncesi yakalamak için de kullanışlıdır.
- Üretim veritabanı veya disk silen plan adımlarını reddedin.
- Genel erişime açılan ağ kuralı oluşturan değişiklikleri engelleyin.
- IAM politikalarında yıldız izin genişlemesini yakalayın.
- Şifreleme anahtarı değişimi gibi kritik işlemlerde ikinci onay isteyin.
- Beklenmeyen bölge veya hesap kimliği tespit edin.
- Etiket, isimlendirme ve maliyet merkezi standardını zorunlu kılın.
Pre-commit ile erken geri bildirim
Geliştiriciye en ucuz geri bildirim, kod daha depoya gitmeden verilendir.
CODE TERMINAL
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.99.0
hooks:
- id: terraform_fmt
- id: terraform_validate
- id: terraform_checkov
- repo: https://github.com/aquasecurity/trivy
rev: v0.70.0
hooks:
- id: trivy-configGitHub Actions ile CI hattı
CODE TERMINAL
name: iac-guvenlik
on: [pull_request]
permissions:
contents: read
security-events: write
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Checkov
run: |
pip install checkov
checkov -d . -o sarif --output-file-path .
- name: Trivy IaC
run: trivy config . --format sarif --output trivy.sarif --exit-code 1 --severity HIGH,CRITICAL
- name: SARIF yukle
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarifCI kimlik bilgilerini uzun ömürlü anahtar yerine OIDC ile alın, iş akışı izinlerini en az ayrıcalıkla tanımlayın ve üçüncü taraf action'ları commit SHA ile sabitleyin.
State dosyası: en çok unutulan risk
Terraform state; parola, anahtar ve sertifika gibi değerleri açık biçimde barındırabilir. Kod taramaları bunu yakalamaz.
- State'i uzak ve şifreli backend'de tutun, sürüm geçmişini açın.
- Kilitleme mekanizmasını etkinleştirin.
- State'e erişimi yalnız CI kimliği ve sınırlı yönetici grubuyla kısıtlayın.
- State'i asla kod deposuna commit etmeyin; .gitignore'a ekleyin.
- Sırları Terraform değişkeni yerine gizli yönetim servisinden okuyun.
- Plan çıktısını log olarak yayımlarken hassas alanları maskeleyin.
- State erişim kayıtlarını merkezi olarak izleyin.
Modül ve sağlayıcı tedarik zinciri
Registry'den çekilen bir modül, sizin hesabınızda sizin yetkinizle kaynak oluşturur. Bu nedenle modül seçimi bir tedarik zinciri kararıdır.
- Modül ve sağlayıcı sürümlerini tam sürümle sabitleyin.
- Bakımı süren, kaynak kodu incelenebilir modülleri tercih edin.
- Kritik modülleri kurum içi registry'ye ayna alın.
- .terraform.lock.hcl dosyasını depoya ekleyin ve değişimini inceleyin.
- Modül güncellemelerini plan farkıyla birlikte gözden geçirin.
- Harici modüllerin oluşturduğu IAM izinlerini ayrı denetleyin.
Gürültüyü yönetmek
İlk taramada yüzlerce bulgu çıkması normaldir ve ekibi kolayca felç eder. Kademeli yaklaşım işe yarar: önce yalnız CRITICAL bulguları engelleyici yapın, HIGH için düzeltme süresi tanıyın, geri kalanını raporlayın. Yeni kodda sıfır tolerans, eski kodda takvimli borç yönetimi uygulayın.
Uygulama kontrol listesi
- Checkov ve Trivy pre-commit ile yerelde çalışıyor.
- CI her pull request'te IaC taraması yapıyor ve SARIF üretiyor.
- CRITICAL bulgular merge'i engelliyor.
- Atlamalar kod içinde gerekçe ve ticket numarasıyla yazılıyor.
- terraform plan JSON'u Conftest ile denetleniyor.
- Kurum politikaları Rego olarak sürüm kontrolünde tutuluyor.
- Politika deposunda test dosyaları bulunuyor.
- State uzak, şifreli, kilitli ve erişimi kayıt altında.
- Modül ve sağlayıcı sürümleri ile lock dosyası sabit.
- CI kimliği OIDC ile alınıyor, uzun ömürlü anahtar yok.
- Yıkıcı plan adımları ayrı onay gerektiriyor.
- Bulgu eğilimi aylık olarak raporlanıyor.
Sonuç
IaC güvenliği tek bir tarayıcı eklemekle bitmez. Checkov ve Trivy yaygın hataları ucuza yakalar; asıl kazanç, kurum kurallarını Rego ile yazılı hâle getirip terraform plan çıktısı üzerinde zorunlu kılmaktan gelir. Buna state koruması ve modül sürüm disiplini eklendiğinde altyapı değişiklikleri denetlenebilir, tekrarlanabilir ve geri alınabilir hâle gelir.
Kaynaklar
- Checkov — Resmî dokümantasyon
- Trivy — Misconfiguration Scanning
- Open Policy Agent — Rego Policy Language
- Conftest — Resmî site
- Terraform — Sensitive Data in State
- Terraform — show ve plan JSON çıktısı
TR Siber Ekibi