Güvenli bir Windows Server ortamı kurmak istiyorsanız, SSL/TLS yapılandırması konusunu atlamak büyük bir hata olur. Özellikle PCI DSS, HIPAA veya ISO 27001 gibi uyumluluk gereksinimlerini karşılamanız gerekiyorsa, hangi protokol sürümlerinin aktif olduğunu ve cipher suite sıralamasının nasıl yapılandırıldığını bilmek zorundasınız. Bu yazıda sıfırdan başlayarak Windows Server’da SSL/TLS yapılandırmasını Registry düzeyinden Group Policy’ye kadar her açıdan ele alacağız.
SSL/TLS Neden Bu Kadar Önemli?
Birkaç yıl önce bir müşterinin e-ticaret sunucusunu denetlerken TLS 1.0 ve hatta SSLv3’ün hâlâ aktif olduğunu gördüm. Sunucu 2012’den beri kimse dokunmadan çalışıyordu. POODLE ve BEAST saldırılarına karşı tamamen açıktı. Üstelik ödeme altyapısı da bu sunucu üzerinden geçiyordu. İşte bu tür senaryolar, SSL/TLS yapılandırmasının neden rutin bakımın bir parçası olması gerektiğini açıkça gösteriyor.
Windows Server varsayılan olarak geriye dönük uyumluluğu ön planda tutar. Bu da beraberinde güvenlik açıkları getiriyor. TLS 1.0 ve TLS 1.1 artık resmi olarak kullanımdan kaldırılmış durumda. TLS 1.2 minimum standart, TLS 1.3 ise hedef olmalı.
Mevcut Durumu Tespit Etmek
Herhangi bir değişiklik yapmadan önce mevcut durumu anlamak gerekiyor. PowerShell ile hızlıca kontrol edebilirsiniz:
# Mevcut TLS protokol durumunu kontrol et
$protocols = @("SSL 2.0", "SSL 3.0", "TLS 1.0", "TLS 1.1", "TLS 1.2", "TLS 1.3")
foreach ($protocol in $protocols) {
$serverKey = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocols$protocolServer"
$clientKey = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocols$protocolClient"
$serverEnabled = (Get-ItemProperty -Path $serverKey -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
$clientEnabled = (Get-ItemProperty -Path $clientKey -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
Write-Host "Protokol: $protocol | Server: $serverEnabled | Client: $clientEnabled"
}
Bu komut size her protokolün mevcut durumunu gösterir. $null dönen değerler, kayıt defterinde açıkça belirtilmemiş ve sistemin varsayılan davranışına bırakılmış anlamına gelir. Bu da genellikle tehlikeli bir durumdur, çünkü Windows sürümüne göre varsayılanlar değişir.
Dışarıdan da test edebilirsiniz. Nmap ile hızlı bir tarama:
# Nmap ile SSL/TLS taraması (Linux tarafından veya WSL üzerinden)
nmap --script ssl-enum-ciphers -p 443 192.168.1.100
# Sadece protokol versiyonlarını görmek için
nmap --script ssl-dh-params,ssl-heartbleed -p 443,8443 192.168.1.100
Registry Üzerinden Manuel Yapılandırma
Windows’ta SSL/TLS yapılandırmasının kalbi HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSecurityProvidersSCHANNEL registry anahtarıdır. Buradaki değişiklikler Schannel bileşenini etkiler ve bu bileşen IIS, RDP, LDAPS, Exchange ve diğer pek çok servis tarafından kullanılır.
Önce eski ve güvensiz protokolleri devre dışı bırakalım:
# SSL 2.0 ve SSL 3.0 devre dışı bırak, TLS 1.0 ve 1.1 kapat
# PowerShell ile çalıştırın - Yönetici yetkisi gerekli
$schannelPath = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocols"
# Devre dışı bırakılacak protokoller
$disableProtocols = @("SSL 2.0", "SSL 3.0", "TLS 1.0", "TLS 1.1")
foreach ($protocol in $disableProtocols) {
# Server tarafı
$serverPath = "$schannelPath$protocolServer"
if (-not (Test-Path $serverPath)) {
New-Item -Path $serverPath -Force | Out-Null
}
Set-ItemProperty -Path $serverPath -Name "Enabled" -Value 0 -Type DWord
Set-ItemProperty -Path $serverPath -Name "DisabledByDefault" -Value 1 -Type DWord
# Client tarafı
$clientPath = "$schannelPath$protocolClient"
if (-not (Test-Path $clientPath)) {
New-Item -Path $clientPath -Force | Out-Null
}
Set-ItemProperty -Path $clientPath -Name "Enabled" -Value 0 -Type DWord
Set-ItemProperty -Path $clientPath -Name "DisabledByDefault" -Value 1 -Type DWord
Write-Host "$protocol devre disi birakildi." -ForegroundColor Green
}
# TLS 1.2 ve TLS 1.3 etkinleştir
$enableProtocols = @("TLS 1.2", "TLS 1.3")
foreach ($protocol in $enableProtocols) {
$serverPath = "$schannelPath$protocolServer"
if (-not (Test-Path $serverPath)) {
New-Item -Path $serverPath -Force | Out-Null
}
Set-ItemProperty -Path $serverPath -Name "Enabled" -Value 1 -Type DWord
Set-ItemProperty -Path $serverPath -Name "DisabledByDefault" -Value 0 -Type DWord
$clientPath = "$schannelPath$protocolClient"
if (-not (Test-Path $clientPath)) {
New-Item -Path $clientPath -Force | Out-Null
}
Set-ItemProperty -Path $clientPath -Name "Enabled" -Value 1 -Type DWord
Set-ItemProperty -Path $clientPath -Name "DisabledByDefault" -Value 0 -Type DWord
Write-Host "$protocol etkinlestirildi." -ForegroundColor Cyan
}
Write-Host "Degisikliklerin gecerli olmasi icin sunucuyu yeniden baslatmaniz gerekiyor!" -ForegroundColor Yellow
Önemli Not: Bu değişiklikler sunucu yeniden başlatılmadan aktif olmaz. Üretim ortamında değişiklik yapıyorsanız mutlaka bir bakım penceresi planlayın.
Cipher Suite Yapılandırması
Protokol sürümlerini doğru ayarlamak yeterli değil. Hangi şifreleme algoritmalarının kullanıldığı da en az protokol versiyonu kadar kritik. Zayıf cipher suite’ler, güçlü bir protokol sürümü kullanıyor olsanız bile sizi savunmasız bırakabilir.
RC4, DES, 3DES ve NULL cipher’ları kesinlikle devre dışı bırakılmalı. ECDHE ve DHE tabanlı anahtar değişimi sunan, AES-GCM kullanan ve SHA-256 veya üzeri hash kullanan cipher suite’lere öncelik verilmeli.
# Mevcut cipher suite listesini görüntüle
Get-TlsCipherSuite | Select-Object Name, Exchange, Cipher, Hash | Format-List
# Zayıf cipher suite'leri devre dışı bırak
$weakCiphers = @(
"TLS_RSA_WITH_RC4_128_MD5",
"TLS_RSA_WITH_RC4_128_SHA",
"TLS_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_RSA_WITH_NULL_SHA256",
"TLS_RSA_WITH_NULL_SHA",
"TLS_RSA_WITH_NULL_MD5",
"TLS_DHE_RSA_WITH_DES_CBC_SHA",
"SSL_CK_DES_192_EDE3_CBC_WITH_MD5"
)
foreach ($cipher in $weakCiphers) {
try {
Disable-TlsCipherSuite -Name $cipher -ErrorAction SilentlyContinue
Write-Host "Devre disi: $cipher" -ForegroundColor Red
} catch {
Write-Host "Bulunamadi veya zaten devre disi: $cipher" -ForegroundColor Gray
}
}
# Güçlü cipher suite'leri öne al
$strongCiphers = @(
"TLS_AES_256_GCM_SHA384",
"TLS_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
)
foreach ($cipher in $strongCiphers) {
try {
Enable-TlsCipherSuite -Name $cipher -Position 0
Write-Host "Etkinlestirildi ve one alindi: $cipher" -ForegroundColor Green
} catch {
Write-Host "Desteklenmiyor: $cipher" -ForegroundColor Gray
}
}
IIS Özelinde SSL/TLS Yapılandırması
IIS kullanıyorsanız, Schannel ayarlarının yanı sıra IIS binding konfigürasyonuna da dikkat etmeniz gerekiyor. IIS, Schannel’in sunduğu protokollerden yararlanır ama site bazında da bazı ek ayarlar yapılabilir.
# IIS üzerinde HTTPS binding'i kontrol et ve güçlendir
Import-Module WebAdministration
# Mevcut HTTPS binding'leri listele
Get-WebBinding -Protocol "https" | Select-Object bindingInformation, sslFlags
# SSL Flag'leri ayarla - SNI ve client cert gereksinimleri
# sslFlags değerleri:
# 0 = Standart SSL
# 1 = SNI (Server Name Indication) aktif
# 2 = IP tabanlı SSL değil, host header bazlı
# 8 = Client sertifika gerekli
# Örnek: Belirli bir site için SNI etkinleştir
Set-WebBinding -Name "VarsayilanWebSitesi" -BindingInformation "*:443:" -PropertyName sslFlags -Value 1
# HTTP Strict Transport Security (HSTS) header ekle
# web.config üzerinden veya PowerShell ile IIS modülü ekleyerek yapılabilir
$hstsSitePath = "IIS:SitesVarsayilanWebSitesi"
Add-WebConfigurationProperty -PSPath $hstsSitePath `
-Filter "system.webServer/httpProtocol/customHeaders" `
-Name "." `
-Value @{name="Strict-Transport-Security"; value="max-age=31536000; includeSubDomains; preload"}
Write-Host "HSTS header eklendi." -ForegroundColor Green
Group Policy ile Merkezi Yönetim
Birden fazla sunucunuz varsa her birinde tek tek değişiklik yapmak hem zaman alır hem de tutarsızlıklara yol açar. Group Policy, merkezi yönetimin en pratik yoludur.
GPO ile SSL/TLS yapılandırması için iki yol var. Birincisi, Group Policy Preferences üzerinden registry değerlerini dağıtmak. İkincisi, özel bir ADMX şablonu kullanmak. Registry yolu çok daha yaygın ve esnek:
GPO Registry Ayarları:
- Konum: Computer Configuration > Preferences > Windows Settings > Registry
- Hive: HKEY_LOCAL_MACHINE
- Key Path: SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsTLS 1.0Server
- Value Name: Enabled
- Value Type: REG_DWORD
- Value Data: 0
Bu yapıyı her protokol ve Client/Server kombinasyonu için tekrar etmeniz gerekiyor. Evet, biraz uzun sürüyor ama bir kez doğru kurulduktan sonra tüm sunuculara otomatik dağıtılıyor.
Toplu dağıtım için PowerShell DSC de güçlü bir alternatif:
# PowerShell DSC ile TLS yapılandırması
Configuration SecureTLSConfig {
param (
[string[]]$ComputerName = "localhost"
)
Import-DscResource -ModuleName PSDesiredStateConfiguration
Node $ComputerName {
# TLS 1.0 Server - Devre disi
Registry "TLS10ServerDisabled" {
Ensure = "Present"
Key = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsTLS 1.0Server"
ValueName = "Enabled"
ValueData = "0"
ValueType = "Dword"
}
# TLS 1.2 Server - Aktif
Registry "TLS12ServerEnabled" {
Ensure = "Present"
Key = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsTLS 1.2Server"
ValueName = "Enabled"
ValueData = "1"
ValueType = "Dword"
}
# TLS 1.2 Client - Aktif
Registry "TLS12ClientEnabled" {
Ensure = "Present"
Key = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsTLS 1.2Client"
ValueName = "Enabled"
ValueData = "1"
ValueType = "Dword"
}
}
}
# Konfigürasyonu derle ve uygula
SecureTLSConfig -OutputPath "C:DSCTLSConfig"
Start-DscConfiguration -Path "C:DSCTLSConfig" -Wait -Verbose -Force
.NET Framework TLS Uyumluluğu
Bu konuyu atlayan sistem yöneticileri çok sık görüyorum. Windows’ta Schannel ayarlarını doğru yapılandırdığınızda bile .NET Framework uygulamaları kendi TLS davranışlarını sergileyebilir. .NET 4.5 ve öncesi, varsayılan olarak TLS 1.0 kullanır. Bu ayarı da düzeltmeniz gerekiyor:
# .NET Framework TLS 1.2 zorunlu hale getir
# 32-bit ve 64-bit .NET için ayrı ayrı yapılmalı
# .NET Framework 4.x - 64-bit
$net4x64Path = "HKLM:SOFTWAREMicrosoft.NETFrameworkv4.0.30319"
Set-ItemProperty -Path $net4x64Path -Name "SystemDefaultTlsVersions" -Value 1 -Type DWord
Set-ItemProperty -Path $net4x64Path -Name "SchUseStrongCrypto" -Value 1 -Type DWord
# .NET Framework 4.x - 32-bit
$net4x32Path = "HKLM:SOFTWAREWOW6432NodeMicrosoft.NETFrameworkv4.0.30319"
if (Test-Path $net4x32Path) {
Set-ItemProperty -Path $net4x32Path -Name "SystemDefaultTlsVersions" -Value 1 -Type DWord
Set-ItemProperty -Path $net4x32Path -Name "SchUseStrongCrypto" -Value 1 -Type DWord
}
# .NET Framework 2.0/3.5
$net2xPath = "HKLM:SOFTWAREMicrosoft.NETFrameworkv2.0.50727"
if (Test-Path $net2xPath) {
Set-ItemProperty -Path $net2xPath -Name "SystemDefaultTlsVersions" -Value 1 -Type DWord
Set-ItemProperty -Path $net2xPath -Name "SchUseStrongCrypto" -Value 1 -Type DWord
}
Write-Host ".NET Framework TLS ayarlari guncellendi." -ForegroundColor Green
Write-Host "Uygulamalarin yeniden baslatilmasi gerekiyor." -ForegroundColor Yellow
SchUseStrongCrypto: Güçlü kriptografi algoritmalarını zorunlu kılar ve zayıf cipher’ları devre dışı bırakır. SystemDefaultTlsVersions: .NET’in sistem varsayılan TLS sürümünü kullanmasını sağlar, sabit kodlanmış TLS 1.0 davranışını geçersiz kılar.
Yapılandırmayı Doğrulama
Değişiklikleri yaptıktan ve sunucuyu yeniden başlattıktan sonra her şeyin beklendiği gibi çalıştığını doğrulamanız şart. Birkaç farklı yöntem kullanabilirsiniz:
# Değişikliklerin geçerli olup olmadığını kontrol et
# Test-NetConnection ile temel kontrol
Test-NetConnection -ComputerName localhost -Port 443
# PowerShell ile TLS versiyonu test et
Add-Type @"
using System.Net;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
"@
function Test-TLSVersion {
param (
[string]$Hostname,
[int]$Port = 443,
[System.Security.Authentication.SslProtocols]$Protocol
)
try {
$tcpClient = New-Object System.Net.Sockets.TcpClient($Hostname, $Port)
$sslStream = New-Object System.Net.Security.SslStream($tcpClient.GetStream(), $false, {$true})
$sslStream.AuthenticateAsClient($Hostname, $null, $Protocol, $false)
Write-Host "$Protocol : AKTIF (TEHLIKELI OLABILIR)" -ForegroundColor Red
$sslStream.Close()
$tcpClient.Close()
return $true
} catch {
Write-Host "$Protocol : DEVRE DISI (GUVENLI)" -ForegroundColor Green
return $false
}
}
# Kapatilmis olmasi gereken protokolleri test et
Test-TLSVersion -Hostname "localhost" -Protocol ([System.Security.Authentication.SslProtocols]::Tls)
Test-TLSVersion -Hostname "localhost" -Protocol ([System.Security.Authentication.SslProtocols]::Tls11)
Test-TLSVersion -Hostname "localhost" -Protocol ([System.Security.Authentication.SslProtocols]::Tls12)
Dış kaynaklı test için SSL Labs (ssllabs.com/ssltest) kullanabilirsiniz. İnternet’e açık sunucular için en güvenilir test ortamlarından biri. A veya A+ not almak hedef olmalı.
Gerçek Dünya Senaryoları ve Dikkat Edilecekler
Exchange Server kullananlar için: Exchange 2013 ve 2016, TLS 1.0’a bağımlı eski bileşenler içerebilir. TLS 1.0’ı kapatmadan önce tüm Exchange CU güncellemelerinin yapıldığından ve ortamınızın desteği olduğundan emin olun. Exchange 2019 bu konuda çok daha iyidir.
Active Directory ve LDAPS: Domain Controller’larda TLS yapılandırması yaparken dikkatli olun. LDAPS (636) üzerinden bağlanan uygulamalar olabilir. Değişiklik öncesi bağımlılıkları haritalayın.
SQL Server ile şifreli bağlantılar: SQL Server da Schannel kullanır. TLS yapılandırmasını değiştirdiğinizde SQL Server bağlantılarını test etmeyi unutmayın. Özellikle eski ODBC sürücüleri sorun çıkarabilir.
Eski uygulamalar: Bazı üçüncü parti uygulamalar hâlâ TLS 1.0 veya hatta SSL 3.0 kullanıyor olabilir. Bu uygulamaları tespit etmek için Wireshark veya Network Monitor ile bağlantı trafiğini izleyebilirsiniz. Mümkünse bu uygulamaları güncelleyin, güncelleme mümkün değilse üretici ile iletişime geçin.
Pilot test: Üretim ortamına geçmeden önce test ortamında her şeyi deneyin. Özellikle çok bileşenli yapılarda (web uygulaması, veritabanı, harici servisler) zincirin her halkasını test edin.
Sonuç
Windows Server’da SSL/TLS yapılandırması, bir kez yapıp unutulacak bir iş değil. Yeni güvenlik açıkları keşfildikçe, yeni protokol sürümleri geldikçe ve uyumluluk gereksinimleriniz değiştikçe bu ayarları gözden geçirmeniz gerekiyor. En azından yılda bir kez SSL Labs veya benzeri bir araçla sunucularınızı test edin.
Özetlemek gerekirse; SSL 2.0, SSL 3.0, TLS 1.0 ve TLS 1.1 kapatılmalı, TLS 1.2 minimum standart olmalı, TLS 1.3 ise mümkün olan her yerde etkinleştirilmeli. Cipher suite listesi güçlü algoritmalar lehine yeniden sıralanmalı, .NET Framework ayarları güncellenmeli ve tüm bu değişiklikler merkezi bir yönetim aracıyla dağıtılmalı.
Bu adımları takip etmek, sunucularınızı bilinen protokol saldırılarına karşı önemli ölçüde koruyacak ve uyumluluk denetimlerinde başınızı ağrıtacak bulgulardan sizi kurtaracaktır. Herhangi bir adımda sorunla karşılaşırsanız veya ortama özel sorularınız varsa yorum bırakmaktan çekinmeyin.