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.
