Production ortamında Windows Server 2022 kurduğunuzda, varsayılan ayarlarla bırakmak bir felaketi davet etmek gibidir. Yıllar içinde onlarca sunucu kurulumu ve güvenlik denetimi yaptım; her seferinde aynı sorunlarla karşılaştım: RDP dünyaya açık, SMBv1 hâlâ etkin, yerel Administrator hesabı tahmin edilebilir bir şifreyle çalışıyor. Bu rehberde Windows Server 2022’yi sertleştirme sürecini, gerçek dünya senaryolarıyla birlikte adım adım ele alacağız.
Neden Sertleştirme Şart?
Bir müşterimin sunucusuna baktığımda ilk gördüğüm şey şuydu: 3389 portu internete açık, Event Log’da binlerce başarısız RDP giriş denemesi ve SMBv1 protokolü aktif. Sunucu tam anlamıyla bir davetiye çıkarmıştı. WannaCry gibi fidye yazılımları hâlâ aktif ve SMBv1 açığını hedef alıyor. Dolayısıyla “nasıl olsa firewall var” mantığıyla hareket etmek sizi korumaz.
Sertleştirme tek seferlik bir iş değildir. Düzenli olarak tekrarlanması, otomatize edilmesi ve belgelenmesi gereken bir süreçtir. Şimdi başlayalım.
Temel Sistem Güncellemeleri ve Yapılandırması
İlk adım her zaman güncel bir sistemle başlamaktır. Yeni kurulumun hemen ardından Windows Update’i çalıştırın ve tüm kritik yamaları uygulayın.
# PowerShell ile Windows Update yönetimi
Install-Module PSWindowsUpdate -Force
Import-Module PSWindowsUpdate
Get-WindowsUpdate -AcceptAll -Install -AutoReboot
Güncelleme sonrası sistemin hangi özelliklerin etkin olduğunu kontrol etmek gerekir. Gereksiz Windows özellikleri saldırı yüzeyini artırır.
# Etkin Windows özelliklerini listele
Get-WindowsOptionalFeature -Online | Where-Object {$_.State -eq "Enabled"} | Select-Object FeatureName
# SMBv1'i devre dışı bırak - bu kritik!
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
Set-SmbClientConfiguration -EnableSMB1Protocol $false -Force
# SMBv2 ve SMBv3'ün etkin olduğunu doğrula
Get-SmbServerConfiguration | Select-Object EnableSMB2Protocol
SMBv1’i devre dışı bırakmak bazen eski yazıcı veya NAS cihazlarıyla uyumluluk sorununa yol açabilir. Bunu müşteriye önceden bildirin ve test ortamında deneyin. Eski cihazlar için genellikle firmware güncellemesi yeterli olur.
Yerel Hesap Güvenliği
Varsayılan Administrator hesabı saldırganların ilk hedefidir. Basit ama etkili önlemler alın.
# Varsayılan Administrator hesabını yeniden adlandır
Rename-LocalUser -Name "Administrator" -NewName "SysAdmin_Prod01"
# Varsayılan Guest hesabını devre dışı bırak
Disable-LocalUser -Name "Guest"
# Güçlü parola politikası belirle
net accounts /minpwlen:14 /maxpwage:90 /minpwage:1 /uniquepw:10 /lockoutthreshold:5 /lockoutwindow:30 /lockoutduration:30
Parola politikasını Group Policy üzerinden de uygulayabilirsiniz; bu yol daha merkezi yönetim sağlar. Ama standalone sunucularda yukarıdaki komutlar işe yarar.
Yerel Administrator hesabına ek olarak, her sistem yöneticisi için ayrı hesap oluşturun. “Hepimiz aynı hesabı kullanıyoruz” durumu hem güvenlik açığı hem de audit problemidir. Kim ne yaptığını izleyemezsiniz.
# Yeni yönetici hesabı oluştur ve gruba ekle
New-LocalUser -Name "ahmet.admin" -Password (ConvertTo-SecureString "P@ssw0rd!2024" -AsPlainText -Force) -FullName "Ahmet Yılmaz Admin" -Description "Sistem Yöneticisi"
Add-LocalGroupMember -Group "Administrators" -Member "ahmet.admin"
# Hesap özelliklerini ayarla
Set-LocalUser -Name "ahmet.admin" -PasswordNeverExpires $false -UserMayChangePassword $true
Windows Güvenlik Duvarı Yapılandırması
Windows Firewall’ı devre dışı bırakmak sık yapılan hatalardan biridir. “Zaten önünde bir firewall var” diyenler için şunu söyleyeyim: derinlemesine savunma prensibinde her katman kendi başına çalışır. Host tabanlı firewall bir katmandır.
# Tüm profillerde firewall durumunu kontrol et
Get-NetFirewallProfile | Select-Object Name, Enabled, DefaultInboundAction, DefaultOutboundAction
# Firewall'ı tüm profillerde etkinleştir
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
# Varsayılan gelen trafiği engelle
Set-NetFirewallProfile -Profile Domain,Public,Private -DefaultInboundAction Block -DefaultOutboundAction Allow
# RDP'yi sadece belirli IP aralığından izin ver
New-NetFirewallRule -DisplayName "RDP - Management Network" -Direction Inbound -Protocol TCP -LocalPort 3389 -RemoteAddress "192.168.10.0/24" -Action Allow -Profile Domain,Private
# Gereksiz açık portları kontrol et
Get-NetTCPConnection -State Listen | Sort-Object LocalPort | Select-Object LocalAddress, LocalPort, OwningProcess
RDP portunu varsayılan 3389’dan değiştirmek “security through obscurity” olsa da brute force saldırılarını ciddi ölçüde azaltır. Tek başına yeterli değildir ama NLA ile birleşince etkili olur.
Remote Desktop Services Güvenliği
RDP, Windows sunucularda en sık saldırıya uğrayan servistir. Doğru yapılandırılmazsa büyük risk oluşturur.
# NLA (Network Level Authentication) zorla
$registryPath = "HKLM:SYSTEMCurrentControlSetControlTerminal ServerWinStationsRDP-Tcp"
Set-ItemProperty -Path $registryPath -Name "UserAuthentication" -Value 1
# RDP için minimum şifreleme düzeyi ayarla (High)
Set-ItemProperty -Path $registryPath -Name "MinEncryptionLevel" -Value 3
# RDP bağlantı sayısını sınırla
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetControlTerminal Server" -Name "MaxInstanceCount" -Value 2
# RDP oturum zaman aşımlarını ayarla (Group Policy yolu)
# Boşta kalan oturumlar için 15 dakika
$gpPath = "HKLM:SOFTWAREPoliciesMicrosoftWindows NTTerminal Services"
New-Item -Path $gpPath -Force | Out-Null
Set-ItemProperty -Path $gpPath -Name "MaxIdleTime" -Value 900000
Set-ItemProperty -Path $gpPath -Name "MaxDisconnectionTime" -Value 3600000
Gerçek dünyada karşılaştığım bir senaryo: Bir e-ticaret firmasının sunucusu RDP üzerinden ele geçirilmişti. Saldırgan NLA olmadığı için doğrudan giriş ekranına ulaşabilmiş ve credential stuffing saldırısıyla içeri girmeyi başarmıştı. NLA olsaydı bu mümkün olmazdı.
Denetim ve Loglama Politikası
Bir saldırı sonrası “ne oldu?” sorusunu yanıtlayabilmek için kapsamlı loglama şarttır. Varsayılan Windows loglama ayarları yetersizdir.
# Gelişmiş denetim politikası yapılandırması
# Başarılı ve başarısız oturum açma işlemlerini logla
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Account Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Account Management" /success:enable /failure:enable
auditpol /set /subcategory:"Object Access" /success:enable /failure:enable
auditpol /set /subcategory:"Policy Change" /success:enable /failure:enable
auditpol /set /subcategory:"Privilege Use" /success:enable /failure:enable
auditpol /set /subcategory:"Process Creation" /success:enable /failure:enable
auditpol /set /subcategory:"System" /success:enable /failure:enable
# Mevcut denetim politikasını görüntüle
auditpol /get /category:*
# Event Log boyutlarını artır
wevtutil sl Security /ms:1073741824
wevtutil sl System /ms:524288000
wevtutil sl Application /ms:524288000
Log boyutlarını artırmak kritiktir. Varsayılan 20 MB’lık Security log, yoğun bir ortamda birkaç saat içinde dolabilir ve eski kayıtların üstüne yazılabilir. Benim tavsiyem Security log için en az 1 GB ayırmanızdır.
PowerShell işlem loglamasını da etkinleştirin; bu özellikle malware analizi ve incident response için değerlidir.
# PowerShell Script Block Logging etkinleştir
$psLogPath = "HKLM:SOFTWAREPoliciesMicrosoftWindowsPowerShellScriptBlockLogging"
New-Item -Path $psLogPath -Force | Out-Null
Set-ItemProperty -Path $psLogPath -Name "EnableScriptBlockLogging" -Value 1
Set-ItemProperty -Path $psLogPath -Name "EnableScriptBlockInvocationLogging" -Value 1
# PowerShell Transcription etkinleştir
$psTransPath = "HKLM:SOFTWAREPoliciesMicrosoftWindowsPowerShellTranscription"
New-Item -Path $psTransPath -Force | Out-Null
Set-ItemProperty -Path $psTransPath -Name "EnableTranscripting" -Value 1
Set-ItemProperty -Path $psTransPath -Name "OutputDirectory" -Value "C:PSTranscripts"
Set-ItemProperty -Path $psTransPath -Name "EnableInvocationHeader" -Value 1
Servis ve Protokol Sertleştirmesi
Çalışmayan servisleri kapatmak saldırı yüzeyini küçültür. Her aktif servis potansiyel bir giriş noktasıdır.
# Gereksiz servisleri devre dışı bırak
$unnecessaryServices = @(
"XblAuthManager", # Xbox Live Auth
"XblGameSave", # Xbox Live Game Save
"XboxNetApiSvc", # Xbox Network
"WMPNetworkSvc", # Windows Media Player Network
"RemoteRegistry", # Remote Registry - kritik!
"Spooler", # Print Spooler (print sunucusu değilse)
"Fax", # Fax servisi
"TapiSrv" # Telephony
)
foreach ($service in $unnecessaryServices) {
$svc = Get-Service -Name $service -ErrorAction SilentlyContinue
if ($svc) {
Stop-Service -Name $service -Force -ErrorAction SilentlyContinue
Set-Service -Name $service -StartupType Disabled
Write-Output "$service devre dışı bırakıldı"
}
}
RemoteRegistry servisini kapatmak özellikle önemlidir. Bu servis aktifken uzaktan registry değişikliği yapılabilir; bu ciddi bir güvenlik riskidir.
LLMNR ve NetBIOS gibi eski protokolleri de devre dışı bırakın. Bu protokoller MITM (Man-in-the-Middle) saldırılarında sıkça kullanılır.
# LLMNR devre dışı bırak
$llmnrPath = "HKLM:SOFTWAREPoliciesMicrosoftWindows NTDNSClient"
New-Item -Path $llmnrPath -Force | Out-Null
Set-ItemProperty -Path $llmnrPath -Name "EnableMulticast" -Value 0
# NetBIOS over TCP/IP devre dışı bırak (tüm adaptörler için)
$adapters = Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object {$_.IPEnabled -eq $true}
foreach ($adapter in $adapters) {
$adapter.SetTcpipNetbios(2) # 2 = Disable NetBIOS over TCP/IP
Write-Output "NetBIOS devre dışı: $($adapter.Description)"
}
# WPAD otomatik proxy algılamasını devre dışı bırak
$wpadPath = "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionInternet SettingsWpad"
New-Item -Path $wpadPath -Force | Out-Null
Set-ItemProperty -Path $wpadPath -Name "WpadOverride" -Value 1
TLS ve Kriptografi Yapılandırması
Eski ve zayıf şifreleme protokollerini devre dışı bırakmak zorunludur. SSL 3.0, TLS 1.0 ve TLS 1.1 artık güvensiz kabul edilmektedir.
# TLS 1.0 devre dışı bırak
$tls10Path = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsTLS 1.0"
New-Item -Path "$tls10PathServer" -Force | Out-Null
New-Item -Path "$tls10PathClient" -Force | Out-Null
Set-ItemProperty -Path "$tls10PathServer" -Name "Enabled" -Value 0 -Type DWord
Set-ItemProperty -Path "$tls10PathServer" -Name "DisabledByDefault" -Value 1 -Type DWord
Set-ItemProperty -Path "$tls10PathClient" -Name "Enabled" -Value 0 -Type DWord
Set-ItemProperty -Path "$tls10PathClient" -Name "DisabledByDefault" -Value 1 -Type DWord
# TLS 1.1 devre dışı bırak
$tls11Path = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsTLS 1.1"
New-Item -Path "$tls11PathServer" -Force | Out-Null
New-Item -Path "$tls11PathClient" -Force | Out-Null
Set-ItemProperty -Path "$tls11PathServer" -Name "Enabled" -Value 0 -Type DWord
Set-ItemProperty -Path "$tls11PathServer" -Name "DisabledByDefault" -Value 1 -Type DWord
# TLS 1.2 ve 1.3 etkin olduğunu doğrula
$tls12Path = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsTLS 1.2"
New-Item -Path "$tls12PathServer" -Force | Out-Null
Set-ItemProperty -Path "$tls12PathServer" -Name "Enabled" -Value 1 -Type DWord
Set-ItemProperty -Path "$tls12PathServer" -Name "DisabledByDefault" -Value 0 -Type DWord
# Zayıf cipher suite'leri devre dışı bırak
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_RC4_128_MD5"
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_RC4_128_SHA"
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
Bu değişiklikler sonrası mutlaka test edin. Özellikle IIS üzerinde web uygulaması çalıştırıyorsanız TLS değişiklikleri bazı eski istemcilerle uyumluluk sorununa yol açabilir.
Windows Defender ve Antimalware Yapılandırması
Windows Server 2022 ile gelen Windows Defender oldukça güçlü bir araçtır. Ama varsayılan ayarlarla optimum koruma sağlanmaz.
# Windows Defender güncel tanım dosyalarını kontrol et
Get-MpComputerStatus | Select-Object AntivirusSignatureLastUpdated, RealTimeProtectionEnabled, BehaviorMonitorEnabled
# Gerçek zamanlı korumayı etkinleştir
Set-MpPreference -DisableRealtimeMonitoring $false
# Bulut tabanlı korumayı etkinleştir
Set-MpPreference -MAPSReporting Advanced
Set-MpPreference -SubmitSamplesConsent SendAllSamples
# Exploit Protection etkinleştir
Set-ProcessMitigation -System -Enable DEP,SEHOP,CFG,ForceRelocateImages
# Defender tarama zamanlaması ayarla
Set-MpPreference -ScanScheduleDay Everyday
Set-MpPreference -ScanScheduleTime 120 # Sabah 02:00
# Defender durum raporu
Get-MpThreatDetection | Select-Object -Last 10
UAC ve Privilege Yönetimi
User Account Control (UAC) devre dışı bırakmak yaygın ama tehlikeli bir hatadır. Yöneticiler “her seferinde onay istiyor” diye UAC’ı kapatır; bu ciddi güvenlik açığı yaratır.
# UAC ayarlarını en yüksek seviyeye çek
$uacPath = "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem"
Set-ItemProperty -Path $uacPath -Name "EnableLUA" -Value 1
Set-ItemProperty -Path $uacPath -Name "ConsentPromptBehaviorAdmin" -Value 2 # Secure desktop ile onay iste
Set-ItemProperty -Path $uacPath -Name "ConsentPromptBehaviorUser" -Value 3 # Standart kullanıcılar için reddet
Set-ItemProperty -Path $uacPath -Name "PromptOnSecureDesktop" -Value 1
# Credential Guard etkinleştir (Hyper-V gerektirir)
$cgPath = "HKLM:SYSTEMCurrentControlSetControlDeviceGuard"
New-Item -Path $cgPath -Force | Out-Null
Set-ItemProperty -Path $cgPath -Name "EnableVirtualizationBasedSecurity" -Value 1
Set-ItemProperty -Path $cgPath -Name "RequirePlatformSecurityFeatures" -Value 1
Set-ItemProperty -Path $cgPath -Name "LsaCfgFlags" -Value 1
LAPS ile Yerel Yönetici Parola Yönetimi
Domain ortamında tüm sunucularda aynı yerel Administrator parolasını kullanmak yaygın bir hatadır. Bir sunucu ele geçirildiğinde saldırgan bu parolayla diğer tüm sunuculara erişebilir. Microsoft LAPS (Local Administrator Password Solution) bu sorunu çözer.
# LAPS modülünü yükle (Windows Server 2022'de dahili gelir)
Import-Module LAPS
# LAPS politikasını yapılandır
Set-LapsADAuditing -Identity "OU=Servers,DC=sirket,DC=local" -AuditedPrincipals "Domain Admins"
# LAPS parolasını görüntüle (yetkili kullanıcılar için)
Get-LapsADPassword -Identity "WEBSERVER01" -AsPlainText
# LAPS parola sona erme süresini ayarla
Set-LapsADPasswordExpirationTime -Identity "WEBSERVER01" -WhenEffective (Get-Date).AddDays(1)
Sertleştirme Durumu Doğrulama Scripti
Tüm bu değişiklikleri yaptıktan sonra doğrulama yapın. Ben genellikle şu scripti kullanıyorum:
# Sertleştirme kontrol scripti
Write-Output "=== Windows Server 2022 Sertleştirme Kontrol Raporu ==="
Write-Output "Tarih: $(Get-Date)"
Write-Output ""
# SMBv1 kontrolü
$smb1 = Get-SmbServerConfiguration | Select-Object -ExpandProperty EnableSMB1Protocol
Write-Output "SMBv1 Durumu: $(if($smb1){'AÇIK - RISK!'} else {'Kapalı - OK'})"
# Firewall kontrolü
$fw = Get-NetFirewallProfile | Where-Object {$_.Enabled -eq $false}
Write-Output "Firewall Durumu: $(if($fw){'KAPALI PROFİL VAR - RISK!'} else {'Tüm profiller aktif - OK'})"
# RDP NLA kontrolü
$nla = (Get-ItemProperty "HKLM:SYSTEMCurrentControlSetControlTerminal ServerWinStationsRDP-Tcp").UserAuthentication
Write-Output "NLA Durumu: $(if($nla -eq 1){'Etkin - OK'} else {'DEVRE DIŞI - RISK!'})"
# Windows Defender kontrolü
$defender = Get-MpComputerStatus
Write-Output "Real-time Koruma: $(if($defender.RealTimeProtectionEnabled){'Etkin - OK'} else {'DEVRE DIŞI - RISK!'})"
# Açık portları listele
Write-Output ""
Write-Output "=== Açık TCP Portları ==="
Get-NetTCPConnection -State Listen | Sort-Object LocalPort | ForEach-Object {
$process = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
Write-Output "Port $($_.LocalPort) - $($process.Name)"
}
Bu scripti düzenli aralıklarla çalıştırın ve çıktısını bir yere kaydedin. Bir şeyler değiştiğinde fark edebilirsiniz.
CIS Benchmark ve Uyumluluk
Microsoft Security Compliance Toolkit ve CIS Benchmark’lar, Windows Server 2022 için hazır politika şablonları sunar. Bu şablonları kullanmak işinizi büyük ölçüde kolaylaştırır.
CIS Level 1 benchmark’ı üretim ortamları için iyi bir başlangıç noktasıdır. Level 2 daha kısıtlayıcıdır ve bazı uygulamalarla uyumluluk sorununa yol açabilir. Microsoft Security Compliance Toolkit’i indirip Group Policy üzerinden uygulayabilirsiniz.
Önemli bir nokta: Bu şablonları körü körüne uygulamayın. Her maddeyi anlayın, test ortamında deneyin ve üretim ortamına alın. Özellikle IIS, SQL Server veya özel uygulamalar çalıştıran sunucularda bazı politikalar sorun çıkarabilir.
Sonuç
Windows Server 2022 sertleştirmesi tek bir komut ya da tek bir politikayla bitmez. Burada anlattıklarım iyi bir başlangıç noktasıdır ama her ortam farklıdır. Bir web sunucusunun sertleştirme gereksinimleri, bir domain controller’dan ya da dosya sunucusundan farklıdır.
Şu temel prensipleri her zaman aklınızda tutun:
- En az yetki prensibi: Kullanıcı ve servisler sadece ihtiyaç duydukları izinlere sahip olmalıdır.
- Saldırı yüzeyini küçültme: Kullanmadığınız her servis ve protokol potansiyel bir risk kaynağıdır.
- Derinlemesine savunma: Tek bir güvenlik katmanına güvenmeyin, katmanları birbiriyle destekleyin.
- Görünürlük: Loglarınızı izlemeden güvenli olup olmadığınızı bilemezsiniz.
- Süreklilik: Sertleştirme tek seferlik değil, süregelen bir süreçtir.
Bu rehberdeki scriptleri doğrudan üretim ortamına uygulamadan önce test ortamında deneyin. Bazı değişiklikler, özellikle TLS ve servis devre dışı bırakma, mevcut uygulamalarınızı etkileyebilir. İyi bir değişiklik yönetimi süreci, sertleştirme kadar önemlidir.
Son olarak, yaptığınız her değişikliği belgeleyin. Altı ay sonra neden o ayarı değiştirdiğinizi hatırlamak isteyeceksiniz; ya da işi devralacak meslektaşınız hatırlamak isteyecektir.