Windows Server Rolleri ve Gereksiz Servisleri Devre Dışı Bırakma

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.

Yorum yapın