Yeni bir Windows Server kurulumu yaptığınızda, Microsoft’un size sunduğu sistem aslında onlarca servis ve rol ile birlikte geliyor. Bunların büyük çoğunluğuna ihtiyacınız olmayabilir, hatta bazıları aktif olarak güvenlik riski oluşturuyor. Bir sysadmin olarak bu konuyu öğrendiğimde, “neden kimse bunu baştan anlatmıyor?” diye düşünmüştüm. Bu yazıda Windows Server üzerinde gereksiz rol ve servisleri nasıl tespit edeceğinizi, nasıl devre dışı bırakacağınızı ve bu süreçte nelere dikkat etmeniz gerektiğini detaylıca ele alacağız.
Neden Gereksiz Servisleri Kapatmalıyız?
Saldırı yüzeyi azaltma (attack surface reduction) kavramı güvenlik dünyasının temel prensiplerinden biridir. Sistem üzerinde çalışan her servis, potansiyel bir giriş noktasıdır. SMBv1 zafiyetini kullanan WannaCry saldırısını hatırlayın. O dönemde binlerce sistem, yıllardır kullanılmayan ama kapatılmamış SMBv1 servisi yüzünden şifrelendi.
Gereksiz servisleri kapatmanın getirdiği avantajlar şunlardır:
- Güvenlik: Her kapalı servis, bir saldırı vektörünü ortadan kaldırır
- Performans: Kullanılmayan servisler CPU ve RAM tüketir
- Lisans: Bazı roller ek lisans maliyeti getirebilir
- Bakım kolaylığı: Daha az servis, daha az güncelleme ve yama yönetimi demektir
- Compliance: PCI-DSS, ISO 27001 gibi standartlar minimum servis prensibini zorunlu kılar
Mevcut Rolleri ve Servisleri Keşfetmek
İlk adım olarak sunucunuzda neyin kurulu ve çalışıyor olduğunu tespit etmeniz gerekiyor. PowerShell bu iş için biçilmiş kaftan.
Kurulu Windows Rolleri ve Özellikleri Listeleme
# Tüm kurulu rolleri ve özellikleri listele
Get-WindowsFeature | Where-Object {$_.InstallState -eq "Installed"} | Select-Object Name, DisplayName, InstallState | Format-List
# Sadece ana rolleri göster
Get-WindowsFeature | Where-Object {$_.InstallState -eq "Installed" -and $_.FeatureType -eq "Role"} | Select-Object DisplayName, Name
Bu komut size sunucuda kurulu olan her şeyi gösterir. Çıktıyı bir metin dosyasına kaydetmenizi tavsiye ederim, değişiklikleri takip etmek için referans olarak kullanırsınız.
Çalışan Servisleri İnceleme
# Çalışan tüm servisleri listele
Get-Service | Where-Object {$_.Status -eq "Running"} | Select-Object Name, DisplayName, StartType | Sort-Object DisplayName
# Başlangıçta otomatik başlayan servisleri göster
Get-Service | Where-Object {$_.StartType -eq "Automatic"} | Select-Object Name, DisplayName, Status | Sort-Object Status -Descending
# Servisleri bir CSV dosyasına aktar (değişiklik öncesi baseline için)
Get-Service | Select-Object Name, DisplayName, Status, StartType | Export-Csv -Path "C:Baseline_Services_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation
Değişiklik yapmadan önce bu baseline’ı mutlaka alın. Bir şey yanlış giderse neyi geri döndürmeniz gerektiğini bilirsiniz.
Tehlikeli ve Gereksiz Windows Özellikleri
SMBv1’i Devre Dışı Bırakma
SMBv1, 1980’lerden kalma bir protokol ve WannaCry, NotPetya gibi saldırılarda kullanılan ana vektör. Modern ortamlarda SMBv1’e ihtiyaç duyan tek şey, çok eski yazıcı veya NAS cihazları olabilir. Onlar için bile çözüm SMBv1 açık tutmak değil, o cihazları değiştirmektir.
# SMBv1 durumunu kontrol et
Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol
# SMBv1'i devre dışı bırak
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart
# Sunucu tarafında SMBv1'i de kapat
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
# Değişikliği doğrula
Get-SmbServerConfiguration | Select-Object EnableSMB1Protocol, EnableSMB2Protocol
Gerçek dünya notu: Bunu bir üretim ortamında uygulamadan önce, ağınızda SMBv1 kullanan cihaz olup olmadığını kontrol edin. Bunun için Wireshark ile kısa bir trafik analizi yapabilir ya da Windows Event Log’larını inceleyebilirsiniz.
Telnet Client ve Server
Telnet, tüm trafiği düz metin olarak iletir. 2024 yılında Telnet kullanmak için hiçbir geçerli sebep yok.
# Telnet Client'ı kaldır
Disable-WindowsOptionalFeature -Online -FeatureName TelnetClient -NoRestart
# Telnet Server servisini durdur ve devre dışı bırak
Stop-Service -Name "TlntSvr" -Force -ErrorAction SilentlyContinue
Set-Service -Name "TlntSvr" -StartupType Disabled -ErrorAction SilentlyContinue
# Windows özelliği olarak da kaldır
Remove-WindowsFeature -Name Telnet-Server
TFTP Client
TFTP (Trivial File Transfer Protocol) de kimlik doğrulama olmadan çalışan eski bir protokol. Çoğu ortamda hiç kullanılmaz.
# TFTP Client'ı devre dışı bırak
Disable-WindowsOptionalFeature -Online -FeatureName TFTP -NoRestart
Windows Remote Registry
Remote Registry servisi, uzaktan kayıt defteri erişimine izin verir. Aktif olarak kullanmıyorsanız kapatın.
# Remote Registry servisini durdur ve devre dışı bırak
Stop-Service -Name "RemoteRegistry" -Force
Set-Service -Name "RemoteRegistry" -StartupType Disabled
# Durumu kontrol et
Get-Service -Name "RemoteRegistry" | Select-Object Name, Status, StartType
IIS ve Web Sunucu Rolü Güvenlik Sertleştirmesi
Bir web sunucusu çalıştırıyorsanız, IIS üzerinde gereksiz pek çok şey varsayılan olarak açık geliyor.
# Kurulu IIS özelliklerini listele
Get-WindowsFeature -Name Web-* | Where-Object {$_.InstallState -eq "Installed"}
# WebDAV'ı kaldır (çoğu web sunucusu için gereksiz ve riskli)
Remove-WindowsFeature -Name Web-DAV-Publishing
# FTP Servisi kullanmıyorsanız kaldır
Remove-WindowsFeature -Name Web-Ftp-Server
# IIS Management Console'u sadece yönetim sunucusunda bırak
# Üretim web sunucularında bu gereksiz
Remove-WindowsFeature -Name Web-Mgmt-Console
# Gereksiz IIS modüllerini PowerShell ile devre dışı bırak
# Örneğin WebDAV modülü
Import-Module WebAdministration
Remove-WebConfigurationProperty -PSPath "IIS:" -Filter "system.webServer/globalModules" -Name "." -AtElement @{name='WebDAVModule'} -ErrorAction SilentlyContinue
IIS’te Gereksiz HTTP Metodlarını Devre Dışı Bırakma
Web uygulamanız sadece GET ve POST kullanıyorsa, diğer HTTP metodlarını engelleyin.
# Web.config veya ApplicationHost.config üzerinden HTTP metodlarını kısıtla
# Bu örnek sadece GET ve POST'a izin verir
$configPath = "IIS:SitesDefault Web Site"
Add-WebConfigurationProperty -PSPath $configPath -Filter "system.webServer/security/requestFiltering/verbs" -Name "." -Value @{verb="DELETE";allowed="false"}
Add-WebConfigurationProperty -PSPath $configPath -Filter "system.webServer/security/requestFiltering/verbs" -Name "." -Value @{verb="PUT";allowed="false"}
Add-WebConfigurationProperty -PSPath $configPath -Filter "system.webServer/security/requestFiltering/verbs" -Name "." -Value @{verb="OPTIONS";allowed="false"}
Yaygın Gereksiz Windows Servisleri
Birçok ortamda güvenle kapatılabilecek servisler şunlardır:
Fax Servisi
# Fax servisini devre dışı bırak
Stop-Service -Name "Fax" -Force -ErrorAction SilentlyContinue
Set-Service -Name "Fax" -StartupType Disabled
# Fax rolünü tamamen kaldır
Remove-WindowsFeature -Name Fax
Print Spooler
Eğer sunucunuz bir print server değilse, Print Spooler servisi kapalı olmalı. PrintNightmare (CVE-2021-34527) zafiyeti, bu servisi aktif olan sistemleri etkilemişti.
# Print Spooler'ı durdur ve devre dışı bırak
Stop-Service -Name "Spooler" -Force
Set-Service -Name "Spooler" -StartupType Disabled
# Print Spooler durumunu doğrula
Get-Service -Name "Spooler"
# Eğer bu bir Domain Controller ise özellikle önemli
# DC'lerde Print Spooler kesinlikle kapalı olmalı
Windows Search
Dosya arama indexleme servisi, sunucu ortamında genellikle gereksizdir ve ciddi I/O yükü oluşturabilir.
# Windows Search servisini devre dışı bırak
Stop-Service -Name "WSearch" -Force -ErrorAction SilentlyContinue
Set-Service -Name "WSearch" -StartupType Disabled
Xbox ve Consumer Özellikleri
Windows Server 2016 ve sonrasında bazı consumer özellikler varsayılan olarak geliyor.
# Xbox ile ilgili servisleri devre dışı bırak (varsa)
$xboxServices = @("XblAuthManager", "XblGameSave", "XboxGipSvc", "XboxNetApiSvc")
foreach ($service in $xboxServices) {
$svc = Get-Service -Name $service -ErrorAction SilentlyContinue
if ($svc) {
Stop-Service -Name $service -Force -ErrorAction SilentlyContinue
Set-Service -Name $service -StartupType Disabled
Write-Host "$service devre disi birakildi" -ForegroundColor Green
}
}
Toplu Güvenlik Sertleştirme Scripti
Yukarıdaki tüm adımları otomatize eden bir script hazırlamak, özellikle çok sayıda sunucu yönetiyorsanız hayat kurtarır.
# Windows Server Hardening Script
# Degisiklik oncesi mutlaka backup ve test ortaminda calistirin
param(
[switch]$WhatIf,
[string]$LogPath = "C:LogsHardening_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
)
function Write-Log {
param($Message, $Level = "INFO")
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "[$timestamp] [$Level] $Message"
Write-Host $logMessage
Add-Content -Path $LogPath -Value $logMessage
}
# Log dizinini oluştur
New-Item -ItemType Directory -Path (Split-Path $LogPath) -Force | Out-Null
Write-Log "Hardening scripti baslatildi"
Write-Log "Sunucu: $env:COMPUTERNAME"
# Baseline kaydet
Write-Log "Baseline kaydediliyor..."
Get-Service | Select-Object Name, Status, StartType | Export-Csv -Path "C:LogsBaseline_Before_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation
# SMBv1'i devre disi birak
Write-Log "SMBv1 devre disi birakiliyor..."
if (-not $WhatIf) {
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart -ErrorAction SilentlyContinue
}
# Tehlikeli servisleri kapat
$servicesToDisable = @(
@{Name="RemoteRegistry"; Description="Remote Registry"},
@{Name="Fax"; Description="Fax Servisi"},
@{Name="Spooler"; Description="Print Spooler"},
@{Name="WSearch"; Description="Windows Search"},
@{Name="TlntSvr"; Description="Telnet Server"}
)
foreach ($svc in $servicesToDisable) {
$service = Get-Service -Name $svc.Name -ErrorAction SilentlyContinue
if ($service) {
Write-Log "$($svc.Description) ($($svc.Name)) devre disi birakiliyor..."
if (-not $WhatIf) {
Stop-Service -Name $svc.Name -Force -ErrorAction SilentlyContinue
Set-Service -Name $svc.Name -StartupType Disabled -ErrorAction SilentlyContinue
}
} else {
Write-Log "$($svc.Name) servisi bu sistemde bulunamadi, atlanıyor..."
}
}
Write-Log "Hardening scripti tamamlandi"
Write-Log "Log dosyasi: $LogPath"
Bu scripti .Harden-Server.ps1 -WhatIf parametresiyle çalıştırarak önce ne yapacağını görebilirsiniz.
Grup İlkesi ile Merkezi Yönetim
Birden fazla sunucu yönetiyorsanız, bu ayarları Group Policy üzerinden uygulamak çok daha verimli.
# GPO ile servis ayarlarını yönetmek için örnek
# Bu komutlar bir yönetim makinesinde çalıştırılır
# Belirli bir OU'daki tüm sunuculara GPO uygulamak için
Import-Module GroupPolicy
# Yeni bir GPO oluştur
New-GPO -Name "Server_Hardening_Policy" -Comment "Sunucu güvenlik sertleştirme politikası"
# GPO'yu OU'ya bağla
New-GPLink -Name "Server_Hardening_Policy" -Target "OU=Servers,DC=domain,DC=local"
# Belirli bir makinede GPO güncellemesini zorla
Invoke-GPUpdate -Computer "SunucuAdi" -Force -RandomDelayInMinutes 0
Değişiklik Sonrası Doğrulama
Değişiklikleri yaptıktan sonra doğrulama yapmak kritik önem taşır.
# Kapatılan servislerin durumunu kontrol et
$criticalServices = @("RemoteRegistry", "Fax", "Spooler", "WSearch")
foreach ($svc in $criticalServices) {
$service = Get-Service -Name $svc -ErrorAction SilentlyContinue
if ($service) {
$status = $service.Status
$startType = $service.StartType
Write-Host "Servis: $svc | Durum: $status | Baslangic: $startType" -ForegroundColor $(if($startType -eq "Disabled"){"Green"}else{"Red"})
}
}
# SMBv1 durumunu doğrula
$smb1Status = Get-SmbServerConfiguration | Select-Object -ExpandProperty EnableSMB1Protocol
Write-Host "SMBv1 Durumu: $smb1Status" -ForegroundColor $(if(-not $smb1Status){"Green"}else{"Red"})
# Açık portları kontrol et (netstat yerine PowerShell ile)
Get-NetTCPConnection -State Listen | Where-Object {$_.LocalPort -lt 1024} | Select-Object LocalPort, State, OwningProcess | Sort-Object LocalPort
Dikkat Edilmesi Gereken Durumlar
Bu süreçte karşılaşabileceğiniz yaygın sorunlar ve çözümleri:
- Print Spooler ve Active Directory: Bazı eski LDAP araçları Print Spooler servisiyle etkileşime girer. Kapatmadan önce test edin.
- Remote Registry ve monitoring araçları: Nagios, SCOM gibi monitoring çözümleri Remote Registry’ye ihtiyaç duyabilir. Alternatif olarak WMI veya SNMP kullanabilirsiniz.
- SMBv1 ve eski NAS cihazları: Synology, QNAP gibi eski firmware’li NAS cihazları SMBv1 gerektirebilir. Firmware güncellemesi yapın, SMBv1’i açık tutmayın.
- Windows Search ve SQL Server: Bazı SQL Server özellikleri Windows Search’e bağımlı olabilir. Full-text search kullanıyorsanız bu bağımlılığı kontrol edin.
- Değişiklikleri test ortamında deneyin: Hiçbir zaman bu tür değişiklikleri doğrudan üretim ortamında uygulamayın.
Düzenli Denetim ve Bakım
Güvenlik sertleştirme tek seferlik bir işlem değil, sürekli bir süreç. Bunu rutine bağlamak için şu yaklaşımı öneriyorum:
# Aylık servis denetim scripti
# Scheduled Task olarak çalıştırın
$reportPath = "C:SecurityReportsService_Audit_$(Get-Date -Format 'yyyyMMdd').txt"
New-Item -ItemType Directory -Path (Split-Path $reportPath) -Force | Out-Null
$report = @()
$report += "=== SERVIS DENETIM RAPORU ==="
$report += "Tarih: $(Get-Date)"
$report += "Sunucu: $env:COMPUTERNAME"
$report += ""
# Beklenmedik şekilde başlayan servisleri tespit et
$unexpectedRunning = Get-Service | Where-Object {
$_.Status -eq "Running" -and
$_.StartType -eq "Disabled"
}
if ($unexpectedRunning) {
$report += "[UYARI] Disabled olmasina ragmen calisan servisler:"
$unexpectedRunning | ForEach-Object {
$report += " - $($_.Name) ($($_.DisplayName))"
}
} else {
$report += "[OK] Tum servis durumlari beklendigi gibi"
}
$report | Out-File -FilePath $reportPath
Write-Host "Rapor olusturuldu: $reportPath"
Bu scripti Windows Task Scheduler ile aylık çalışacak şekilde ayarlayın ve raporları mail ile gönderin.
Sonuç
Windows Server güvenlik sertleştirmesi, tek bir komut ya da tek bir kurala indirgenemeyecek kadar çok boyutlu bir konu. Ancak temel prensip basit: çalıştırmadığınız şeye saldıramazlar.
Bu yazıda anlattığım adımları uygularken şu sırayı takip etmenizi öneririm. İlk olarak mevcut durumunuzu belgeleyin ve baseline alın. Ardından test ortamında değişiklikleri uygulayın ve en az bir hafta boyunca sistemi izleyin. Sorun çıkmazsa üretim ortamına taşıyın. Son olarak değişiklikleri Change Management sürecinize dahil edin ve dokümante edin.
Güvenlik bir hedef değil, sürekli iyileştirilen bir süreçtir. Her yeni CVE yayınlandığında, her yeni servis kurduğunuzda, “bu gerçekten gerekli mi?” diye sormayı alışkanlık haline getirin. Saldırı yüzeyini küçük tutmak, en ucuz ve en etkili güvenlik önlemlerinden biridir.
Sorularınız olursa yorumlar kısmında belirtin, elimden geldiğince yanıtlamaya çalışırım.