Bulut Ortamında Şifreleme Stratejileri: Verilerinizi Güvende Tutun
Buluta geçiş kararı aldığınızda, güvenlik ekibinin ilk sorusu genellikle aynı oluyor: “Verilerimiz orada güvende mi?” Bu sorunun cevabı büyük ölçüde şifreleme stratejinize bağlı. Ancak bulut ortamında şifreleme, on-premise dünyasından çok daha karmaşık bir hal alıyor. Hangi anahtarı kim yönetiyor, şifreleme nerede gerçekleşiyor, anahtar rotasyonu nasıl yapılıyor… Bunların hepsini doğru kurgulamazsanız ya güvenlik açığı bırakırsınız ya da gereksiz maliyet yaratırsınız.
Bulut Şifrelemesinin Temel Kavramları
Önce temel ayrımları netleştirelim. Bulut şifrelemesi üç ana kategoriye ayrılır:
- Data at Rest (Durağan Veri Şifreleme): Diskte, veritabanında veya nesne depolama alanında duran verinin şifrelenmesi
- Data in Transit (Geçiş Halindeki Veri Şifreleme): Network üzerinden taşınan verinin şifrelenmesi
- Data in Use (Kullanımdaki Veri Şifreleme): İşlemci tarafından aktif olarak işlenen verinin şifrelenmesi (bu alan henüz gelişmekte)
Anahtar yönetimi açısından da üç model var:
- Provider-Managed Keys (SSE-S3, Google-managed): Bulut sağlayıcı her şeyi halleder, siz hiçbir şey yapmazsınız
- Customer-Managed Keys (CMK/CMEK): Anahtarları siz oluşturursunuz, KMS’te saklarsınız
- Customer-Provided Keys (SSE-C, CSEK): Anahtarları siz oluşturur, siz saklarsınız, her istekte siz sağlarsınız
Çoğu organizasyon için Customer-Managed Keys dengeli bir seçim. Kontrol sizde, operasyonel yük makul seviyede.
AWS Ortamında Şifreleme
S3 Bucket Şifreleme Politikası
Önce bir S3 bucket’ının varsayılan şifrelemesini CMK ile kuralım:
# KMS anahtarı oluştur
aws kms create-key
--description "S3 bucket encryption key - production"
--key-usage ENCRYPT_DECRYPT
--origin AWS_KMS
# Anahtara alias ekle
aws kms create-alias
--alias-name alias/s3-prod-encryption
--target-key-id "arn:aws:kms:eu-west-1:123456789:key/xxxx-xxxx"
# S3 bucket'a varsayılan şifreleme uygula
aws s3api put-bucket-encryption
--bucket my-production-bucket
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "alias/s3-prod-encryption"
},
"BucketKeyEnabled": true
}]
}'
Burada BucketKeyEnabled: true kritik bir detay. Bu özelliği açmazsanız her S3 nesne erişiminde ayrı bir KMS API çağrısı yapılır. Büyük ölçekte bu hem performans sorunu hem de ciddi maliyet kalemı oluşturur. Bucket Key aktif olduğunda KMS çağrı sayısı dramatik biçimde düşer.
Şifreli olmayan nesnelerin bucket’a eklenmesini engelleyen policy:
# Şifrelenmemiş upload'ları reddeden bucket policy
aws s3api put-bucket-policy
--bucket my-production-bucket
--policy '{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyUnencryptedUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-production-bucket/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
}
}
}]
}'
RDS ve EBS Şifreleme
RDS instance oluştururken şifreleme:
# Şifreli RDS instance oluştur
aws rds create-db-instance
--db-instance-identifier prod-database
--db-instance-class db.r6g.large
--engine postgres
--engine-version 15.4
--master-username dbadmin
--master-user-password "SecurePass123!"
--allocated-storage 100
--storage-encrypted
--kms-key-id alias/rds-prod-encryption
--backup-retention-period 7
--deletion-protection
# Mevcut şifresiz EBS volume'ü şifreli hale getir
# Önce snapshot al
aws ec2 create-snapshot
--volume-id vol-0123456789abcdef0
--description "Pre-encryption snapshot"
# Snapshot'tan şifreli kopya oluştur
aws ec2 copy-snapshot
--source-region eu-west-1
--source-snapshot-id snap-0123456789abcdef0
--encrypted
--kms-key-id alias/ebs-prod-encryption
--region eu-west-1
Mevcut şifresiz bir RDS database’iniz varsa ve onu şifreli hale getirmeniz gerekiyorsa, doğrudan dönüştürme mümkün değil. Snapshot alıp şifreli kopya oluşturup oradan restore etmek gerekiyor. Bu yüzden başından şifreli kurmanızı şiddetle tavsiye ederim.
KMS Anahtar Rotasyonu
# Otomatik anahtar rotasyonunu aktif et
aws kms enable-key-rotation
--key-id alias/s3-prod-encryption
# Rotasyon durumunu kontrol et
aws kms get-key-rotation-status
--key-id alias/s3-prod-encryption
# Tüm KMS anahtarlarının rotasyon durumunu listele
aws kms list-keys --query 'Keys[*].KeyId' --output text |
tr 't' 'n' |
while read key_id; do
status=$(aws kms get-key-rotation-status --key-id "$key_id"
--query 'KeyRotationEnabled' --output text 2>/dev/null)
echo "$key_id: Rotation=$status"
done
AWS KMS otomatik rotasyon her 365 günde bir gerçekleşir. Rotasyon sonrası eski anahtarla şifrelenmiş veriler otomatik olarak yeni anahtarla tekrar şifrelenmez, ancak eski anahtar materyali saklanmaya devam eder ve mevcut veriler okunabilir kalır.
Azure Ortamında Şifreleme
Azure’da benzer konseptler farklı isimlerle geliyor. Azure Key Vault, AWS KMS’in karşılığı. Customer-Managed Keys için BYOK (Bring Your Own Key) ya da Azure Key Vault’ta oluşturulan CMK kullanabilirsiniz.
# Azure Key Vault oluştur
az keyvault create
--name prod-keyvault-01
--resource-group production-rg
--location westeurope
--sku premium
--enable-purge-protection true
--enable-soft-delete true
--retention-days 90
# Şifreleme anahtarı oluştur
az keyvault key create
--vault-name prod-keyvault-01
--name storage-encryption-key
--kty RSA
--size 4096
--protection hsm
# Storage account'a CMK uygula
az storage account update
--name mystorageaccount
--resource-group production-rg
--encryption-key-source Microsoft.Keyvault
--encryption-key-vault https://prod-keyvault-01.vault.azure.net/
--encryption-key-name storage-encryption-key
--encryption-key-version ""
--enable-purge-protection true ayarını mutlaka aktif edin. Aksi halde birisi Key Vault’u silerse anahtarlarınız geri dönüşü olmaksızın kaybolur ve verilerinize erişemezsiniz. Bu bir kurtarma senaryosu değil, kalıcı veri kaybı demektir.
GCP Ortamında Şifreleme
Google Cloud’da şifreleme için Cloud KMS ve CMEK (Customer-Managed Encryption Keys) kullanılıyor:
# KMS keyring oluştur
gcloud kms keyrings create prod-keyring
--location europe-west1
# Şifreleme anahtarı oluştur
gcloud kms keys create gcs-encryption-key
--keyring prod-keyring
--location europe-west1
--purpose encryption
--rotation-period 7776000s
--next-rotation-time "2024-01-01T00:00:00Z"
# GCS bucket'a CMEK uygula
gcloud storage buckets update gs://my-production-bucket
--default-encryption-key projects/my-project/locations/europe-west1/keyRings/prod-keyring/cryptoKeys/gcs-encryption-key
# BigQuery dataset'e CMEK uygula
bq update
--default_kms_key projects/my-project/locations/europe-west1/keyRings/prod-keyring/cryptoKeys/bq-encryption-key
my-project:production_dataset
GCP’nin güzel özelliklerinden biri rotation-period parametresini doğrudan anahtar oluştururken belirleyebilmeniz. AWS’de bunu sonradan enable etmeniz gerekiyor.
Transit Şifreleme ve TLS Yönetimi
Durağan veri şifrelemesini kurdunuz, harika. Peki veriler servisler arasında hareket ederken ne oluyor?
# Let's Encrypt ile certificate oluştur ve yenile (certbot)
certbot certonly
--dns-route53
--domain "*.production.example.com"
--email [email protected]
--agree-tos
--non-interactive
# Nginx'de TLS 1.3 only konfigürasyonu
cat > /etc/nginx/snippets/ssl-params.conf << 'EOF'
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000" always;
EOF
# Internal servisler arası mTLS için sertifika oluştur (örnek: microservice mesh)
# Self-signed CA oluştur
openssl req -x509 -newkey rsa:4096
-keyout /etc/ssl/private/internal-ca.key
-out /etc/ssl/certs/internal-ca.crt
-days 3650
-nodes
-subj "/CN=Internal-CA/O=Production/C=TR"
# Servis sertifikası oluştur
openssl req -newkey rsa:2048
-keyout /etc/ssl/private/service-a.key
-out /tmp/service-a.csr
-nodes
-subj "/CN=service-a.internal/O=Production/C=TR"
openssl x509 -req
-in /tmp/service-a.csr
-CA /etc/ssl/certs/internal-ca.crt
-CAkey /etc/ssl/private/internal-ca.key
-CAcreateserial
-out /etc/ssl/certs/service-a.crt
-days 365
Microservice mimarinizde servisler arası iletişimi şifrelemek için mTLS (mutual TLS) kullanın. Istio veya Linkerd gibi service mesh çözümleri bunu otomatik hale getirir, ancak sertifika yaşam döngüsü yönetimini hala takip etmeniz gerekir.
Gerçek Dünya Senaryosu: Veri Sızıntısını Şifrelemeyle Sınırlamak
Bir e-ticaret şirketinde çalıştığınızı düşünün. Müşteri kartı bilgileri ve kişisel veriler var. Bir uygulama katmanındaki zafiyet nedeniyle saldırgan S3’e erişim sağladı. Eğer:
- Tüm S3 nesneleri CMK ile şifreliyse
- KMS key policy’si sadece belirli IAM rolleri ve IP aralıklarından erişime izin veriyorsa
- CloudTrail ile KMS API çağrıları loglanıyorsa
Saldırgan nesneleri indirebilir ama şifrelenmiş blob’larla karşılaşır. KMS’e erişimi olmadığı için şifreyi çözemez.
# KMS key policy'sine IP kısıtlaması ekle
aws kms put-key-policy
--key-id alias/s3-prod-encryption
--policy-name default
--policy '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowRootAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "AllowAppRoleWithIPRestriction",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789:role/app-production-role"
},
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Resource": "*",
"Condition": {
"IpAddress": {
"aws:SourceIp": ["10.0.0.0/8", "172.16.0.0/12"]
}
}
}
]
}'
Envelope Şifreleme ve Uygulama Katmanı Şifrelemesi
Bulut sağlayıcı şifrelemesine güvenmek istemiyorsanız veya ekstra bir katman istiyorsanız, uygulama katmanında da şifreleme yapabilirsiniz. Bu yaklaşım envelope encryption prensibi üzerine kuruludur: verilerinizi bir data key ile şifrelersiniz, data key’i ise KMS ile şifrelersiniz.
#!/usr/bin/env python3
# AWS SDK ile envelope encryption örneği
import boto3
import os
from cryptography.fernet import Fernet
import base64
def encrypt_data(plaintext: bytes, kms_key_id: str) -> dict:
"""Envelope encryption uygula"""
kms = boto3.client('kms', region_name='eu-west-1')
# KMS'ten data key üret
response = kms.generate_data_key(
KeyId=kms_key_id,
KeySpec='AES_256'
)
plaintext_key = response['Plaintext'] # RAM'de kısa süre tutulan temiz anahtar
encrypted_key = response['CiphertextBlob'] # KMS ile şifrelenmiş anahtar
# Veriyi plaintext key ile şifrele
fernet_key = base64.urlsafe_b64encode(plaintext_key[:32])
f = Fernet(fernet_key)
encrypted_data = f.encrypt(plaintext)
# Plaintext key'i bellekten temizle
del plaintext_key
return {
'encrypted_data': encrypted_data,
'encrypted_key': encrypted_key
}
def decrypt_data(encrypted_package: dict) -> bytes:
"""Veriyi çöz"""
kms = boto3.client('kms', region_name='eu-west-1')
# Şifrelenmiş data key'i KMS ile çöz
response = kms.decrypt(
CiphertextBlob=encrypted_package['encrypted_key']
)
plaintext_key = response['Plaintext']
fernet_key = base64.urlsafe_b64encode(plaintext_key[:32])
f = Fernet(fernet_key)
return f.decrypt(encrypted_package['encrypted_data'])
Bu yaklaşımı özellikle şu durumlarda kullanıyoruz: Düzenleyici gereklilikler nedeniyle “cloud sağlayıcı veriye erişemez” kanıtlaması gerektiğinde veya çok hassas veriler (sağlık, finans) söz konusu olduğunda.
Şifreleme Maliyetleri ve Optimizasyon
Şifreleme ücretsiz değil. AWS KMS örneğinden gidersek:
- KMS API çağrısı başına maliyet var (yaklaşık 0.03 USD per 10.000 istek)
- Büyük ölçekte milyonlarca S3 nesne erişiminiz varsa bu maliyet önemli olabilir
Optimizasyon stratejileri:
- S3 Bucket Key kullanın: Her nesne erişiminde KMS çağrısı yerine bucket seviyesinde data key cache’lemesi yapar. Bu tek ayar ile KMS maliyetini yüzde 99’a kadar düşürebilir.
- Aynı veriyi birden fazla kez şifrelemeyin: Zaten şifreli bir veriyi tekrar şifrelemenin anlamı yok.
- Sık erişilen veriler için performans testleri yapın: Şifreleme gecikmeyi artırır, bu etkiyi ölçün.
- Arşiv verileri için farklı strateji: Glacier’da duran ve yıllarca açılmayacak veriler için anahtar yönetimi karmaşıklığını minimize edin.
# KMS maliyetini izlemek için CloudWatch metrik
aws cloudwatch get-metric-statistics
--namespace AWS/KMS
--metric-name NumberOfRequestsSucceeded
--dimensions Name=KeyId,Value=alias/s3-prod-encryption
--start-time 2024-01-01T00:00:00Z
--end-time 2024-01-31T23:59:59Z
--period 86400
--statistics Sum
--query 'Datapoints[*].[Timestamp,Sum]'
--output table
Uyumluluk ve Denetim
Şifreleme uygulamak yeterli değil; kanıtlamanız da gerekiyor. GDPR, PCI-DSS, HIPAA gibi regülasyonlar için şifrelemenin sürekli aktif olduğunu göstermelisiniz.
# AWS Config rule ile şifrelenmemiş S3 bucket'ları tespit et
aws configservice put-config-rule
--config-rule '{
"ConfigRuleName": "s3-bucket-server-side-encryption-enabled",
"Source": {
"Owner": "AWS",
"SourceIdentifier": "S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED"
},
"Scope": {
"ComplianceResourceTypes": ["AWS::S3::Bucket"]
}
}'
# Uyumsuz kaynakları listele
aws configservice get-compliance-details-by-config-rule
--config-rule-name s3-bucket-server-side-encryption-enabled
--compliance-types NON_COMPLIANT
--query 'EvaluationResults[*].EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId'
Ayrıca AWS Security Hub veya Azure Security Center gibi araçları açın. Bunlar şifreleme eksikliklerini otomatik olarak raporlar ve uyumluluk skorunuzu gösterir.
Anahtar Yönetimi Operasyonları
Anahtar yönetimi “bir kere kur unut” değil. Şu senaryolara hazırlıklı olmanız gerekiyor:
- Personel değişikliğinde anahtar erişim politikalarını güncelleme
- Compromised key senaryosunda acil rotasyon
- Disaster recovery durumunda anahtarların başka bölgede de kullanılabilir olması
# Multi-region KMS key oluştur (AWS)
aws kms create-key
--description "Multi-region production key"
--multi-region true
--key-usage ENCRYPT_DECRYPT
# Primary key'i başka bölgeye replika et
aws kms replicate-key
--key-id arn:aws:kms:eu-west-1:123456789:key/mrk-xxxx
--replica-region us-east-1
# Acil anahtar devre dışı bırakma (compromise durumunda)
aws kms disable-key
--key-id alias/compromised-key
# Acil sonrası yeni anahtar oluştur ve servisleri migrate et
aws kms create-key
--description "Emergency replacement key"
Multi-region key kullanımı disaster recovery planınızın bir parçası olmalı. Özellikle aktif-aktif ya da aktif-pasif çoklu bölge mimarisi kuruyorsanız, anahtarlarınızın sadece bir bölgede olması ciddi bir tek nokta arıza riski demek.
Sonuç
Bulut ortamında şifreleme, tek seferlik bir kurulum değil; sürekli yönetim gerektiren bir disiplin. Pratik özet olarak şunları söyleyebilirim:
- Baştan doğru kurun: Sonradan şifrelemeye geçmek hem zahmetli hem riskli. Her yeni kaynak için şifrelemeyi varsayılan yapın.
- CMK kullanın: Provider-managed keys kolayken, uyumluluk ve kontrol açısından customer-managed keys tercih edin.
- Anahtar rotasyonunu otomatize edin: Manuel rotasyon er ya da geç unutulur.
- Maliyeti göz ardı etmeyin: Özellikle yüksek istek hacimlerinde Bucket Key gibi optimizasyonları kullanın.
- Denetim izlerini saklayın: CloudTrail, Key Vault logs, Cloud Audit Logs… Bunlar hem güvenlik hem uyumluluk için altın değerinde.
- DR senaryonuzu şifreleyerek test edin: Şifreli backup’lardan restore yapabildiğinizi periyodik olarak doğrulayın.
Şifreleme stratejiniz ne kadar güçlü olursa olsun, yanlış IAM politikaları veya sızdırılmış credentials tüm çabayı boşa çıkarabilir. Şifreleme, genel güvenlik mimarinizin bir katmanı olarak düşünülmeli, tek savunma hattı olarak değil.
