Geleneksel güvenlik anlayışı artık işe yaramıyor. “İçeride olana güven, dışarıdakinden şüphe et” mantığı, modern tehditlere karşı tamamen çaresiz kalıyor. Fidye yazılımları, içeriden tehditler, ele geçirilmiş kimlik bilgileri… Bunların hepsi o güvenli saydığımız iç ağda rahatça dolaşabiliyor. İşte tam bu noktada Zero Trust, yani Sıfır Güven mimarisi devreye giriyor: Hiç kimseye, hiçbir yerde otomatik olarak güvenme.
Bu yazıda Windows Server ortamında Zero Trust’ı gerçek anlamda nasıl uygulayacağını, hangi araçları ve konfigürasyonları kullanacağını adım adım anlatacağım. Soyut kavramları değil, sahaya uygulanabilir teknikleri konuşacağız.
Zero Trust Nedir ve Neden Windows Server İçin Kritik?
Zero Trust bir ürün değil, bir mimari felsefedir. Microsoft’un tanımıyla üç temel prensibe dayanır:
- Açıkça doğrula: Her erişim talebini, her seferinde doğrula
- En az ayrıcalık uygula: Kullanıcı ve sistemlere sadece ihtiyaç duydukları kadar yetki ver
- İhlali varsay: Bir ihlal olmuş gibi hareket et, hasarı sınırla
Windows Server ortamında bu prensipler özellikle önemli çünkü Active Directory, ağınızdaki her şeyin anahtarı. AD ele geçirilirse oyun biter. Ayrıca RDP, SMB, WinRM gibi protokoller, yanlış konfigüre edildiğinde saldırganların cennetine dönüşebilir.
Şimdi bu felsefeyi pratiğe dökelim.
Kimlik Doğrulama Katmanını Güçlendirme
Multi-Factor Authentication ve Windows Hello for Business
Zero Trust’ın kalbi kimliktedir. Parola tek başına yetmez. Windows Server 2019 ve üzerinde Windows Hello for Business’ı Group Policy ile zorunlu kılabilirsin.
# Group Policy üzerinden Windows Hello for Business zorunlu yapma
# GPMC'de şu yola git:
# Computer Configuration > Administrative Templates > Windows Components > Windows Hello for Business
# PowerShell ile GPO oluşturup bağlama
Import-Module GroupPolicy
New-GPO -Name "ZeroTrust-WHfB-Policy" -Comment "Windows Hello for Business Zorunlu"
Set-GPRegistryValue -Name "ZeroTrust-WHfB-Policy" `
-Key "HKLMSOFTWAREPoliciesMicrosoftPassportForWork" `
-ValueName "Enabled" `
-Type DWord `
-Value 1
Set-GPRegistryValue -Name "ZeroTrust-WHfB-Policy" `
-Key "HKLMSOFTWAREPoliciesMicrosoftPassportForWork" `
-ValueName "RequireSecurityDevice" `
-Type DWord `
-Value 1
New-GPLink -Name "ZeroTrust-WHfB-Policy" -Target "OU=Servers,DC=sirket,DC=local"
Protected Users Güvenlik Grubu
Bu grup, Active Directory’deki en hafife alınan ama en güçlü koruma mekanizmalarından biri. Kullanıcıları bu gruba ekleyince şu korumalar otomatik devreye girer:
- NTLM authentication devre dışı kalır
- Kerberos delegation çalışmaz
- DES ve RC4 Kerberos şifreleme algoritmaları engellenir
- Kerberos TGT ömrü 4 saate indirilir
# Kritik hesapları Protected Users grubuna ekle
# Özellikle servis hesapları HARİÇ tüm adminleri ekle
Add-ADGroupMember -Identity "Protected Users" -Members @(
"admin.ahmet",
"admin.mehmet",
"domain.admin",
"backup.admin"
)
# Grubun mevcut üyelerini kontrol et
Get-ADGroupMember -Identity "Protected Users" |
Select-Object Name, SamAccountName, ObjectClass |
Format-Table -AutoSize
# Hesabın Protected Users üyesi olup olmadığını doğrula
$user = "admin.ahmet"
$groups = Get-ADUser $user -Properties MemberOf |
Select-Object -ExpandProperty MemberOf
$groups | Get-ADGroup | Where-Object {$_.Name -eq "Protected Users"}
Ağ Segmentasyonu ve Mikro-Segmentasyon
Windows Firewall ile Merkezi Politika Yönetimi
Zero Trust’ta lateral movement’ı engellemek çok önemli. Bir sistemi ele geçiren saldırganın yan yana hareket edememesi gerekiyor. Windows Firewall’u GPO ile merkezi yönetmek tam da burada kritik.
# PowerShell ile Windows Firewall kurallarını Zero Trust mantığıyla yapılandır
# Önce mevcut tüm profilleri kapat - whitelist mantığı
Set-NetFirewallProfile -Profile Domain,Public,Private -DefaultInboundAction Block -DefaultOutboundAction Allow
# Sadece gerekli portlara izin ver - örnek: Web sunucusu
New-NetFirewallRule -DisplayName "ZT-Allow-HTTP-Inbound" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 80,443 `
-Action Allow `
-Profile Domain `
-RemoteAddress "10.0.1.0/24" # Sadece belirli subnet'ten
# RDP'yi sadece jump server IP'sinden kabul et
New-NetFirewallRule -DisplayName "ZT-RDP-JumpServer-Only" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 3389 `
-Action Allow `
-RemoteAddress "10.0.100.10" # Jump server IP'si
# SMB'yi tamamen kapat - lateral movement'ın en büyük yolu
New-NetFirewallRule -DisplayName "ZT-Block-SMB-Inbound" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 445,139 `
-Action Block `
-Profile Domain,Private,Public
# WinRM'i sadece yönetim ağından kabul et
New-NetFirewallRule -DisplayName "ZT-WinRM-ManagementNet" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 5985,5986 `
-Action Allow `
-RemoteAddress "10.0.200.0/24" # Management network
IPSec ile Sunucu-Sunucu İletişimini Şifreleme
Segmentasyonun ötesinde, sunucular arası trafiği de şifrelemek gerekiyor. IPSec isolation politikaları bu işi yapar.
# Domain Isolation GPO oluştur
# Bu sayede sadece domain üyesi makineler birbirleriyle konuşabilir
# PowerShell ile IPSec politikası tanımla
$Phase1AuthSet = New-NetIPsecPhase1AuthSet -DisplayName "ZT-Kerberos-Auth" `
-Proposal (New-NetIPsecAuthProposal -Machine -Kerberos)
$Phase2AuthSet = New-NetIPsecPhase2AuthSet -DisplayName "ZT-Phase2-Auth" `
-Proposal (New-NetIPsecAuthProposal -None)
$MainModeRule = New-NetIPsecRule -DisplayName "ZT-Server-Isolation" `
-InboundSecurity Require `
-OutboundSecurity Request `
-Phase1AuthSet $Phase1AuthSet.Name `
-Phase2AuthSet $Phase2AuthSet.Name `
-Profile Domain
Write-Host "IPSec isolation politikasi basariyla olusturuldu" -ForegroundColor Green
Privileged Access Workstation (PAW) ve Jump Server Mimarisi
Yönetim işlemlerini normal iş istasyonlarından yapmamalısın. Gerçek bir Zero Trust ortamında yöneticiler için özel PAW’lar veya en azından sıkılaştırılmış jump server’lar kullanılır.
# Jump Server üzerinde uygulama kısıtlama - sadece yönetim araçları
# AppLocker politikası oluştur
$AppLockerPolicy = @"
<AppLockerPolicy Version="1">
<RuleCollection Type="Exe" EnforcementMode="Enabled">
<FilePublisherRule Id="$(New-Guid)" Name="Allow Windows Components"
Description="" UserOrGroupSid="S-1-1-0" Action="Allow">
<Conditions>
<FilePublisherCondition PublisherName="O=MICROSOFT CORPORATION, L=REDMOND, S=WASHINGTON, C=US"
ProductName="*" BinaryName="*">
<BinaryVersionRange LowSection="*" HighSection="*" />
</FilePublisherCondition>
</Conditions>
</FilePublisherRule>
</RuleCollection>
</AppLockerPolicy>
"@
# AppLocker XML dosyasına kaydet
$AppLockerPolicy | Out-File -FilePath "C:GPOAppLockerPolicy.xml" -Encoding UTF8
# Politikayı uygula
Set-AppLockerPolicy -XMLPolicy "C:GPOAppLockerPolicy.xml"
# AppLocker servisinin çalıştığından emin ol
Set-Service -Name AppIDSvc -StartupType Automatic
Start-Service -Name AppIDSvc
Get-AppLockerPolicy -Effective | Test-AppLockerPolicy -Path "C:WindowsSystem32cmd.exe" -User "Everyone"
Credential Protection ve LAPS
Local Administrator Password Solution
Tüm sunucular aynı local admin şifresini paylaşıyor mu? Bu, lateral movement için biçilmiş kaftan. LAPS her sunucuya farklı, otomatik dönen bir local admin şifresi atar.
# LAPS kurulumu ve yapılandırması
# Önce LAPS MSI'yi Domain Controller'a kur, sonra:
# AD şemasını LAPS için genişlet
Import-Module AdmPwd.PS
Update-AdmPwdADSchema
# OU için LAPS şifre yönetim iznini ver
Set-AdmPwdComputerSelfPermission -OrgUnit "OU=Servers,DC=sirket,DC=local"
# Sadece belirli güvenlik grubuna şifre okuma yetkisi ver
Set-AdmPwdReadPasswordPermission -OrgUnit "OU=Servers,DC=sirket,DC=local" `
-AllowedPrincipals "SIRKETServer-Admins"
# LAPS GPO ayarlarını yapılandır
# Computer Configuration > Admin Templates > LAPS
# PowerShell ile LAPS şifresi sorgulama (yetkili kişi olarak)
Get-AdmPwdPassword -ComputerName "WEBSERVER01" |
Select-Object ComputerName, Password, ExpirationTimestamp
# Tüm sunucuların LAPS durumunu kontrol et
Get-ADComputer -Filter * -SearchBase "OU=Servers,DC=sirket,DC=local" `
-Properties ms-Mcs-AdmPwdExpirationTime |
Select-Object Name, "ms-Mcs-AdmPwdExpirationTime" |
Sort-Object Name
Credential Guard Aktivasyonu
Credential Guard, NTLM hash’lerini ve Kerberos biletlerini sanallaştırma tabanlı güvenlik ile korur. Pass-the-hash ve pass-the-ticket saldırılarını etkisiz kılar.
# Credential Guard'ı PowerShell ile etkinleştir
# Windows 10/11 ve Windows Server 2016+ üzerinde çalışır
# Önce sistem uyumluluğunu kontrol et
$CredGuardCheck = Get-WmiObject -Class Win32_DeviceGuard -Namespace rootMicrosoftWindowsDeviceGuard
if ($CredGuardCheck.VirtualizationBasedSecurityStatus -eq 2) {
Write-Host "VBS zaten aktif" -ForegroundColor Green
} else {
Write-Host "VBS etkin degil, aktive ediliyor..." -ForegroundColor Yellow
# Registry üzerinden Credential Guard aç
$regPath = "HKLM:SYSTEMCurrentControlSetControlDeviceGuard"
New-Item -Path $regPath -Force | Out-Null
Set-ItemProperty -Path $regPath -Name "EnableVirtualizationBasedSecurity" -Value 1 -Type DWord
Set-ItemProperty -Path $regPath -Name "RequirePlatformSecurityFeatures" -Value 3 -Type DWord
$credPath = "HKLM:SYSTEMCurrentControlSetControlLsa"
Set-ItemProperty -Path $credPath -Name "LsaCfgFlags" -Value 1 -Type DWord
Write-Host "Credential Guard etkinlestirildi. Yeniden baslatma gerekiyor." -ForegroundColor Cyan
}
# Credential Guard durumunu doğrula (yeniden başlatma sonrası)
$Status = Get-WmiObject -Class Win32_DeviceGuard -Namespace rootMicrosoftWindowsDeviceGuard
Write-Host "Credential Guard Durumu: $($Status.SecurityServicesRunning)"
Audit ve Monitoring: Saldırıyı Erkenden Farket
Zero Trust’ın “ihlali varsay” prensibi, kapsamlı loglama ve monitoring olmadan anlamsız. Ne olduğunu göremiyorsan, ihlali nasıl fark edeceksin?
# Gelişmiş denetim politikasını PowerShell ile yapılandır
# Logon/Logoff, Account Management, Object Access, Privilege Use
# Tüm kritik kategoriler için auditlama aç
$AuditCategories = @{
"Account Logon" = "Success,Failure"
"Account Management" = "Success,Failure"
"DS Access" = "Success,Failure"
"Logon/Logoff" = "Success,Failure"
"Object Access" = "Failure"
"Policy Change" = "Success,Failure"
"Privilege Use" = "Success,Failure"
"System" = "Success,Failure"
"Process Tracking" = "Success"
}
# auditpol komutunu kullan
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Account Lockout" /success:enable /failure:enable
auditpol /set /subcategory:"User Account Management" /success:enable /failure:enable
auditpol /set /subcategory:"Security Group Management" /success:enable /failure:enable
auditpol /set /subcategory:"Credential Validation" /success:enable /failure:enable
auditpol /set /subcategory:"Kerberos Authentication Service" /success:enable /failure:enable
auditpol /set /subcategory:"Other Logon/Logoff Events" /success:enable /failure:enable
auditpol /set /subcategory:"Special Logon" /success:enable /failure:enable
# Mevcut audit ayarlarını raporla
auditpol /get /category:* | Out-File "C:AuditCurrentAuditPolicy.txt"
Write-Host "Audit politikalari yapılandirildi ve rapora yazildi." -ForegroundColor Green
Suspicious Activity Tespiti için Otomatik Script
# Şüpheli aktiviteleri tespit eden monitoring scripti
# Başarısız logon denemelerini raporlar
$StartTime = (Get-Date).AddHours(-24)
$FailedLogons = Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4625 # Failed logon event ID
StartTime = $StartTime
} -ErrorAction SilentlyContinue
$Report = $FailedLogons | ForEach-Object {
$xml = [xml]$_.ToXml()
[PSCustomObject]@{
TimeCreated = $_.TimeCreated
TargetAccount = $xml.Event.EventData.Data |
Where-Object {$_.Name -eq "TargetUserName"} |
Select-Object -ExpandProperty '#text'
WorkStation = $xml.Event.EventData.Data |
Where-Object {$_.Name -eq "WorkstationName"} |
Select-Object -ExpandProperty '#text'
IPAddress = $xml.Event.EventData.Data |
Where-Object {$_.Name -eq "IpAddress"} |
Select-Object -ExpandProperty '#text'
LogonType = $xml.Event.EventData.Data |
Where-Object {$_.Name -eq "LogonType"} |
Select-Object -ExpandProperty '#text'
}
}
# Brute force şüphesi: Aynı IP'den 10'dan fazla başarısız deneme
$BruteForce = $Report |
Group-Object IPAddress |
Where-Object {$_.Count -gt 10} |
Sort-Object Count -Descending
if ($BruteForce) {
Write-Host "UYARI: Potansiyel Brute Force Tespiti!" -ForegroundColor Red
$BruteForce | Select-Object Name, Count | Format-Table -AutoSize
# E-posta bildirimi gönder (SMTP ayarlarını düzenle)
Send-MailMessage -To "[email protected]" `
-From "[email protected]" `
-Subject "KRITIK: Brute Force Girişimi Tespit Edildi" `
-Body ($BruteForce | Out-String) `
-SmtpServer "mail.sirket.local"
}
$Report | Export-Csv "C:LogsFailedLogons_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation
Just-In-Time (JIT) Erişim ve Privileged Access Management
Zero Trust’ın en güçlü prensiplerinden biri: Hiç kimsenin kalıcı admin yetkisi olmaması. Yetki, sadece gerektiğinde, gerektiği kadar verilmeli.
# Geçici grup üyeliği scripti - Just-In-Time Access simülasyonu
# (Microsoft PAM olmadan basit bir JIT implementasyonu)
function Grant-TemporaryAccess {
param(
[Parameter(Mandatory=$true)]
[string]$Username,
[Parameter(Mandatory=$true)]
[string]$GroupName,
[Parameter(Mandatory=$true)]
[int]$DurationMinutes,
[string]$Justification = "Belirtilmedi"
)
$ExpiryTime = (Get-Date).AddMinutes($DurationMinutes)
# Grup üyeliğini ekle
Add-ADGroupMember -Identity $GroupName -Members $Username
# Logla
$LogEntry = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | GRANT | User: $Username | Group: $GroupName | Expiry: $ExpiryTime | Justification: $Justification"
Add-Content -Path "C:LogsJIT_Access.log" -Value $LogEntry
Write-Host "Erisim verildi. Sona erme: $ExpiryTime" -ForegroundColor Green
# Zamanlayici gorev olustur - yetkiyi otomatik geri al
$TaskAction = New-ScheduledTaskAction -Execute "PowerShell.exe" `
-Argument "-Command `"Remove-ADGroupMember -Identity '$GroupName' -Members '$Username' -Confirm:`$false; Add-Content -Path 'C:LogsJIT_Access.log' -Value '$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | REVOKE | User: $Username | Group: $GroupName'`""
$TaskTrigger = New-ScheduledTaskTrigger -Once -At $ExpiryTime
Register-ScheduledTask -TaskName "JIT-Revoke-$Username-$(Get-Date -Format 'HHmmss')" `
-Action $TaskAction `
-Trigger $TaskTrigger `
-RunLevel Highest `
-User "SYSTEM" | Out-Null
Write-Host "Otomatik iptal gorevi olusturuldu: $DurationMinutes dakika sonra yetki kaldirilacak." -ForegroundColor Yellow
}
# Kullanım örneği:
# Grant-TemporaryAccess -Username "ahmet.yilmaz" -GroupName "Server Operators" -DurationMinutes 60 -Justification "Kritik yama uygulamasi"
Gercek Dunya Senaryosu: Hastane BT Ortami
Bir hastane BT ortamı düşün. PACS sunucuları, hasta kayıt sistemleri, tıbbi cihaz ağları… Hepsi aynı flat network üzerinde. Tek bir fidye yazılımı tüm hastaneyi çökertebilir. Bunu engellemek için uyguladığımız Zero Trust adımları şunlar oldu:
İlk adımda ağı mikro-segmentlere böldük. PACS ağı, klinik ağı ve idari ağ birbirinden tamamen izole edildi. Firewall kuralları whitelist mantığıyla yazıldı. PACS sunucuları sadece radyoloji iş istasyonlarıyla konuşabilir hale getirildi.
İkinci adımda tüm servis hesap şifreleri 30 karakterli, rastgele şifrelerle değiştirildi ve LAPS benzeri bir yönetim sistemine alındı. Shared admin şifresi dönemi bitti.
Üçüncü adımda admin hesapları Protected Users grubuna eklendi, PAW’lar kuruldu ve yönetim trafiği ayrı bir VLAN üzerinden yönlendirildi.
Dördüncü adımda kapsamlı audit loglaması devreye alındı, SIEM’e beslendi. İlk haftada 3 brute force girişimi ve 1 lateral movement denemesi tespit edildi. Bunların hepsi daha önce fark edilmiyordu.
Sonuç
Zero Trust bir gün içinde kurulacak bir şey değil. Bu bir yolculuk. Ama doğru sırayla atılan adımlar çok büyük fark yaratıyor.
Önce kimlik katmanını güçlendir: Protected Users, MFA, Credential Guard. Sonra ağı segmente et ve lateral movement yollarını kapat. LAPS ile local admin karmaşasını bitir. JIT erişim ile kalıcı ayrıcalıkları ortadan kaldır. Ve her şeyi logla, izle, analiz et.
Pratik bir öneri: Ortamını denetlemeden başlama. Hangi servis hesapları domain admin? Hangi kullanıcılar her yere RDP yapabiliyor? Hangi sunucular SMB üzerinden birbirleriyle konuşuyor? Bu soruların cevapları seni şaşırtacak, ama aynı zamanda nereden başlayacağını gösterecek.
Zero Trust’ın özü şu: Güven kazan, varsayma. Bu felsefyi Windows Server ortamına yerleştirdiğinde, bir saldırganın hayatını gerçekten zorlaştırıyorsun. Belki %100 önleyemezsin ama fark edilmeden ne kadar ileri gidebileceklerini ciddi ölçüde kısıtlıyorsun. Fidye yazılımı dünyasında bu fark, ayakta kalmak ile çökmek arasındaki fark olabilir.