AWS CloudTrail ile Denetim Kayıtları Nasıl Yönetilir?

AWS’de bir şeylerin ters gitmesi an meselesi. Biri yanlışlıkla bir S3 bucket’ını herkese açık yapabilir, bir IAM kullanıcısı beklenmedik saatlerde konsola giriş yapabilir ya da kritik bir kaynak hiç olmadık bir anda silinebilir. İşte tam bu noktada CloudTrail devreye giriyor. CloudTrail, AWS hesabınızdaki her API çağrısını, her konsol girişini ve her kaynak değişikliğini kaydeden, bulut ortamınızın hafızası diyebileceğimiz bir denetim servisidir. Bu yazıda CloudTrail’i nasıl etkin biçimde kullanacağınızı, log’ları nasıl analiz edeceğinizi ve gerçek dünya senaryolarında nasıl işe yaradığını ele alacağız.

CloudTrail Nedir ve Ne İşe Yarar?

CloudTrail, AWS’nin managed denetim ve uyumluluk servisidir. Temel olarak şu soruları yanıtlar: Kim, ne zaman, nereden, ne yaptı? Bir EC2 instance’ı kim başlattı? Güvenlik grubu kuralını kim değiştirdi? Hangi IAM rolü o S3 objesine erişti?

CloudTrail üç tür olay kaydeder:

  • Management Events: AWS kaynaklarınız üzerindeki yönetim operasyonları. EC2 instance oluşturma, IAM policy değişikliği, VPC subnet silme gibi kontrol düzlemi olayları.
  • Data Events: S3 obje düzeyinde erişimler, Lambda fonksiyon çağrıları, DynamoDB item düzeyinde işlemler gibi veri düzlemi olayları. Bu olaylar varsayılan olarak kapalıdır ve maliyet doğurur.
  • Insights Events: Anormal API aktivitelerini otomatik tespit eden olaylar. Birdenbire artan DeleteBucket çağrıları gibi durumları yakalar.

Varsayılan olarak CloudTrail, son 90 günlük management event’larını ücretsiz olarak Event History’de tutar. Ancak ciddi bir denetim altyapısı için S3’e yönlendirilen, şifrelenmiş ve alarm mekanizmalarıyla donatılmış bir Trail kurmanız gerekir.

Trail Kurulumu ve Temel Konfigürasyon

İlk adım olarak AWS CLI ile bir trail oluşturalım. Önce log’ların gideceği S3 bucket’ını hazırlamamız gerekiyor.

# CloudTrail log bucket'ı oluştur
aws s3api create-bucket 
  --bucket my-company-cloudtrail-logs 
  --region eu-west-1 
  --create-bucket-configuration LocationConstraint=eu-west-1

# Bucket versioning aktif et
aws s3api put-bucket-versioning 
  --bucket my-company-cloudtrail-logs 
  --versioning-configuration Status=Enabled

# Bucket public access'i tamamen kapat
aws s3api put-public-access-block 
  --bucket my-company-cloudtrail-logs 
  --public-access-block-configuration 
    BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true

Şimdi CloudTrail’in bu bucket’a yazabilmesi için gerekli bucket policy’yi ekleyelim:

cat > cloudtrail-bucket-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AWSCloudTrailAclCheck",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "s3:GetBucketAcl",
      "Resource": "arn:aws:s3:::my-company-cloudtrail-logs"
    },
    {
      "Sid": "AWSCloudTrailWrite",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::my-company-cloudtrail-logs/AWSLogs/123456789012/*",
      "Condition": {
        "StringEquals": {
          "s3:x-amz-acl": "bucket-owner-full-control"
        }
      }
    }
  ]
}
EOF

aws s3api put-bucket-policy 
  --bucket my-company-cloudtrail-logs 
  --policy file://cloudtrail-bucket-policy.json

Şimdi trail’i oluşturalım. Multi-region trail oluşturmak kritik önem taşır; yoksa başka bir region’da yapılan işlemler kayıt dışı kalır:

# Multi-region trail oluştur
aws cloudtrail create-trail 
  --name my-company-audit-trail 
  --s3-bucket-name my-company-cloudtrail-logs 
  --is-multi-region-trail 
  --enable-log-file-validation 
  --include-global-service-events 
  --kms-key-id arn:aws:kms:eu-west-1:123456789012:key/your-kms-key-id

# Trail'i başlat
aws cloudtrail start-logging 
  --name my-company-audit-trail

# Trail durumunu kontrol et
aws cloudtrail get-trail-status 
  --name my-company-audit-trail

--enable-log-file-validation: Log dosyalarının değiştirilip değiştirilmediğini doğrulamaya yarar. Uyumluluk gereksinimleri için şart. --is-multi-region-trail: Tüm region’lardaki olayları tek bir trail’de toplar. --include-global-service-events: IAM, STS, CloudFront gibi global servislerin olaylarını da kaydeder.

Log Dosyası Doğrulama

CloudTrail log’ları S3’e JSON formatında yazılır ve saatlik olarak sıkıştırılmış dosyalar halinde gelir. Log dosyası doğrulaması, bir saldırganın izlerini kapatmak için log’ları silip silemediğini ya da manipüle edip edemediğini anlamanızı sağlar:

# Log dosyası bütünlüğünü doğrula
aws cloudtrail validate-logs 
  --trail-arn arn:aws:cloudtrail:eu-west-1:123456789012:trail/my-company-audit-trail 
  --start-time 2024-01-01T00:00:00Z 
  --end-time 2024-01-31T23:59:59Z 
  --verbose

# Belirli bir tarih aralığındaki olayları sorgula
aws cloudtrail lookup-events 
  --lookup-attributes AttributeKey=EventName,AttributeValue=ConsoleLogin 
  --start-time 2024-01-15T00:00:00Z 
  --end-time 2024-01-15T23:59:59Z 
  --query 'Events[*].{User:Username,Time:EventTime,Source:EventSource}' 
  --output table

Gerçek Dünya Senaryosu: Yetkisiz Erişim Tespiti

Bir Pazartesi sabahı güvenlik ekibinizden alert geliyor: Üretim ortamınızdaki bir RDS instance’ının snapshot’ı alınmış ve başka bir hesaba kopyalanmış. CloudTrail’e bakma zamanı.

Önce hangi olayın gerçekleştiğini belirleyelim:

# RDS ile ilgili tüm son olayları sorgula
aws cloudtrail lookup-events 
  --lookup-attributes AttributeKey=ResourceType,AttributeValue=AWS::RDS::DBInstance 
  --start-time 2024-01-14T00:00:00Z 
  --end-time 2024-01-15T12:00:00Z 
  --output json | jq '.Events[] | {
    EventName: .EventName,
    Username: .Username,
    EventTime: .EventTime,
    SourceIP: (.CloudTrailEvent | fromjson | .sourceIPAddress),
    UserAgent: (.CloudTrailEvent | fromjson | .userAgent)
  }'

Diyelim ki şüpheli bir ModifyDBSnapshotAttribute olayı buldunuz. Bu olayın detaylarına bakalım:

# Belirli bir event ID'sine göre detay çek
aws cloudtrail lookup-events 
  --lookup-attributes AttributeKey=EventId,AttributeValue=abc12345-def6-7890-ghij-klmnopqrstuv 
  --output json | jq '.Events[0].CloudTrailEvent | fromjson'

Dönen JSON’da requestParameters alanına bakacaksınız. Eğer attributeName: "restore" ve başka bir AWS hesap ID’si görüyorsanız, snapshot başka bir hesaba paylaşılmış demektir. sourceIPAddress alanı size saldırının nereden geldiğini söyler. userIdentity bloğu ise hangi IAM kullanıcısı ya da rolünün bu işlemi yaptığını gösterir.

CloudWatch Logs Entegrasyonu ve Alarmlar

CloudTrail’i sadece S3’e yazmak yetmez; olayları gerçek zamanlı izlemek için CloudWatch Logs entegrasyonu şart:

# CloudWatch Log Group oluştur
aws logs create-log-group 
  --log-group-name /aws/cloudtrail/my-company-audit

# Log retention'ı ayarla (90 gün)
aws logs put-retention-policy 
  --log-group-name /aws/cloudtrail/my-company-audit 
  --retention-in-days 90

# Trail'i CloudWatch Logs ile entegre et
aws cloudtrail update-trail 
  --name my-company-audit-trail 
  --cloud-watch-logs-log-group-arn arn:aws:logs:eu-west-1:123456789012:log-group:/aws/cloudtrail/my-company-audit:* 
  --cloud-watch-logs-role-arn arn:aws:iam::123456789012:role/CloudTrail-CloudWatch-Role

Şimdi kritik olaylar için metric filter ve alarm oluşturalım. Root account kullanımını izlemek en önemli kontrol noktalarından biridir:

# Root account kullanımı için metric filter
aws logs put-metric-filter 
  --log-group-name /aws/cloudtrail/my-company-audit 
  --filter-name RootAccountUsage 
  --filter-pattern '{ $.userIdentity.type = "Root" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != "AwsServiceEvent" }' 
  --metric-transformations 
    metricName=RootAccountUsageCount,metricNamespace=CloudTrailMetrics,metricValue=1

# Alarm oluştur
aws cloudwatch put-metric-alarm 
  --alarm-name RootAccountUsageAlarm 
  --alarm-description "Root account kullanimi tespit edildi" 
  --metric-name RootAccountUsageCount 
  --namespace CloudTrailMetrics 
  --statistic Sum 
  --period 300 
  --threshold 1 
  --comparison-operator GreaterThanOrEqualToThreshold 
  --evaluation-periods 1 
  --alarm-actions arn:aws:sns:eu-west-1:123456789012:security-alerts 
  --treat-missing-data notBreaching

Benzer şekilde IAM policy değişikliklerini, güvenlik grubu değişikliklerini ve MFA olmadan yapılan konsol girişlerini izlemek için de metric filter’lar oluşturabilirsiniz. AWS’nin CIS Benchmark’ları bu alarmların tam listesini sunar ve referans olarak kullanmanızı öneririm.

Athena ile Log Analizi

S3’teki CloudTrail loglarını analiz etmenin en güçlü yolu Amazon Athena’dır. Yüzlerce gigabaytlık log üzerinde SQL sorgusu çalıştırabilirsiniz:

# Athena'da CloudTrail için tablo oluştur
aws athena start-query-execution 
  --query-string "
CREATE EXTERNAL TABLE cloudtrail_logs (
  eventversion STRING,
  useridentity STRUCT<
    type:STRING,
    principalid:STRING,
    arn:STRING,
    accountid:STRING,
    username:STRING,
    sessioncontext:STRUCT<
      attributes:STRUCT<
        mfaauthenticated:STRING,
        creationdate:STRING
      >
    >
  >,
  eventtime STRING,
  eventsource STRING,
  eventname STRING,
  awsregion STRING,
  sourceipaddress STRING,
  useragent STRING,
  errorcode STRING,
  errormessage STRING,
  requestparameters STRING,
  responseelements STRING,
  requestid STRING,
  eventid STRING,
  resources ARRAY<STRUCT<ARN:STRING,accountId:STRING,type:STRING>>,
  eventtype STRING,
  apiversion STRING,
  readonly STRING,
  recipientaccountid STRING,
  serviceeventdetails STRING,
  sharedeventid STRING,
  vpcendpointid STRING
)
ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde'
STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://my-company-cloudtrail-logs/AWSLogs/123456789012/CloudTrail/'
" 
  --query-execution-context Database=default 
  --result-configuration OutputLocation=s3://my-athena-results/

Tablo oluşturulduktan sonra güçlü sorgular çalıştırabilirsiniz. Örneğin son 7 gün içinde en çok hata alan IAM kullanıcısını bulmak için:

SELECT
  useridentity.username,
  eventname,
  errorcode,
  COUNT(*) as error_count,
  MIN(eventtime) as first_occurrence,
  MAX(eventtime) as last_occurrence
FROM cloudtrail_logs
WHERE
  errorcode IS NOT NULL
  AND errorcode != ''
  AND eventtime > date_format(date_add('day', -7, current_date), '%Y-%m-%dT%H:%i:%SZ')
GROUP BY
  useridentity.username,
  eventname,
  errorcode
ORDER BY error_count DESC
LIMIT 20;

Bu sorgu size hangi kullanıcının hangi işlemlerde defalarca başarısız olduğunu gösterir. Brute force girişimleri veya izin sınırlarını zorlayan bir kullanıcı hemen gözünüze çarpar.

Gerçek Dünya Senaryosu: Maliyet Anomalisi Araştırması

Ay sonu faturanız beklenenden yüzde kırk yüksek geldi. Finance ekibi sorumlusunun kim olduğunu soruyor. CloudTrail bu durumda da yardımcı olur:

# EC2 instance başlatma olaylarını sorgula
aws cloudtrail lookup-events 
  --lookup-attributes AttributeKey=EventName,AttributeValue=RunInstances 
  --start-time 2024-01-01T00:00:00Z 
  --end-time 2024-01-31T23:59:59Z 
  --output json | jq '.Events[] | {
    Username: .Username,
    EventTime: .EventTime,
    Region: (.CloudTrailEvent | fromjson | .awsRegion),
    InstanceType: (.CloudTrailEvent | fromjson | .requestParameters.instanceType),
    InstanceCount: (.CloudTrailEvent | fromjson | .requestParameters.maxCount)
  }'

Ardından Athena’da daha kapsamlı bir sorgu çalıştırırsınız ve ap-southeast-1 region’ında gece yarısı biri tarafından p3.16xlarge instance’ların ayağa kaldırıldığını görürsünüz. O kullanıcının credential’ı sızdırılmış ya da bir geliştirici “sadece test edeyim” diye büyük bir makine açmış ve kapatmayı unutmuştur. Her iki durumda da sorumluyu ve zamanı net olarak tespit ettiniz.

Organizasyon Düzeyinde CloudTrail

Eğer birden fazla AWS hesabınız varsa ve AWS Organizations kullanıyorsanız, organization trail kurmak hayat kurtarır. Tüm member hesaplarını tek bir trail altında toplar:

# Organization trail oluştur (management hesabında çalıştırın)
aws cloudtrail create-trail 
  --name org-wide-audit-trail 
  --s3-bucket-name my-org-cloudtrail-logs 
  --is-multi-region-trail 
  --enable-log-file-validation 
  --include-global-service-events 
  --is-organization-trail

aws cloudtrail start-logging 
  --name org-wide-audit-trail

# Trail detaylarını kontrol et
aws cloudtrail describe-trails 
  --include-shadow-trails false 
  --output json | jq '.trailList[] | {
    Name: .Name,
    IsOrganizationTrail: .IsOrganizationTrail,
    IsMultiRegionTrail: .IsMultiRegionTrail,
    LogFileValidationEnabled: .LogFileValidationEnabled
  }'

Organization trail’i kurduğunuzda member hesaplar kendi trail’lerini devre dışı bırakamaz. Bu sayede merkezi bir denetim yapısı oluşturursunuz ve hiçbir hesap “gözden kaçamaz”.

Log Şifreleme ve Güvenlik Sertleştirme

Üretim ortamında CloudTrail loglarını KMS ile şifrelemek zorunludur. Özellikle PCI-DSS, SOC 2 veya ISO 27001 gibi uyumluluk standartlarına tabiiyseniz bu tartışmaya yer yok:

# KMS anahtarını CloudTrail için yapılandır
aws kms create-key 
  --description "CloudTrail log encryption key" 
  --key-usage ENCRYPT_DECRYPT 
  --key-spec SYMMETRIC_DEFAULT

# Key alias oluştur
aws kms create-alias 
  --alias-name alias/cloudtrail-logs 
  --target-key-id your-key-id

# Trail'i KMS ile güncelle
aws cloudtrail update-trail 
  --name my-company-audit-trail 
  --kms-key-id alias/cloudtrail-logs

# S3 bucket'ta log dosyası silmeyi engellemek için Object Lock aktif et
aws s3api put-object-lock-configuration 
  --bucket my-company-cloudtrail-logs 
  --object-lock-configuration '{
    "ObjectLockEnabled": "Enabled",
    "Rule": {
      "DefaultRetention": {
        "Mode": "GOVERNANCE",
        "Days": 365
      }
    }
  }'

S3 Object Lock ile log dosyalarının belirli bir süre boyunca silinememesini ve değiştirilememesini garantilemiş olursunuz. Bu özellik forensic analiz sırasında “birisi kanıtları imha etti” endişesini ortadan kaldırır.

Uyumluluk ve Raporlama

Denetçilere rapor sunmak zorunda kaldığınızda CloudTrail logları ham halde işe yaramaz. AWS Config ile entegre çalışarak kaynak konfigürasyon geçmişini izleyebilir, AWS Security Hub ile bulguları merkezi bir panelde toplayabilirsiniz.

Belirli bir kullanıcının belirli bir zaman aralığındaki tüm aktivitesini çıkarmak için şu script işinizi görür:

#!/bin/bash
# Kullanici aktivite raporu olustur
USERNAME="john.doe"
START_DATE="2024-01-01T00:00:00Z"
END_DATE="2024-01-31T23:59:59Z"
OUTPUT_FILE="user_activity_${USERNAME}_$(date +%Y%m%d).json"

echo "CloudTrail aktivite raporu olusturuluyor: $USERNAME"

aws cloudtrail lookup-events 
  --lookup-attributes AttributeKey=Username,AttributeValue=$USERNAME 
  --start-time $START_DATE 
  --end-time $END_DATE 
  --output json | jq '.Events[] | {
    EventTime: .EventTime,
    EventName: .EventName,
    EventSource: .EventSource,
    SourceIP: (.CloudTrailEvent | fromjson | .sourceIPAddress),
    UserAgent: (.CloudTrailEvent | fromjson | .userAgent),
    ErrorCode: (.CloudTrailEvent | fromjson | .errorCode // "Success"),
    AWSRegion: (.CloudTrailEvent | fromjson | .awsRegion)
  }' > $OUTPUT_FILE

EVENT_COUNT=$(cat $OUTPUT_FILE | grep -c "EventTime")
echo "Toplam $EVENT_COUNT olay kaydi: $OUTPUT_FILE"

# Benzersiz kaynaklar
echo "En cok kullanilan servisler:"
cat $OUTPUT_FILE | jq -r '.EventSource' | sort | uniq -c | sort -rn | head -10

Bu script ile bir kullanıcının aylık aktivite özetini hızla çıkarabilir, denetçilere teslim edebilirsiniz.

CloudTrail Insights Aktifleştirme

CloudTrail Insights, anormal API aktivitelerini otomatik olarak tespit eder. El ile alarm kurmak yerine AWS’nin makine öğrenmesinden yararlanmak isteyenler için güçlü bir alternatiftir:

# Insights'ı trail üzerinde aktif et
aws cloudtrail put-insight-selectors 
  --trail-name my-company-audit-trail 
  --insight-selectors '[
    {"InsightType": "ApiCallRateInsight"},
    {"InsightType": "ApiErrorRateInsight"}
  ]'

# Mevcut insight selector'larını kontrol et
aws cloudtrail get-insight-selectors 
  --trail-name my-company-audit-trail

Insights aktifleştirildikten sonra birdenbire artan TerminateInstances çağrıları ya da anormal GetSecretValue istekleri gibi durumlar otomatik olarak tespit edilip raporlanır. Maliyet açısından bakıldığında Insights ek ücret doğurur ancak güvenlik ekibi küçük ya da yoksa bu yatırıma değer.

Sık Yapılan Hatalar

CloudTrail kurulumunda sistem yöneticilerinin sıkça düştüğü tuzaklar şunlardır:

  • Sadece tek region trail kurmak: Saldırganlar başka region’larda kaynak oluşturabilir. Multi-region trail zorunlu.
  • Data events’i tamamen kapatmak: S3 bucket’larına yapılan okuma/yazma işlemlerini takip etmiyorsanız veri sızdırılması durumunda körü körüne olursunuz. En azından kritik bucket’lar için data events açın.
  • Log bucket’ını aynı hesapta tutmak: Hesap tamamen ele geçirilirse saldırgan logları silebilir. Ayrı bir log arşiv hesabı kullanmak en iyi pratiktir.
  • Log file validation’ı kapatmak: “Zaten şifreledik” demek yetmez. Validation olmadan dosyaların manipüle edilip edilmediğini bilemezsiniz.
  • CloudWatch alarmları kurmamak: Loglar S3’te duruyorsa kimse bakmaz. Gerçek zamanlı alarmlar olmadan CloudTrail reaktif bir araç olarak kalır.
  • 90 günlük ücretsiz limiti yeterli saymak: Event History’de saklanan 90 günlük veri, uyumluluk gereksinimleri ve forensic analizler için genellikle yetersiz kalır. S3’e yazılacak şekilde trail kurmak uzun süreli saklama sağlar.

Sonuç

CloudTrail, AWS ortamınızda olanların hesabını tutmanın temel yoludur. Sadece “birisi bir şey yaptı mı?” sorusunu değil, “kim, ne zaman, nereden, hangi araçla yaptı?” sorularını da yanıtlar. Bunu kurumsal bir kamera sistemi gibi düşünebilirsiniz. Sadece kamerayı takmak yetmez; kayıtların güvenli bir yerde saklanması, belirli olaylarda alarmların çalması ve düzenli olarak görüntülerin incelenmesi gerekir.

Minimum seviyede yapmanız gerekenler: Multi-region trail kurun, log file validation’ı açın, KMS ile şifreleyin, log bucket’ını ayrı bir hesaba koyun ve en azından root account kullanımı ile IAM policy değişiklikleri için CloudWatch alarmları tanımlayın. Buradan sonrasını ihtiyacınıza göre genişletebilirsiniz: Athena entegrasyonu, Security Hub, organization trail ve Insights bunların başında gelir.

Bir güvenlik olayı yaşandığında CloudTrail loglarının hazır ve güvenilir olması, saatler içinde sonuca ulaşmanızı sağlar. Aksi takdirde “ne oldu bilmiyoruz” demek zorunda kalırsınız ki bu hem teknik hem de kurumsal açıdan son derece kötü bir konumdur.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir