Azure Subnet ve NSG Yönetimi: Ağ Güvenliğini Doğru Yapılandırma
Azure üzerinde ağ yönetimi, bulut altyapısının en kritik parçalarından biri. Özellikle kurumsal ortamlarda subnet planlama ve NSG kurallarının doğru yapılandırılması, hem güvenlik hem de operasyonel sürdürülebilirlik açısından belirleyici oluyor. Yanlış yapılandırılmış bir NSG, production servisini çökertebileceği gibi güvenlik açığı da yaratabilir. Bu yazıda Azure Subnet ve NSG yönetimini, gerçek dünya senaryolarıyla birlikte ele alacağız.
Azure Sanal Ağ ve Subnet Temelleri
Azure’da her şey bir Virtual Network (VNet) etrafında şekilleniyor. VNet, Azure kaynaklarının birbirleriyle ve dış dünyayla nasıl iletişim kuracağını belirleyen mantıksal bir yalıtım sınırı. Subnet’ler ise bu VNet’in daha küçük parçalara bölünmüş halleri.
Tipik bir kurumsal yapıda şöyle bir subnet mimarisi görürsünüz:
- 10.0.1.0/24: Web tier (Application Gateway, Front-end sunucular)
- 10.0.2.0/24: Application tier (Backend uygulamalar, API servisleri)
- 10.0.3.0/24: Data tier (SQL Server, Redis, Storage hesapları)
- 10.0.4.0/24: Management subnet (Bastion Host, Jump Server)
- 10.0.5.0/24: Gateway subnet (VPN Gateway veya ExpressRoute)
Bu ayrımı yapmak sadece düzeni sağlamak için değil, aynı zamanda NSG’leri daha granüler uygulamak için de kritik.
Azure CLI ile VNet ve Subnet Oluşturma
Önce temel yapıyı CLI üzerinden kuralım. Azure Portal üzerinden yapabilseniz de, tekrarlanabilir ve versiyon kontrol edilebilir altyapı için CLI veya ARM/Bicep şablonları çok daha mantıklı.
# Resource Group oluşturma
az group create
--name rg-production-network
--location westeurope
# VNet oluşturma
az network vnet create
--resource-group rg-production-network
--name vnet-production
--address-prefix 10.0.0.0/16
--location westeurope
# Web tier subnet
az network vnet subnet create
--resource-group rg-production-network
--vnet-name vnet-production
--name snet-web
--address-prefixes 10.0.1.0/24
# App tier subnet
az network vnet subnet create
--resource-group rg-production-network
--vnet-name vnet-production
--name snet-app
--address-prefixes 10.0.2.0/24
# Data tier subnet
az network vnet subnet create
--resource-group rg-production-network
--vnet-name vnet-production
--name snet-data
--address-prefixes 10.0.3.0/24
# Management subnet
az network vnet subnet create
--resource-group rg-production-network
--vnet-name vnet-production
--name snet-mgmt
--address-prefixes 10.0.4.0/24
Subnet isimlerinde snet- prefix’i kullanmak, Azure’un kendi naming convention önerilerine uygun. Büyük ortamlarda bu tür standartlar, kaynakları bulmayı ve yönetmeyi ciddi ölçüde kolaylaştırıyor.
Network Security Group Nedir ve Nasıl Çalışır?
NSG, Azure’daki sanal güvenlik duvarı mekanizması. Her NSG, gelen ve giden trafiği kontrol eden kurallar listesi içeriyor. NSG’ler hem subnet seviyesinde hem de NIC (Network Interface Card) seviyesinde uygulanabiliyor.
Önemli bir nokta: Trafik bir VM’ye ulaşmak istediğinde önce subnet NSG’si, ardından NIC NSG’si işleniyor. Çıkış trafiğinde ise sıra tersine dönüyor: önce NIC NSG, sonra subnet NSG.
Her NSG kuralının şu bileşenleri var:
- Öncelik (Priority): 100 ile 4096 arasında. Düşük sayı, yüksek öncelik anlamına geliyor. Azure’un built-in kuralları 65000, 65001, 65500 gibi yüksek numaralar kullanıyor.
- Kaynak/Hedef: IP adresi, CIDR bloğu, servis etiketi veya uygulama güvenlik grubu olabilir.
- Port: Tekil port, aralık (80-443) veya yıldız (*) ile tüm portlar.
- Protokol: TCP, UDP, ICMP veya Any.
- Eylem: Allow veya Deny.
Temel NSG Oluşturma ve Kural Yönetimi
# Web tier için NSG oluşturma
az network nsg create
--resource-group rg-production-network
--name nsg-web
--location westeurope
# HTTP trafiğine izin ver (kaynak: herhangi bir IP)
az network nsg rule create
--resource-group rg-production-network
--nsg-name nsg-web
--name Allow-HTTP-Inbound
--priority 100
--direction Inbound
--access Allow
--protocol Tcp
--source-address-prefixes '*'
--source-port-ranges '*'
--destination-address-prefixes '*'
--destination-port-ranges 80
# HTTPS trafiğine izin ver
az network nsg rule create
--resource-group rg-production-network
--nsg-name nsg-web
--name Allow-HTTPS-Inbound
--priority 110
--direction Inbound
--access Allow
--protocol Tcp
--source-address-prefixes '*'
--source-port-ranges '*'
--destination-address-prefixes '*'
--destination-port-ranges 443
# Azure Load Balancer health probe'larına izin ver
az network nsg rule create
--resource-group rg-production-network
--nsg-name nsg-web
--name Allow-AzureLoadBalancer
--priority 120
--direction Inbound
--access Allow
--protocol '*'
--source-address-prefixes AzureLoadBalancer
--source-port-ranges '*'
--destination-address-prefixes '*'
--destination-port-ranges '*'
# Diğer tüm inbound trafiği reddet
az network nsg rule create
--resource-group rg-production-network
--nsg-name nsg-web
--name Deny-All-Inbound
--priority 4000
--direction Inbound
--access Deny
--protocol '*'
--source-address-prefixes '*'
--source-port-ranges '*'
--destination-address-prefixes '*'
--destination-port-ranges '*'
# NSG'yi subnet'e bağla
az network vnet subnet update
--resource-group rg-production-network
--vnet-name vnet-production
--name snet-web
--network-security-group nsg-web
Servis Etiketleri ve Uygulama Güvenlik Grupları
Azure’un en pratik özelliklerinden biri Servis Etiketleri (Service Tags). Bunlar, belirli Azure servislerinin IP aralıklarını temsil eden önceden tanımlanmış gruplar. Manuel olarak IP adresi girmek yerine bu etiketleri kullanmak, hem daha güvenli hem de bakımı çok daha kolay.
Sık kullanılan servis etiketleri:
- Internet: Tüm internet IP aralıkları
- VirtualNetwork: VNet adres alanı ve bağlı ağlar
- AzureLoadBalancer: Azure yük dengeleyici probe IP’leri
- AzureCloud: Tüm Azure datacenter IP’leri
- Storage: Azure Storage servis IP’leri
- Sql: Azure SQL Database IP’leri
- AzureMonitor: Azure Monitor ve Log Analytics IP’leri
# App tier NSG - sadece web subnet'inden gelen trafiğe izin ver
az network nsg create
--resource-group rg-production-network
--name nsg-app
--location westeurope
az network nsg rule create
--resource-group rg-production-network
--nsg-name nsg-app
--name Allow-From-Web-Tier
--priority 100
--direction Inbound
--access Allow
--protocol Tcp
--source-address-prefixes 10.0.1.0/24
--source-port-ranges '*'
--destination-address-prefixes '*'
--destination-port-ranges 8080 8443
# Azure Monitor ve diagnostics için çıkış trafiği
az network nsg rule create
--resource-group rg-production-network
--nsg-name nsg-app
--name Allow-AzureMonitor-Outbound
--priority 100
--direction Outbound
--access Allow
--protocol Tcp
--source-address-prefixes '*'
--source-port-ranges '*'
--destination-address-prefixes AzureMonitor
--destination-port-ranges 443
Uygulama Güvenlik Grupları (ASG)
ASG’ler, sanal makineleri IP adresi yerine mantıksal gruplar halinde yönetmenizi sağlıyor. Özellikle aynı subnet içinde farklı roller oynayan VM’ler olduğunda çok işe yarıyor.
# ASG oluşturma
az network asg create
--resource-group rg-production-network
--name asg-webservers
--location westeurope
az network asg create
--resource-group rg-production-network
--name asg-appservers
--location westeurope
az network asg create
--resource-group rg-production-network
--name asg-dbservers
--location westeurope
# ASG kullanarak NSG kuralı oluşturma
az network nsg rule create
--resource-group rg-production-network
--nsg-name nsg-app
--name Allow-WebServers-To-AppServers
--priority 200
--direction Inbound
--access Allow
--protocol Tcp
--source-asgs asg-webservers
--source-port-ranges '*'
--destination-asgs asg-appservers
--destination-port-ranges 8080
# VM NIC'ini ASG'ye atama
az network nic update
--resource-group rg-production-network
--name vm-web01-nic
--add ipConfigurations[0].applicationSecurityGroups id=/subscriptions/<sub-id>/resourceGroups/rg-production-network/providers/Microsoft.Network/applicationSecurityGroups/asg-webservers
Gerçek Dünya Senaryosu: E-Ticaret Altyapısı
Diyelim ki bir e-ticaret şirketinin Azure altyapısını yönetiyorsunuz. Şu bileşenler var:
- Önünde Application Gateway olan 3 web sunucusu
- Backend API servisleri çalıştıran 4 uygulama sunucusu
- Azure SQL Managed Instance
- Redis Cache
- Azure Bastion üzerinden erişilen jump server
Bu senaryoda data tier NSG’sinin yapılandırması kritik:
# Data tier NSG
az network nsg create
--resource-group rg-production-network
--name nsg-data
--location westeurope
# SQL Server - sadece app subnet'inden
az network nsg rule create
--resource-group rg-production-network
--nsg-name nsg-data
--name Allow-SQL-From-App
--priority 100
--direction Inbound
--access Allow
--protocol Tcp
--source-address-prefixes 10.0.2.0/24
--source-port-ranges '*'
--destination-address-prefixes '*'
--destination-port-ranges 1433
# Redis - sadece app subnet'inden
az network nsg rule create
--resource-group rg-production-network
--nsg-name nsg-data
--name Allow-Redis-From-App
--priority 110
--direction Inbound
--access Allow
--protocol Tcp
--source-address-prefixes 10.0.2.0/24
--source-port-ranges '*'
--destination-address-prefixes '*'
--destination-port-ranges 6379 6380
# Management subnet'inden DB yönetimi
az network nsg rule create
--resource-group rg-production-network
--nsg-name nsg-data
--name Allow-SQL-From-Mgmt
--priority 120
--direction Inbound
--access Allow
--protocol Tcp
--source-address-prefixes 10.0.4.0/24
--source-port-ranges '*'
--destination-address-prefixes '*'
--destination-port-ranges 1433
# Her şeyi reddet
az network nsg rule create
--resource-group rg-production-network
--nsg-name nsg-data
--name Deny-All-Inbound
--priority 4000
--direction Inbound
--access Deny
--protocol '*'
--source-address-prefixes '*'
--source-port-ranges '*'
--destination-address-prefixes '*'
--destination-port-ranges '*'
NSG Flow Logs ve Troubleshooting
Production ortamda en sık karşılaşılan sorun, bağlantı kesintileri ve NSG kaynaklı trafik blokları. Azure’un NSG Flow Logs özelliği bu durumda hayat kurtarıyor.
# Network Watcher'ı etkinleştir (zaten yoksa)
az network watcher configure
--resource-group rg-production-network
--locations westeurope
--enabled true
# Storage account oluştur (flow logs için)
az storage account create
--resource-group rg-production-network
--name stflowlogsproduction
--location westeurope
--sku Standard_LRS
--kind StorageV2
# NSG Flow Logs'u etkinleştir
az network watcher flow-log create
--resource-group rg-production-network
--name flowlog-nsg-web
--nsg nsg-web
--storage-account stflowlogsproduction
--enabled true
--format JSON
--log-version 2
--retention 30
# Mevcut NSG kurallarını listele
az network nsg rule list
--resource-group rg-production-network
--nsg-name nsg-web
--output table
# Belirli bir NSG kuralını kontrol et
az network nsg rule show
--resource-group rg-production-network
--nsg-name nsg-web
--name Allow-HTTPS-Inbound
Bağlantı Sorunu Tespiti
Bir uygulamada bağlantı sorunu yaşandığında, Network Watcher’ın IP Flow Verify özelliği hangi NSG kuralının trafiği bloke ettiğini anında gösteriyor:
# IP Flow Verify - belirli bir trafiğin izin verilip verilmediğini test et
az network watcher test-ip-flow
--resource-group rg-production-network
--direction Inbound
--protocol TCP
--local 10.0.2.10:8080
--remote 10.0.1.5:45123
--vm vm-app01
--nic vm-app01-nic
# NSG'nin effective rules'ını görüntüle (hem subnet hem NIC NSG dahil)
az network nic list-effective-nsg
--resource-group rg-production-network
--name vm-app01-nic
--output json | python3 -m json.tool
Subnet Delegasyonu ve Servis Entegrasyonu
Bazı Azure servisleri, kendi subnet’lerine ihtiyaç duyuyor ya da subnet delegasyonu gerektiriyor. Azure SQL Managed Instance, App Service Environment, Azure Kubernetes Service gibi servisler bu kategoriye giriyor.
# App Service Environment için subnet oluşturma ve delege etme
az network vnet subnet create
--resource-group rg-production-network
--vnet-name vnet-production
--name snet-ase
--address-prefixes 10.0.6.0/24
--delegations Microsoft.Web/serverFarms
# Azure SQL Managed Instance için subnet
az network vnet subnet create
--resource-group rg-production-network
--vnet-name vnet-production
--name snet-sqlmi
--address-prefixes 10.0.7.0/28
--delegations Microsoft.Sql/managedInstances
# Service Endpoint ekleme (Storage için)
az network vnet subnet update
--resource-group rg-production-network
--vnet-name vnet-production
--name snet-app
--service-endpoints Microsoft.Storage Microsoft.Sql Microsoft.KeyVault
Dikkat edilmesi gereken nokta: Azure SQL Managed Instance için subnet en az /28 olmalı ama Microsoft, daha büyük bir subnet kullanmanızı öneriyor. Yetersiz IP adresi nedeniyle ilerleyen dönemde subnet’i büyütemezsiniz.
NSG Yönetiminde En İyi Pratikler
Yıllar içinde öğrendiğim bazı kritik pratikler var, bunları paylaşmadan geçemem:
- Deny-All kuralını varsayılan yap: NSG oluşturduğunuzda explicit bir Deny-All kuralı ekleyin. Böylece kasıtsız izinlerin önüne geçmiş olursunuz.
- Kural önceliklerini boşluklu ayarlayın: 100, 110, 120 yerine 100, 200, 300 gibi gruplandırın. İlgili kuralları 100-199, 200-299 gibi gruplar halinde tutmak, sonradan kural eklemeyi kolaylaştırır.
- Yorumları kullanın: NSG kurallarına açıklama ekleyin. Altı ay sonra kimse o kuralın neden eklendiğini hatırlamıyor.
- IP adresi yerine servis etiketi ve ASG kullanın: IP adresleri değişir, mantıksal gruplar değişmez.
- Flow Logs’u her zaman açık tutun: Maliyet düşünülerek kapatılıyor ama bir olay anında bu loglar paha biçilmez.
- Değişiklikleri test ortamında deneyin önce: Production NSG kuralı değişikliği, yanlış yapılandırıldığında tüm uygulamayı devre dışı bırakabilir.
- Düzenli NSG denetimi yapın: Gereksiz kuralları temizleyin. Zamanla NSG’ler çöp dolabilir.
# Tüm NSG'leri ve bağlı subnet/NIC'leri listele
az network nsg list
--resource-group rg-production-network
--query "[].{Name:name, SubnetCount:length(subnets), NicCount:length(networkInterfaces)}"
--output table
# Kullanılmayan NSG'leri bul (subnet veya NIC'e bağlı olmayan)
az network nsg list
--resource-group rg-production-network
--query "[?subnets==null && networkInterfaces==null].name"
--output tsv
Sonuç
Azure Subnet ve NSG yönetimi, ilk bakışta basit görünse de ölçek büyüdükçe karmaşıklaşan bir alan. Temel prensip her zaman aynı: en az ayrıcalık ilkesini uygula, trafiği segmentlere ayır ve her şeyi kayıt altına al.
Başarılı bir network güvenlik mimarisi için subnet tasarımını en baştan doğru yapmak gerekiyor çünkü sonradan değiştirmek çok pahalı. NSG kurallarını ise IP adresi yerine mantıksal soyutlamalar üzerinden yönetmek, uzun vadede bakım yükünü önemli ölçüde azaltıyor.
Son olarak, tüm bu yapılandırmaları Infrastructure as Code olarak tutmanızı şiddetle tavsiye ederim. Bicep veya Terraform ile tanımlanmış bir ağ altyapısı, hem tekrarlanabilirlik hem de felaket kurtarma senaryolarında büyük avantaj sağlıyor. El ile yapılan değişiklikler er ya da geç karmaşaya yol açıyor ve “configuration drift” denen sorun başlıyor. Kodla yönetin, versiyonlayın, review’dan geçirin.
