Bulut Depolama Erişim Logları ve Denetim Rehberi

Bulut depolama sistemlerini yönetirken en çok gözden kaçan konulardan biri erişim loglarıdır. “Kim, ne zaman, hangi dosyaya erişti?” sorusunu cevaplayamıyorsan, bir güvenlik ihlali yaşandığında veya uyumluluk denetiminde ciddi sıkıntıya girersin. Bu yazıda AWS S3, Google Cloud Storage ve Azure Blob Storage üzerinde erişim loglarını nasıl toplayacağını, analiz edeceğini ve anlamlı denetim raporları oluşturacağını adım adım ele alacağım.

Neden Bulut Depolama Logları Bu Kadar Önemli?

Klasik on-premise altyapıda storage erişimlerini takip etmek zaten zordu. Buluta geçince bu iş hem kolaylaştı (hazır log mekanizmaları var) hem de karmaşıklaştı (çok fazla kaynak, çok fazla kullanıcı, çok fazla servis hesabı). Şunu düşün: Bir S3 bucket’ına günde milyonlarca istek gelebilir. Bu isteklerin içinden yetkisiz bir erişimi ya da veri sızıntısını nasıl bulacaksın?

Erişim logları sana şunları verir:

  • Güvenlik tespiti: Beklenmedik IP’lerden gelen erişimler, olağandışı saatlerde yapılan işlemler
  • Uyumluluk: GDPR, HIPAA, PCI-DSS gibi regülasyonlar log tutmayı zorunlu kılar
  • Maliyet analizi: Hangi bucket en çok erişim alıyor, transfer maliyeti nereden geliyor?
  • Operasyonel görünürlük: Hangi uygulama hangi dosyaları ne sıklıkla okuyor?
  • Olay müdahalesi: Bir şeyler ters gittiğinde geriye dönük analiz yapabilmek

AWS S3 Erişim Logları

Server Access Logging Aktif Etme

S3’te iki farklı log mekanizması var: Server Access Logging ve AWS CloudTrail. İkisi birbirinin yerine geçmez, tamamlayıcıdır.

Server Access Logging, her HTTP isteğini detaylıca kaydeder. Önce log’ların yazılacağı bir hedef bucket oluştur:

# Log bucket oluştur (ayrı bir bucket kullan, asla aynı bucket'a yazma)
aws s3api create-bucket 
  --bucket my-app-access-logs-2024 
  --region eu-west-1 
  --create-bucket-configuration LocationConstraint=eu-west-1

# Hedef bucket'a log yazma izni ver
aws s3api put-bucket-acl 
  --bucket my-app-access-logs-2024 
  --grant-write URI=http://acs.amazonaws.com/groups/s3-service/LogDelivery 
  --grant-read-acp URI=http://acs.amazonaws.com/groups/s3-service/LogDelivery

Şimdi izlemek istediğin bucket için logging’i aktif et:

# logging-config.json dosyası oluştur
cat > logging-config.json << 'EOF'
{
  "LoggingEnabled": {
    "TargetBucket": "my-app-access-logs-2024",
    "TargetPrefix": "s3-logs/my-production-bucket/"
  }
}
EOF

# Logging'i etkinleştir
aws s3api put-bucket-logging 
  --bucket my-production-bucket 
  --bucket-logging-status file://logging-config.json

# Doğrula
aws s3api get-bucket-logging --bucket my-production-bucket

CloudTrail ile API Düzeyinde Denetim

Server Access Logging nesne düzeyinde erişimleri yakalarken, CloudTrail API çağrılarını yakalar. Özellikle bucket politika değişiklikleri, ACL güncellemeleri gibi kritik olaylar için CloudTrail şarttır:

# Data event'leri içeren trail oluştur
aws cloudtrail create-trail 
  --name s3-audit-trail 
  --s3-bucket-name my-cloudtrail-logs 
  --include-global-service-events 
  --is-multi-region-trail

# S3 data event'lerini ekle
aws cloudtrail put-event-selectors 
  --trail-name s3-audit-trail 
  --event-selectors '[
    {
      "ReadWriteType": "All",
      "IncludeManagementEvents": true,
      "DataResources": [
        {
          "Type": "AWS::S3::Object",
          "Values": ["arn:aws:s3:::my-production-bucket/"]
        }
      ]
    }
  ]'

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

S3 Loglarını Analiz Etme

Log dosyaları ham formatta gelir. Günlük analizler için basit bir bash script işini görür:

#!/bin/bash
# s3-log-analyzer.sh
# Belirli bir tarihe ait S3 loglarını analiz et

BUCKET="my-app-access-logs-2024"
PREFIX="s3-logs/my-production-bucket/"
DATE=$(date -d "yesterday" +%Y-%m-%d)
LOCAL_DIR="/tmp/s3-logs/$DATE"

mkdir -p "$LOCAL_DIR"

echo "Loglar indiriliyor: $DATE"
aws s3 sync "s3://${BUCKET}/${PREFIX}" "$LOCAL_DIR" 
  --exclude "*" 
  --include "*${DATE}*"

echo "=== En Çok Erişen IP Adresleri ==="
cat "$LOCAL_DIR"/* 2>/dev/null | awk '{print $5}' | sort | uniq -c | sort -rn | head -20

echo ""
echo "=== HTTP Hata Kodları ==="
cat "$LOCAL_DIR"/* 2>/dev/null | awk '{print $9}' | grep -E '^[45]' | sort | uniq -c | sort -rn

echo ""
echo "=== En Çok Erişilen Objeler ==="
cat "$LOCAL_DIR"/* 2>/dev/null | awk '{print $8}' | sort | uniq -c | sort -rn | head -10

echo ""
echo "=== Toplam Transfer (Bytes) ==="
cat "$LOCAL_DIR"/* 2>/dev/null | awk '{sum += $17} END {print sum " bytes = " sum/1024/1024/1024 " GB"}'

Google Cloud Storage Erişim Logları

Audit Log Konfigürasyonu

GCS’de iki katman var: Data Access audit logs ve Admin Activity logs. Admin Activity logları her zaman aktiftir. Data Access loglarını manuel olarak etkinleştirmen gerekir:

# Mevcut IAM policy'yi al
gcloud projects get-iam-policy my-project-id 
  --format=json > current-policy.json

# Audit log konfigürasyonunu ekle
cat > audit-config.json << 'EOF'
{
  "auditConfigs": [
    {
      "service": "storage.googleapis.com",
      "auditLogConfigs": [
        {"logType": "DATA_READ"},
        {"logType": "DATA_WRITE"},
        {"logType": "ADMIN_READ"}
      ]
    }
  ]
}
EOF

# Policy'yi güncelle
gcloud projects set-iam-policy my-project-id updated-policy.json

Storage bucket için access log aktif etmek daha basit:

# Log bucket oluştur
gsutil mb -l europe-west1 gs://my-gcs-access-logs

# Access logging aktif et
gsutil logging set on 
  -b gs://my-gcs-access-logs 
  -o "access_log_" 
  gs://my-production-data

# Durumu kontrol et
gsutil logging get gs://my-production-data

Cloud Logging ile Gerçek Zamanlı İzleme

GCS logları otomatik olarak Cloud Logging’e (eski adıyla Stackdriver) gider. Buradan sorgu yazabilirsin:

# gcloud CLI ile log sorgula
# Son 24 saatte 403 hatası alan erişimler
gcloud logging read 
  'resource.type="gcs_bucket"
   protoPayload.status.code=403
   timestamp>="2024-01-15T00:00:00Z"' 
  --project=my-project-id 
  --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.resourceName, protoPayload.status.message)" 
  --limit=100

# Belirli bir kullanıcının erişimlerini filtrele
gcloud logging read 
  'resource.type="gcs_bucket"
   protoPayload.authenticationInfo.principalEmail="[email protected]"' 
  --project=my-project-id 
  --since="7d" 
  --format=json | jq '.[] | {time: .timestamp, action: .protoPayload.methodName, resource: .protoPayload.resourceName}'

Azure Blob Storage Erişim Logları

Storage Analytics ve Diagnostic Settings

Azure’da log toplama için Storage Analytics veya yeni nesil Azure Monitor Diagnostic Settings kullanabilirsin. Diagnostic Settings daha güçlü ve esnek:

# Azure CLI ile diagnostic setting oluştur
# Önce storage account ID'yi al
STORAGE_ID=$(az storage account show 
  --name mystorageaccount 
  --resource-group myResourceGroup 
  --query id -o tsv)

# Log Analytics workspace oluştur (yoksa)
az monitor log-analytics workspace create 
  --resource-group myResourceGroup 
  --workspace-name my-log-workspace 
  --location westeurope

WORKSPACE_ID=$(az monitor log-analytics workspace show 
  --resource-group myResourceGroup 
  --workspace-name my-log-workspace 
  --query id -o tsv)

# Diagnostic setting oluştur
az monitor diagnostic-settings create 
  --name "blob-audit-logs" 
  --resource "${STORAGE_ID}/blobServices/default" 
  --workspace "$WORKSPACE_ID" 
  --logs '[
    {"category": "StorageRead", "enabled": true, "retentionPolicy": {"enabled": true, "days": 90}},
    {"category": "StorageWrite", "enabled": true, "retentionPolicy": {"enabled": true, "days": 90}},
    {"category": "StorageDelete", "enabled": true, "retentionPolicy": {"enabled": true, "days": 90}}
  ]'

KQL ile Log Analizi

Azure Monitor’da Kusto Query Language kullanarak logları analiz edebilirsin:

# Az CLI üzerinden KQL sorgusu çalıştır
az monitor log-analytics query 
  --workspace "$WORKSPACE_ID" 
  --analytics-query '
StorageBlobLogs
| where TimeGenerated > ago(24h)
| where StatusCode >= 400
| summarize ErrorCount = count() by StatusCode, CallerIpAddress, bin(TimeGenerated, 1h)
| order by ErrorCount desc
| take 20
' 
  --output table

Gerçek Dünya Senaryoları

Senaryo 1: Veri Sızıntısı Tespiti

Bir sabah güvenlik ekibinden mesaj geldi: “Bir müşteri verilerinin internette dolaştığını gördük.” Hızlıca S3 loglarına baktım. İşte böyle durumlarda kullandığım script:

#!/bin/bash
# suspicious-access-detector.sh
# Olağandışı büyük veri transferlerini tespit et

LOG_DIR="/tmp/s3-logs"
THRESHOLD_GB=10  # 10 GB üzeri transferler şüpheli

echo "=== Büyük Veri Transferleri (Son 7 Gün) ==="
find "$LOG_DIR" -name "*.log" -mtime -7 | xargs cat 2>/dev/null | 
  awk '$9 == "200" && $17 > ('"$THRESHOLD_GB"' * 1024 * 1024 * 1024) {
    print $1, $2, $5, $8, $17/1024/1024/1024 " GB"
  }' | sort -k5 -rn

echo ""
echo "=== Bilinmeyen IP'lerden Gelen Erişimler ==="
# Bilinen IP aralıklarınızı buraya ekleyin
KNOWN_CIDRS="10.0.0.0/8 172.16.0.0/12 192.168.0.0/16"
find "$LOG_DIR" -name "*.log" -mtime -1 | xargs cat 2>/dev/null | 
  awk '{print $5}' | sort -u | while read ip; do
    # Basit kontrol - production'da daha gelişmiş bir tool kullan
    if [[ $ip =~ ^[0-9]+.[0-9]+.[0-9]+.[0-9]+$ ]]; then
      echo "Dış IP erişimi: $ip"
    fi
  done

echo ""
echo "=== DELETE İşlemleri ==="
find "$LOG_DIR" -name "*.log" -mtime -1 | xargs cat 2>/dev/null | 
  awk '$7 == "DELETE" {print $1, $2, $5, $8}' | head -50

Bu scripti çalıştırdığımda 3 saatlik bir zaman diliminde tek bir IP’den 47 GB veri çekildiğini gördüm. IP adresi Asya’daki bir VPN çıkış noktasıydı. CloudTrail loglarıyla birlikte analiz ettiğimde hangi IAM kullanıcısının credential’larının ele geçirildiğini tespit ettik.

Senaryo 2: Otomatik Uyumluluk Raporu

Her ay uyumluluk ekibine “kim hangi hassas verilere erişti” raporu vermem gerekiyordu. Bunu otomatikleştirdim:

#!/bin/bash
# monthly-compliance-report.sh

REPORT_DATE=$(date -d "last month" +%Y-%m)
REPORT_FILE="/reports/s3-compliance-${REPORT_DATE}.txt"
LOG_BUCKET="my-app-access-logs-2024"
SENSITIVE_PREFIX="sensitive-data/"

echo "Uyumluluk Raporu: $REPORT_DATE" > "$REPORT_FILE"
echo "================================" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"

# Logları indir
aws s3 sync "s3://${LOG_BUCKET}/" "/tmp/compliance-logs/" 
  --exclude "*" 
  --include "*${REPORT_DATE}*" 
  --quiet

echo "## Hassas Veri Erişimleri" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"

grep -h "${SENSITIVE_PREFIX}" /tmp/compliance-logs/*.log 2>/dev/null | 
  awk '{print $1, $2, $5, $8, $9}' | 
  sort | uniq >> "$REPORT_FILE"

echo "" >> "$REPORT_FILE"
echo "## Özet İstatistikler" >> "$REPORT_FILE"
TOTAL=$(grep -c "${SENSITIVE_PREFIX}" /tmp/compliance-logs/*.log 2>/dev/null | 
  awk -F: '{sum+=$2} END {print sum}')
echo "Toplam Erişim Sayısı: $TOTAL" >> "$REPORT_FILE"

UNIQUE_IPS=$(grep -h "${SENSITIVE_PREFIX}" /tmp/compliance-logs/*.log 2>/dev/null | 
  awk '{print $5}' | sort -u | wc -l)
echo "Benzersiz IP Sayısı: $UNIQUE_IPS" >> "$REPORT_FILE"

echo "Rapor oluşturuldu: $REPORT_FILE"

# Raporu e-posta ile gönder (mail komutu konfigüre edilmiş olmalı)
mail -s "S3 Uyumluluk Raporu - $REPORT_DATE" [email protected] < "$REPORT_FILE"

Log Retention ve Maliyet Yönetimi

Logları sonsuza kadar tutamazsın, hem depolama maliyeti artar hem de yönetimi zorlaşır. Akıllı bir retention politikası şart:

# S3'te lifecycle policy ile otomatik log temizleme
cat > log-lifecycle.json << 'EOF'
{
  "Rules": [
    {
      "ID": "log-retention-policy",
      "Filter": {
        "Prefix": "s3-logs/"
      },
      "Status": "Enabled",
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 90,
          "StorageClass": "GLACIER"
        }
      ],
      "Expiration": {
        "Days": 365
      }
    }
  ]
}
EOF

aws s3api put-bucket-lifecycle-configuration 
  --bucket my-app-access-logs-2024 
  --lifecycle-configuration file://log-lifecycle.json

echo "Lifecycle policy uygulandı"
echo "- 0-30 gün: Standard (hızlı erişim)"
echo "- 30-90 gün: Standard-IA (daha ucuz, az erişilen)"
echo "- 90-365 gün: Glacier (arşiv)"
echo "- 365+ gün: Otomatik silme"

Bu yapıyla logların ilk 30 günde hızlı erişilebilir kalmasını, sonraki dönemlerde maliyet optimize edilmesini sağlarsın. Regülasyona göre Glacier’dan çıkarma süresini de göz önünde bulundur, HIPAA için anlık erişim gerekebilir.

Alarm ve Bildirim Kurulumu

Log toplamak yetmez, kritik olaylar için anlık bildirim alman gerekir:

# AWS CloudWatch alarm - çok fazla 403 hatası
aws cloudwatch put-metric-alarm 
  --alarm-name "S3-Excessive-403-Errors" 
  --alarm-description "S3 bucket'ta aşırı erişim reddi" 
  --metric-name "4xxErrors" 
  --namespace "AWS/S3" 
  --dimensions Name=BucketName,Value=my-production-bucket 
  --period 300 
  --evaluation-periods 2 
  --threshold 100 
  --comparison-operator GreaterThanThreshold 
  --statistic Sum 
  --alarm-actions "arn:aws:sns:eu-west-1:123456789:security-alerts" 
  --ok-actions "arn:aws:sns:eu-west-1:123456789:security-alerts"

# CloudTrail Events için EventBridge rule
aws events put-rule 
  --name "S3-PublicACL-Change" 
  --event-pattern '{
    "source": ["aws.s3"],
    "detail-type": ["AWS API Call via CloudTrail"],
    "detail": {
      "eventSource": ["s3.amazonaws.com"],
      "eventName": ["PutBucketAcl", "PutObjectAcl"]
    }
  }' 
  --state ENABLED 
  --description "S3 ACL değişikliklerini izle"

echo "Alarmlar kuruldu"

Log Merkezi Toplama: Çoklu Bulut Senaryosu

Hem AWS hem de GCP kullanıyorsan logları tek bir yerde toplamak mantıklı. Elasticsearch veya bir SIEM çözümü bu iş için ideal:

#!/bin/bash
# multi-cloud-log-collector.sh
# AWS S3 ve GCS loglarını merkezi bir yere topla

CENTRAL_S3="s3://central-security-logs"
DATE=$(date +%Y/%m/%d)

# AWS loglarını topla
echo "AWS S3 logları kopyalanıyor..."
aws s3 sync s3://my-app-access-logs-2024/ 
  "${CENTRAL_S3}/aws/${DATE}/" 
  --exclude "*" 
  --include "*$(date +%Y-%m-%d)*"

# GCS loglarını çek ve S3'e yükle
echo "GCS logları kopyalanıyor..."
TEMP_DIR=$(mktemp -d)
gsutil -m rsync -r 
  "gs://my-gcs-access-logs/access_log_$(date +%Y_%m_%d)" 
  "$TEMP_DIR/"

aws s3 sync "$TEMP_DIR/" 
  "${CENTRAL_S3}/gcs/${DATE}/"

rm -rf "$TEMP_DIR"

echo "Merkezi log toplama tamamlandı: $DATE"
echo "Konumlar:"
echo "  AWS logları: ${CENTRAL_S3}/aws/${DATE}/"
echo "  GCS logları: ${CENTRAL_S3}/gcs/${DATE}/"

Pratik İpuçları

Yıllarca bu işi yapmanın verdiği tecrübeyle bazı önemli noktaları paylaşayım:

  • Log bucket’ını asla kaynak bucket ile aynı tutma: Döngüsel log problemi yaşarsın ve maliyetler uçar
  • Zaman damgalarını UTC’de tut: Farklı region’lardaki logları karşılaştırırken saat dilimi kaosunu önler
  • Log formatını değiştirme: Parser’larını ve alarm kurallarını bozmamak için format değişikliklerini dikkatli planla
  • Erişim loglarına da erişim kontrolü uygula: Logların kendisi de hassas veri içerir, kim hangi dosyaya erişiyor bilgisi değerlidir
  • Test ortamında loglama: Prodüksiyon loglarını boğmamak için dev/test bucket’larını ayrı tutmak ve daha kısa retention uygulamak maliyet tasarrufu sağlar
  • Log boyutunu tahmin et: Büyük bir S3 bucket’ı için günde gigabyte’larca log üretilebilir, kapasiteyi önceden planla
  • Structured log analizi için Athena veya BigQuery kullan: Ham log dosyaları üzerinde grep çalıştırmak çok yavaş kalır, SQL tabanlı araçlar çok daha verimli

Sonuç

Bulut depolama erişim logları, güvenlik ve uyumluluk stratejisinin temel taşlarından biridir. Başta küçük bir detay gibi görünse de, bir güvenlik ihlali yaşandığında veya bir denetim geldiğinde bu loglar hayat kurtarır.

Temel yaklaşımı şöyle özetleyebilirim: Önce tüm kritik bucket’larda loglama aktif et, ardından merkezi bir toplama noktası oluştur, sonra temel analizleri otomatikleştir ve kritik olaylar için alarm kur. Bu dört adımı tamamladığında, bulut depolama altyapında ne olduğu hakkında gerçek bir görünürlüğe sahip olursun.

Uyumluluk gereksinimlerine göre retention politikalarını ayarlamayı unutma. GDPR 6 ay demiyorsa da olaya göre değişiyor, hukuk ekibinizle mutlaka konuşun. Maliyet tarafında ise Glacier ve benzeri soğuk depolama sınıfları log arşivi için oldukça ekonomik çözümler sunuyor.

Son olarak, logları toplamak yetmez; düzenli olarak gözden geçirmek ve anomali tespitini otomatikleştirmek gerekir. Log deposu bir dolap değil, aktif bir güvenlik aracıdır.

Bir yanıt yazın

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