Azure Blob Storage Erişim Kontrolü: Kapsamlı Yönetim Rehberi

Bulut ortamında veri güvenliğinin en kritik noktalarından biri, depolama kaynaklarına kimin, nasıl ve ne zaman erişebileceğini kontrol etmektir. Azure Blob Storage kullanıyorsanız ve “ben sadece public container açtım, ne olabilir ki?” diye düşünüyorsanız, bu yazı tam size göre. Gerçek dünyada gördüğüm onlarca yanlış yapılandırma ve bunların sonuçlarından yola çıkarak Azure Blob Storage erişim kontrolünü A’dan Z’ye ele alacağız.

Azure Blob Storage Erişim Modelleri

Azure Blob Storage’da erişim kontrolü katmanlı bir yapıdan oluşur. En dıştan en içe doğru bakarsak şu katmanları görürüz:

  • Storage Account Level: Tüm storage account’a genel erişim kuralları
  • Container Level: Belirli bir container’a özel erişim ayarları
  • Blob Level: Tek bir blob nesnesine özel erişim kontrolü

Bu katmanlı yapıyı anlamadan yapılandırma yapmaya çalışmak, binanın çatısını tamir etmeye çalışırken bodrum katının sular altında kalmasına izin vermek gibidir.

Anonymous Access ve Neden Tehlikelidir

Azure Blob Storage’da container’lar için üç farklı erişim seviyesi mevcuttur:

  • Private: Yalnızca yetkili istekler erişebilir, anonim erişim tamamen kapalıdır
  • Blob: Anonim kullanıcılar blob’lara doğrudan URL ile erişebilir ama container’ı listeleyemez
  • Container: Anonim kullanıcılar hem blob’lara erişebilir hem de container içeriğini listeleyebilir

2021 yılında büyük bir e-ticaret firmasıyla çalışırken “Container” seviyesinde public erişim açık bırakılmış bir storage account keşfettik. İçinde müşteri sipariş faturalarının PDF halleri vardı. Kimse farkında değildi çünkü “zaten URL’yi kimse bilmiyor” mantığıyla hareket edilmişti. Security through obscurity’nin ne kadar işe yaramadığını bir kez daha gördük.

İlk yapmanız gereken şey storage account seviyesinde public erişimi tamamen devre dışı bırakmak olmalıdır:

# Storage account için public blob erişimini devre dışı bırak
az storage account update 
  --name mystorageaccount 
  --resource-group myResourceGroup 
  --allow-blob-public-access false

# Mevcut durumu kontrol et
az storage account show 
  --name mystorageaccount 
  --resource-group myResourceGroup 
  --query "allowBlobPublicAccess"

Bu komut storage account seviyesinde kilidi kapatır. Artık bu account altındaki hiçbir container public erişime açılamaz.

Azure RBAC ile Erişim Yönetimi

Azure Role-Based Access Control (RBAC), kim ne yapabilir sorusunun cevabını vermenin en modern ve ölçeklenebilir yoludur. Blob Storage için hazır rolleri şöyle sıralayabiliriz:

  • Storage Blob Data Owner: Tam kontrol, POSIX ACL yönetimi dahil
  • Storage Blob Data Contributor: Okuma, yazma ve silme yapabilir
  • Storage Blob Data Reader: Yalnızca okuma yapabilir
  • Storage Blob Delegator: SAS token üretmek için gerekli
  • Storage Queue Data Contributor: Queue işlemleri için
  • Storage Account Contributor: Account yönetimi ama veri erişimi değil (önemli fark!)

Storage Account Contributor ile Storage Blob Data Contributor arasındaki farkı iyi anlamak gerekir. İlki Azure management plane’de storage account’u yönetir ama blob verilerine doğrudan erişemez. İkincisi ise blob verilerine erişebilir ama account ayarlarını değiştiremez. Production ortamında bu rolleri birbirinden ayırmak şarttır.

# Bir kullanıcıya belirli bir container üzerinde Reader yetkisi ver
az role assignment create 
  --assignee "[email protected]" 
  --role "Storage Blob Data Reader" 
  --scope "/subscriptions/SUBSCRIPTION_ID/resourceGroups/myRG/providers/Microsoft.Storage/storageAccounts/mystorageaccount/blobServices/default/containers/mycontainer"

# Service principal'a Contributor yetkisi ver
az role assignment create 
  --assignee "SERVICE_PRINCIPAL_CLIENT_ID" 
  --role "Storage Blob Data Contributor" 
  --scope "/subscriptions/SUBSCRIPTION_ID/resourceGroups/myRG/providers/Microsoft.Storage/storageAccounts/mystorageaccount"

# Mevcut role assignment'ları listele
az role assignment list 
  --scope "/subscriptions/SUBSCRIPTION_ID/resourceGroups/myRG/providers/Microsoft.Storage/storageAccounts/mystorageaccount" 
  --output table

Shared Access Signatures (SAS) Kullanımı

SAS token’lar, belirli bir süre için belirli kaynaklara sınırlı erişim vermenin en pratik yoludur. Bir müşteriye 24 saatliğine bir dosyayı indirme linki göndermek istiyorsanız, SAS tam size göre. Ama burada da tuzaklar var.

SAS token türleri:

  • Account SAS: Tüm storage servislerine (blob, queue, table, file) erişim
  • Service SAS: Belirli bir servise erişim
  • User Delegation SAS: Azure AD kimlik bilgileriyle imzalanmış, en güvenli yöntem
  • Stored Access Policy: Container seviyesinde politika ile bağlantılı SAS
# Belirli bir blob için 1 saatlik okuma izinli SAS token oluştur
az storage blob generate-sas 
  --account-name mystorageaccount 
  --container-name mycontainer 
  --name myfile.pdf 
  --permissions r 
  --expiry $(date -u -d "1 hour" '+%Y-%m-%dT%H:%MZ') 
  --auth-mode login 
  --as-user 
  --output tsv

# Container seviyesinde SAS oluştur (liste + okuma)
az storage container generate-sas 
  --account-name mystorageaccount 
  --name mycontainer 
  --permissions rl 
  --expiry $(date -u -d "24 hours" '+%Y-%m-%dT%H:%MZ') 
  --auth-mode login 
  --as-user 
  --output tsv

--as-user parametresi kullanıldığında User Delegation SAS üretilir. Bu yöntemde token, Azure AD credential’larınızla imzalanır ve account key’e gerek kalmaz. Güvenlik açısından bu tercih edilmesi gereken yöntemdir.

SAS Token’larda Yapılan Klasik Hatalar

  • Çok uzun expiry süresi: “Belki lazım olur” diye 1 yıllık SAS token oluşturmak
  • Fazla izin vermek: Okuma yetecekken read+write+delete vermek
  • IP kısıtlaması koymamak: Belli bir IP veya IP aralığından erişim kısıtlanabilir
  • HTTPS zorunluluğunu kaldırmak: HTTP üzerinden SAS kullanmak veriyi açık eder
# IP kısıtlamalı ve HTTPS zorunlu SAS token
az storage blob generate-sas 
  --account-name mystorageaccount 
  --container-name mycontainer 
  --name sensitive-report.xlsx 
  --permissions r 
  --expiry $(date -u -d "2 hours" '+%Y-%m-%dT%H:%MZ') 
  --ip "203.0.113.0-203.0.113.255" 
  --https-only 
  --auth-mode login 
  --as-user 
  --output tsv

Storage Account Key Yönetimi

Account key’ler storage account’a tam erişim sağlar. Root password muamelesi görmeli. Pratikte çok sık gördüğüm sorun şu: geliştiriciler test sırasında account key’i kullanıp bunu koda gömiyor, sonra kod Git’e push ediliyor. Oradan GitHub’a gidiyor. Security scanner’lar dakikalar içinde bu key’leri buluyor.

# Account key'leri listele
az storage account keys list 
  --account-name mystorageaccount 
  --resource-group myResourceGroup

# Key'i rotate et (önce key2'yi rotate et, uygulamaları güncelle, sonra key1'i rotate et)
az storage account keys renew 
  --account-name mystorageaccount 
  --resource-group myResourceGroup 
  --key key2

# Key erişimini tamamen devre dışı bırak (yalnızca Azure AD kullan)
az storage account update 
  --name mystorageaccount 
  --resource-group myResourceGroup 
  --allow-shared-key-access false

--allow-shared-key-access false ayarı, account key ve SAS token (account key ile imzalanmış olanlar) kullanımını tamamen devre dışı bırakır. Bu noktadan sonra yalnızca Azure AD tabanlı kimlik doğrulama çalışır. Production’da yönetilebilir bir ortamınız varsa bu ayarı mutlaka aktif edin.

Network Level Erişim Kontrolü

RBAC ve SAS ile kimlik bazlı kontrolü hallettik. Şimdi network katmanına bakalım. Azure Storage Firewall, storage account’unuza hangi network’lerden erişilebileceğini kontrol eder.

  • Default action deny: Tanımlanmamış tüm kaynaklardan gelen trafiği engelle
  • Virtual Network rules: Belirli VNet subnet’lerinden erişime izin ver
  • IP network rules: Belirli IP adresleri veya aralıklarından erişime izin ver
  • Resource instances: Azure servisleri için istisna tanımla
# Default erişimi deny'a çek
az storage account update 
  --name mystorageaccount 
  --resource-group myResourceGroup 
  --default-action Deny

# Ofis IP adresinden erişime izin ver
az storage account network-rule add 
  --account-name mystorageaccount 
  --resource-group myResourceGroup 
  --ip-address "203.0.113.10"

# Bir VNet subnet'inden erişime izin ver
az storage account network-rule add 
  --account-name mystorageaccount 
  --resource-group myResourceGroup 
  --vnet-name myVNet 
  --subnet mySubnet

# Mevcut network kurallarını göster
az storage account network-rule list 
  --account-name mystorageaccount 
  --resource-group myResourceGroup

Private Endpoint Kullanımı

Daha güçlü bir izolasyon için Private Endpoint kullanmak gerekir. Bu yöntemde storage account, public internet’e tamamen kapalı olup yalnızca Azure private network üzerinden erişilebilir olur.

# Private endpoint oluştur
az network private-endpoint create 
  --name myStoragePrivateEndpoint 
  --resource-group myResourceGroup 
  --vnet-name myVNet 
  --subnet mySubnet 
  --private-connection-resource-id "/subscriptions/SUBSCRIPTION_ID/resourceGroups/myRG/providers/Microsoft.Storage/storageAccounts/mystorageaccount" 
  --group-id blob 
  --connection-name myStorageConnection

# Private endpoint network policy'yi subnet'te devre dışı bırak
az network vnet subnet update 
  --name mySubnet 
  --resource-group myResourceGroup 
  --vnet-name myVNet 
  --disable-private-endpoint-network-policies true

Private endpoint kurulduktan sonra storage account’u yalnızca private network’ten erişilebilir hale getirmek için public network erişimini kapatın:

az storage account update 
  --name mystorageaccount 
  --resource-group myResourceGroup 
  --public-network-access Disabled

Managed Identity ile Uygulama Erişimi

Uygulamalarınız blob storage’a erişmesi gerekiyorsa credential kullanmaktan kaçının. Azure Managed Identity bu problemi çözer. VM veya App Service’e atadığınız system-assigned ya da user-assigned identity, Azure AD’den otomatik token alır.

Gerçek dünya senaryosu: Bir Azure App Service uygulaması blob storage’dan konfigürasyon dosyası okuyor olsun. Connection string’i App Settings’e gömmek yerine Managed Identity kullanın:

# App Service için system-assigned managed identity aktif et
az webapp identity assign 
  --name myAppService 
  --resource-group myResourceGroup

# Dönen principal ID'yi al
PRINCIPAL_ID=$(az webapp identity show 
  --name myAppService 
  --resource-group myResourceGroup 
  --query principalId 
  --output tsv)

# Bu identity'e storage'a okuma yetkisi ver
az role assignment create 
  --assignee $PRINCIPAL_ID 
  --role "Storage Blob Data Reader" 
  --scope "/subscriptions/SUBSCRIPTION_ID/resourceGroups/myRG/providers/Microsoft.Storage/storageAccounts/mystorageaccount"

Uygulama kodunda credential geçmenize gerek kalmaz. Azure SDK otomatik olarak managed identity token’ını kullanır. Bu yaklaşım hem güvenli hem de maintain edilmesi kolaydır çünkü döngüsel token yenileme SDK tarafından otomatik yapılır.

Azure Policy ile Uyumluluk Zorlama

Tek bir storage account’u güvenli hale getirmek yeterli değil. Tüm organizasyonun güvenlik standartlarına uymasını sağlamak için Azure Policy devreye girer.

En önemli built-in policy tanımları:

  • Storage accounts should not allow public blob access: Public blob erişimini engeller
  • Storage accounts should use customer-managed key encryption: CMK şifrelemeyi zorunlu kılar
  • Secure transfer to storage accounts should be enabled: HTTPS zorunluluğu
  • Storage accounts should restrict network access: Network firewall kuralı zorunluluğu
# Tüm subscription'da public blob erişimini audit et
az policy assignment create 
  --name "deny-public-blob-access" 
  --policy "/providers/Microsoft.Authorization/policyDefinitions/4fa4b6c0-31ca-4c0d-b10d-24b96f62a751" 
  --scope "/subscriptions/SUBSCRIPTION_ID" 
  --enforcement-mode Default

# Compliant olmayan resource'ları listele
az policy state list 
  --policy-assignment "deny-public-blob-access" 
  --filter "complianceState eq 'NonCompliant'" 
  --query "[].{Resource:resourceId, State:complianceState}" 
  --output table

Loglama ve İzleme

Erişim kontrolü kuralları ne kadar iyi olursa olsun, kim ne zaman neye erişti sorusunu cevaplayabilmek gerekir. Azure Storage için iki ana log kaynağı var:

  • Azure Monitor Diagnostic Logs: API çağrılarının detaylı logları
  • Storage Analytics Logs: Klasik loglama mekanizması
# Diagnostic settings ile Log Analytics'e log gönder
az monitor diagnostic-settings create 
  --name "BlobStorageLogs" 
  --resource "/subscriptions/SUBSCRIPTION_ID/resourceGroups/myRG/providers/Microsoft.Storage/storageAccounts/mystorageaccount/blobServices/default" 
  --workspace "/subscriptions/SUBSCRIPTION_ID/resourceGroups/myRG/providers/Microsoft.OperationalInsights/workspaces/myLogAnalytics" 
  --logs '[{"category": "StorageRead", "enabled": true}, {"category": "StorageWrite", "enabled": true}, {"category": "StorageDelete", "enabled": true}]' 
  --metrics '[{"category": "Transaction", "enabled": true}]'

# Log Analytics'te başarısız erişim denemelerini sorgula
# KQL sorgusu (Log Analytics workspace'te çalıştırın):
# StorageBlobLogs
# | where StatusCode == 403
# | project TimeGenerated, CallerIpAddress, OperationName, Uri
# | order by TimeGenerated desc
# | take 100

Microsoft Defender for Storage’ı da aktif etmenizi öneririm. Anormal erişim patternlerini, potansiyel veri exfiltration girişimlerini ve kötü amaçlı dosya yüklemelerini otomatik olarak tespit eder:

# Defender for Storage aktif et
az security atp storage update 
  --resource-group myResourceGroup 
  --storage-account mystorageaccount 
  --is-enabled true

Encryption ve Ek Güvenlik Katmanları

Erişim kontrolünü tamamlayan şifreleme katmanı da ihmal edilmemelidir:

  • SSE (Server-Side Encryption): Varsayılan olarak aktif, Microsoft-managed key ile
  • Customer-Managed Keys (CMK): Key Vault’taki kendi anahtarınızla şifreleme
  • Client-Side Encryption: Veriyi Azure’a göndermeden önce şifrele
  • Infrastructure Encryption: Double encryption, özellikle compliance gereksinimleri için
# Customer-managed key ile şifreleme aktif et
az storage account update 
  --name mystorageaccount 
  --resource-group myResourceGroup 
  --encryption-key-source Microsoft.Keyvault 
  --encryption-key-vault "https://mykeyvault.vault.azure.net" 
  --encryption-key-name myStorageKey 
  --encryption-key-version KEY_VERSION 
  --encryption-services blob

# Infrastructure encryption aktif et (account oluşturma sırasında yapılmalı)
az storage account create 
  --name mystorageaccount 
  --resource-group myResourceGroup 
  --location eastus 
  --sku Standard_LRS 
  --require-infrastructure-encryption true

Gerçek Dünya Senaryosu: Finans Firması için Güvenli Blob Storage

Geçen yıl bir finans şirketine danışmanlık yaparken şu yapıyı kurmuştuk:

İhtiyaçlar:

  • Müşteri ekstreleri PDF olarak blob’da tutulacak
  • Her müşteri yalnızca kendi belgelerine erişebilecek
  • Uygulama sunucuları sanal ağ üzerinden erişecek
  • Denetim amaçlı tüm erişimler loglanacak
  • GDPR uyumluluğu için veri silme talepleri hızlı karşılanabilecek

Çözüm yaklaşımı:

  • Public erişim tamamen kapalı
  • Private endpoint ile uygulama VNet’i bağlantısı
  • Managed Identity üzerinden uygulama erişimi
  • Container bazında müşteri segmentasyonu yerine blob path yapısı: statements/{customerID}/{year}/{month}/statement.pdf
  • SAS token ile müşteriye geçici indirme linki (2 saatlik, IP kısıtlı)
  • Diagnostic logs Log Analytics’e, retention 90 gün
  • CMK şifreleme Key Vault üzerinden
  • Soft delete aktif, 30 gün retention
  • Azure Policy ile tüm bu kuralların drift detection’ı

Bu yapı sayesinde bir güvenlik denetiminde sıfır bulgu ile çıktılar. Mükemmel bir başarı değil, ama doğru yapılandırmanın somut bir sonucu.

Sonuç

Azure Blob Storage erişim kontrolü tek bir ayarla bitmiyor. Kimlik katmanı, network katmanı, şifreleme katmanı ve izleme katmanı bir arada çalışmak zorunda. Benim önerdiğim kontrol listesi şu şekilde:

  • Public erişimi storage account seviyesinde kapatın, istisnasız
  • RBAC kullanın, account key’leri yalnızca gerektiğinde kullanın ve rotate edin
  • Managed Identity kullanarak uygulamalarınızı credential’sız hale getirin
  • Network firewall kuralları ile trafiği kısıtlayın, mümkünse private endpoint kullanın
  • SAS token üretirken minimum izin, kısa süre ve IP kısıtlaması prensibini uygulayın
  • Diagnostic logging ile tüm erişimleri kayıt altına alın
  • Azure Policy ile konfigürasyon standartlarını otomatik denetleyin
  • Defender for Storage ile tehdit tespitini otomatize edin

Bulut güvenliği “bir kez yapılıp bırakılan” bir alan değil. Haftalık bazda erişim kontrollerini, aylık bazda key rotation’ı ve sürekli policy compliance raporlamasını rutin hale getirin. Güvenlik bir ürün değil, bir süreçtir.

Bir yanıt yazın

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