Windows Server’da İki Faktörlü Kimlik Doğrulama

Güvenlik ihlallerinin büyük çoğunluğu hâlâ çalınan ya da tahmin edilen parolalar üzerinden gerçekleşiyor. Sadece parola korumasına güvenmek, özellikle Windows Server ortamlarında ciddi bir risk. İki faktörlü kimlik doğrulama (2FA), bu riski dramatik biçimde azaltan ve kurumsal güvenliğin olmazsa olmaz parçası haline gelen bir katman. Bu yazıda Windows Server ortamında 2FA’yı nasıl kuracağınızı, yapılandıracağınızı ve yöneteceğinizi adım adım ele alacağız.

İki Faktörlü Kimlik Doğrulama Neden Bu Kadar Kritik?

Önce somut bir senaryo üzerinden düşünelim. Bir muhasebe çalışanının RDP şifresi, phishing saldırısıyla ele geçirildi. Saldırgan gece yarısı sunucuya bağlandı, finansal verileri kopyaladı ve izini örttü. Sabaha kadar kimse fark etmedi. Bu senaryo maalesef sık karşılaştığım gerçek vakalardan birinin özeti.

2FA devrede olsaydı, çalınan parola tek başına işe yaramayacaktı. Saldırganın aynı zamanda fiziksel bir cihaza ya da kullanıcının telefonuna erişmesi gerekecekti.

Windows Server ortamında 2FA’nın koruduğu başlıca alanlar şunlar:

  • RDP (Remote Desktop Protocol) bağlantıları
  • Active Directory kullanıcı oturumları
  • VPN erişimleri
  • Web tabanlı yönetim arayüzleri (IIS, OWA vb.)
  • PowerShell Remoting oturumları

Windows Server’da 2FA Seçenekleri

Microsoft’un yerleşik araçları ve üçüncü parti çözümler dahil olmak üzere birden fazla yol var. Her birinin artısı ve eksiği mevcut.

Microsoft Authenticator ve Azure AD MFA

Eğer Azure AD (şimdiki adıyla Microsoft Entra ID) kullanıyorsanız, Azure MFA en doğal tercih. Hibrit ortamlarda AD Connect ile on-premise Active Directory’yi Azure AD ile senkronize edip MFA katmanını bulut üzerinden ekleyebilirsiniz.

RADIUS Protokolü ile NPS Extension

On-premise ortamlarda en yaygın çözüm, Network Policy Server (NPS) ile Azure AD MFA Extension kombinasyonu. Bu yaklaşım özellikle RDP ve VPN için son derece etkili.

Üçüncü Parti Çözümler

  • Duo Security (Cisco)
  • Authy for Enterprise
  • TOTP tabanlı açık kaynak çözümler (Google Authenticator uyumlu)
  • YubiKey ile FIDO2/U2F

Bu yazıda hem NPS + Azure MFA yolunu hem de TOTP tabanlı açık kaynak yaklaşımı ele alacağız.

Yöntem 1: NPS Extension ile Azure AD MFA

Bu yöntem, mevcut Active Directory altyapısını koruyarak bulut tabanlı MFA eklemek isteyenler için ideal.

Önkoşullar

  • Windows Server 2016 veya üzeri
  • Azure AD Premium P1 veya P2 lisansı (bazı planlar MFA’yı ücretsiz içerir)
  • AD Connect ile hibrit kurulum
  • NPS rolü yüklenmiş sunucu

NPS Rolünü Kurma

Önce NPS rolünü PowerShell ile yükleyelim:

# NPS rolünü kur
Install-WindowsFeature NPAS -IncludeManagementTools

# Servis durumunu kontrol et
Get-Service -Name IAS

# NPS servisini başlat
Start-Service -Name IAS

Azure AD MFA NPS Extension Kurulumu

Microsoft’un indirme sayfasından NPS Extension’ı indirdikten sonra kurulum başlangıçta basit görünse de birkaç kritik adım var.

# PowerShell'i yönetici olarak aç ve kurulum scriptini çalıştır
# NPS Extension kurulumundan sonra konfigürasyon scriptini çalıştır

cd "C:Program FilesMicrosoftAzureMfaConfig"

# Tenant ID ile scripti çalıştır
.AzureMfaNpsExtnConfigSetup.ps1

# Servisleri yeniden başlat
Restart-Service -Name IAS
Restart-Service -Name RasMan

Tenant ID’nizi bulmak için:

# Azure AD PowerShell modülü ile tenant bilgisi
Connect-AzureAD
(Get-AzureADTenantDetail).ObjectId

RDP için NPS Politikası Oluşturma

NPS konsolunda Connection Request Policy ve Network Policy oluşturmanız gerekiyor. Bunu PowerShell ile de yapabilirsiniz:

# NPS politika durumunu kontrol et
netsh nps show config

# Mevcut politikaları listele
netsh nps show crpolicy

# Yeni connection request policy ekle (RDP için)
netsh nps add crpolicy name="RDP-MFA-Policy" processingorder=1 condition="NAS-Port-Type=Virtual(VPN)" authtype=MSPV2

Registry Ayarları

NPS Extension bazı registry değerlerine ihtiyaç duyar:

# MFA timeout süresini ayarla (saniye cinsinden)
Set-ItemProperty -Path "HKLM:SOFTWAREMicrosoftAzureMfa" `
  -Name "OVERRIDE_NUMBER_OF_RETRIES" -Value 3 -Type DWord

# Bypass listesi (acil durum hesapları için)
Set-ItemProperty -Path "HKLM:SOFTWAREMicrosoftAzureMfa" `
  -Name "BYPASS_USERNAMES" -Value "[email protected]" -Type String

# Extension log seviyesi
Set-ItemProperty -Path "HKLM:SOFTWAREMicrosoftAzureMfa" `
  -Name "OVERRIDE_NUMBER_OF_RETRIES" -Value 3

Yöntem 2: TOTP Tabanlı Açık Kaynak Çözüm

Azure lisansı olmayan ya da tamamen on-premise kalmak isteyenler için TOTP (Time-based One-Time Password) tabanlı bir çözüm daha uygun olabilir. Bu senaryoda winauth veya benzeri araçlarla ya da custom bir RADIUS sunucusu kurarak ilerleyebilirsiniz.

Pratik bir yaklaşım olarak FreeRADIUS + Google Authenticator PAM kombinasyonunu Windows ortamına entegre etmek mümkün. Ancak çoğu sysadmin için daha gerçekçi seçenek, Duo Security’nin ücretsiz katmanı veya doğrudan RDP Gateway üzerinden çalışan bir çözüm.

Duo Security ile RDP Koruması

Duo’nun Windows Logon eklentisi kurulumu oldukça basit ve ücretsiz katmanı küçük ekipler için yeterli.

# Duo kurulum sonrası konfigürasyon dosyası
# C:Program FilesDuo Security Authenticationduo.conf

# PowerShell ile konfigürasyonu doğrula
$duoConf = Get-Content "C:Program FilesDuo Security Authenticationduo.conf"
$duoConf | Select-String "ikey|skey|host"

# Duo servis durumu
Get-Service -Name "Duo Security Authentication"
Start-Service -Name "Duo Security Authentication"

Active Directory ile 2FA Politikası Entegrasyonu

2FA’yı AD Group Policy ile zorunlu kılmak, yönetim açısından hayatı kolaylaştırır.

GPO ile RDP Güvenlik Ayarları

# GPO oluştur ve 2FA gerektiren ayarları uygula
New-GPO -Name "Server-RDP-MFA-Policy" -Comment "RDP icin MFA zorunlu"

# GPO'yu OU'ya bağla
New-GPLink -Name "Server-RDP-MFA-Policy" `
  -Target "OU=Servers,DC=domain,DC=local" `
  -LinkEnabled Yes

# Network Level Authentication'ı zorla (GPO ile)
# Bu ayar: Computer Config > Admin Templates > Windows Components > 
# Remote Desktop Services > RDP Session Host > Security
Set-GPRegistryValue -Name "Server-RDP-MFA-Policy" `
  -Key "HKLMSOFTWAREPoliciesMicrosoftWindows NTTerminal Services" `
  -ValueName "UserAuthentication" -Type DWord -Value 1

# RDP minimum şifreleme seviyesi
Set-GPRegistryValue -Name "Server-RDP-MFA-Policy" `
  -Key "HKLMSOFTWAREPoliciesMicrosoftWindows NTTerminal Services" `
  -ValueName "MinEncryptionLevel" -Type DWord -Value 3

Conditional Access Politikaları

Azure AD kullanıyorsanız Conditional Access, 2FA’yı çok daha granüler hale getiriyor:

# Azure AD Conditional Access politikasını PowerShell ile kontrol et
Connect-AzureAD
Get-AzureADMSConditionalAccessPolicy | Select-Object DisplayName, State

# MFA gerektiren politikaları filtrele
Get-AzureADMSConditionalAccessPolicy | Where-Object {
  $_.GrantControls.BuiltInControls -contains "mfa"
} | Select-Object DisplayName, State, CreatedDateTime

RD Gateway Üzerinden 2FA

Remote Desktop Gateway, dışarıdan gelen RDP bağlantıları için mükemmel bir kontrol noktası. 2FA’yı RD Gateway seviyesinde uygulamak, iç ağa hiçbir doğrulanmamış bağlantı geçirmez.

# RD Gateway rolünü kur
Install-WindowsFeature RDS-Gateway -IncludeManagementTools

# RD Gateway Manager'ı aç (GUI)
mmc.exe

# PowerShell ile gateway politikalarını listele
Import-Module RemoteDesktopServices
Get-RDSessionCollection

# CAP (Connection Authorization Policy) durumu
Get-Item -Path RDS:GatewayServerCAP

# RAP (Resource Authorization Policy) listele  
Get-Item -Path RDS:GatewayServerRAP

RD Gateway’i NPS ile entegre ederek MFA akışını şöyle kurgulayabilirsiniz:

  1. Kullanıcı RD Gateway’e bağlanır
  2. Gateway, NPS’e kimlik doğrulama isteği gönderir
  3. NPS Extension, Azure MFA’ya push notification gönderir
  4. Kullanıcı telefondan onaylar
  5. Gateway bağlantıya izin verir

Break-Glass Hesapları ve Acil Durum Prosedürleri

2FA kurulumunun en sık atlanan kısmı burası. MFA sistemi çöktüğünde ya da yöneticinin telefonu olmadığında ne yapacaksınız?

# Break-glass hesabı oluştur (MFA bypass için)
New-ADUser -Name "BreakGlass-Admin" `
  -SamAccountName "bgadmin" `
  -UserPrincipalName "[email protected]" `
  -AccountPassword (ConvertTo-SecureString "Guclu_Parola_123!" -AsPlainText -Force) `
  -Enabled $true `
  -PasswordNeverExpires $true

# Bu hesabı MFA bypass grubuna ekle
Add-ADGroupMember -Identity "MFA-Bypass-Group" -Members "bgadmin"

# Hesap kullanımını audit et (olay tetiklendiğinde uyarı gönder)
$filter = @{
  LogName = 'Security'
  Id = 4624
  StartTime = (Get-Date).AddHours(-1)
}

Get-WinEvent -FilterHashtable $filter | Where-Object {
  $_.Properties[5].Value -eq "bgadmin"
} | Select-Object TimeCreated, Message

Break-glass hesapları için altın kurallar:

  • Şifreyi fiziksel kasada veya şifreli dijital kasada saklayın
  • Kullanıldığında otomatik uyarı gönderecek audit kuralı tanımlayın
  • Düzenli aralıklarla şifreyi rotasyona sokun
  • Sadece gerçek acil durumlarda kullanın ve sonra mutlaka log inceleyin

Güvenlik Loglarını İzleme

2FA kurdunuz, harika. Ama düzgün izleme yoksa güvenlik yarım kalır.

# Başarısız MFA denemelerini izle
Get-WinEvent -LogName "Security" | Where-Object {
  $_.Id -eq 6273 -and $_.Message -like "*Reason Code: 16*"
} | Select-Object TimeCreated, 
  @{N="Username";E={$_.Properties[1].Value}},
  @{N="ClientIP";E={$_.Properties[13].Value}} |
  Sort-Object TimeCreated -Descending |
  Select-Object -First 20

# NPS event loglarını kontrol et
Get-WinEvent -LogName "Security" -FilterXPath `
  "*[System[(EventID=6272 or EventID=6273 or EventID=6274)]]" |
  Select-Object TimeCreated, Id, Message |
  Sort-Object TimeCreated -Descending

# Şüpheli IP adreslerinden gelen başarısız denemeleri say
$events = Get-WinEvent -LogName "Security" | Where-Object { $_.Id -eq 6273 }
$events | ForEach-Object {
  $_.Properties[13].Value
} | Group-Object | Sort-Object Count -Descending | Select-Object -First 10

Otomatik Kilitleme Scripti

Belirli bir IP’den çok fazla başarısız deneme geliyorsa otomatik engelleyelim:

# Brute force tespiti ve otomatik firewall engeli
$threshold = 5
$timeWindow = 15  # dakika

$recentFailures = Get-WinEvent -LogName "Security" | Where-Object {
  $_.Id -eq 6273 -and 
  $_.TimeCreated -gt (Get-Date).AddMinutes(-$timeWindow)
}

$suspiciousIPs = $recentFailures | ForEach-Object {
  $_.Properties[13].Value
} | Group-Object | Where-Object { $_.Count -ge $threshold }

foreach ($ip in $suspiciousIPs) {
  $ipAddress = $ip.Name
  Write-Host "Engelleniyor: $ipAddress ($($ip.Count) basarisiz deneme)"
  
  # Windows Firewall ile engelle
  New-NetFirewallRule `
    -DisplayName "AUTO-BLOCK-$ipAddress" `
    -Direction Inbound `
    -RemoteAddress $ipAddress `
    -Action Block `
    -Profile Any
    
  # Log dosyasına yaz
  "$((Get-Date).ToString()) - Blocked: $ipAddress - Attempts: $($ip.Count)" | 
    Add-Content "C:Logsmfa-blocks.log"
}

Sık Karşılaşılan Sorunlar ve Çözümleri

NPS Extension Bağlantı Sorunları

# NPS Extension log dosyalarını kontrol et
Get-Content "C:Program FilesMicrosoftAzureMfaLogs*.log" -Tail 50

# Sertifika sorunlarını kontrol et
Get-ChildItem Cert:LocalMachineMy | Where-Object {
  $_.Subject -like "*Azure*"
} | Select-Object Subject, NotAfter, Thumbprint

# Azure bağlantısını test et
Test-NetConnection -ComputerName "adnotifications.windowsazure.com" -Port 443
Test-NetConnection -ComputerName "strongauthenticationservice.auth.microsoft.com" -Port 443

Kullanıcı MFA Kaydı Sorunları

# Kullanıcının MFA durumunu kontrol et (MSOnline modülü)
Connect-MsolService
Get-MsolUser -UserPrincipalName "[email protected]" | 
  Select-Object DisplayName, StrongAuthenticationRequirements, 
  StrongAuthenticationMethods

# Tüm kullanıcıların MFA durumunu raporla
Get-MsolUser -All | Select-Object UserPrincipalName, 
  @{N="MFAStatus";E={
    if ($_.StrongAuthenticationRequirements) { "Enabled" } 
    else { "Disabled" }
  }} | Export-Csv "C:Reportsmfa-status.csv" -NoTypeInformation

Zaman Senkronizasyon Sorunları

TOTP tabanlı çözümlerde en sık karşılaşılan sorun, sunucu saatinin doğru ayarlanmaması. TOTP 30 saniyelik pencereler kullanır ve zaman sapması token geçersizliğine yol açar.

# NTP durumunu kontrol et
w32tm /query /status

# NTP sunucusunu yapılandır
w32tm /config /manualpeerlist:"time.windows.com,0x8 pool.ntp.org,0x8" /syncfromflags:manual /reliable:YES /update

# Zaman servisini yeniden başlat
Restart-Service w32tm
w32tm /resync /force

# Sapma miktarını kontrol et (0.5 saniyeden az olmalı)
w32tm /query /status | Select-String "RMS Offset"

Gerçek Dünya Senaryosu: 50 Kişilik Şirkette 2FA Rollout

Geçen yıl bir müşteri için yaptığım deployment’ı özetleyeyim. 50 kullanıcılı, 3 Windows Server 2019’dan oluşan bir ortam. Azure AD Premium lisansları zaten vardı ama MFA açılmamıştı.

Aşama 1 (1. Hafta): NPS kurulumu ve test ortamında doğrulama. Sadece IT ekibi (5 kişi) pilot grupta.

Aşama 2 (2. Hafta): Kullanıcılara Microsoft Authenticator kurulum kılavuzu gönderildi. Yardım masası desteği hazır tutuldu. Yöneticiler dahil 20 kişiye genişletildi.

Aşama 3 (3-4. Hafta): Kalan tüm kullanıcılar. Break-glass hesapları oluşturuldu ve kasaya kaldırıldı.

Rollout sırasında en çok karşılaştığımız sorunlar:

  • “Telefonum yanımda değildi” — Backup kodu önceden verilmeli
  • NTP sapması — Tüm sunucularda saat senkronizasyonu kontrol edilmeli
  • VPN + RDP çakışması — NPS politika sıralaması kritik
# Rollout öncesi kullanıcı hazırlığını kontrol et
# MFA kaydı tamamlanmamış kullanıcıları bul
Get-MsolUser -All | Where-Object {
  $_.StrongAuthenticationMethods.Count -eq 0 -and
  $_.BlockCredential -eq $false
} | Select-Object UserPrincipalName, DisplayName |
  Export-Csv "C:Reportsmfa-not-registered.csv" -NoTypeInformation

Write-Host "MFA kaydi tamamlanmamis kullanici sayisi: $(
  (Import-Csv 'C:Reportsmfa-not-registered.csv').Count
)"

Düzenli Bakım ve Denetim

2FA kurulumu bir kerelik iş değil. Periyodik kontroller şart.

# Haftalik MFA saglik kontrolu scripti
# Cron Job / Task Scheduler ile calistirin

# 1. NPS servis durumu
$npsStatus = Get-Service -Name IAS
if ($npsStatus.Status -ne "Running") {
  Send-MailMessage -To "[email protected]" `
    -Subject "KRITIK: NPS Servisi Calısmiyor" `
    -Body "NPS servisi durdu! Hemen kontrol edin." `
    -SmtpServer "mail.domain.com" `
    -From "[email protected]"
}

# 2. Son 24 saatte MFA bypass kullanimi
$bypassEvents = Get-WinEvent -LogName "Security" | Where-Object {
  $_.Id -eq 4624 -and
  $_.TimeCreated -gt (Get-Date).AddHours(-24) -and
  $_.Properties[5].Value -eq "bgadmin"
}

if ($bypassEvents.Count -gt 0) {
  Write-Warning "Break-glass hesabi $($bypassEvents.Count) kez kullanildi!"
}

# 3. Suresi dolmus sertifikalari kontrol et
Get-ChildItem Cert:LocalMachineMy | Where-Object {
  $_.NotAfter -lt (Get-Date).AddDays(30)
} | Select-Object Subject, NotAfter

Sonuç

Windows Server ortamında 2FA kurmak artık lüks değil, temel gereksinim. Özellikle RDP erişimi olan her sunucu, 2FA olmadan internete açık bir kapı bırakmak anlamına geliyor.

Bu yazıda ele aldığımız yaklaşımları özetlersek: Azure AD ortamı varsa NPS Extension + Azure MFA kombinasyonu en temiz ve en yönetilebilir çözüm. On-premise kalmanız gerekiyorsa Duo Security gibi üçüncü parti araçlar ciddi kolaylık sağlıyor. Her iki durumda da RD Gateway seviyesinde uygulama, ek bir güvenlik katmanı sunuyor.

En kritik hatırlatma: Break-glass hesaplarını ve acil durum prosedürlerini kurulum öncesinde planlayın. 2FA sistemi kendisi bir sorun çıkardığında hazırlıksız yakalanmak, güvenliği artırmak için kurduğunuz sistemin tam tersine işlemesine yol açabilir.

Log izleme ve periyodik denetimler olmadan 2FA yarım kalır. Scriptleri görev zamanlayıcıya alın, kritik olaylar için mail uyarısı kurun ve en az ayda bir MFA kayıt raporunu gözden geçirin. Güvenlik, sürekli bakım gerektiren canlı bir süreç.

Yorum yapın