IIS FTP Sunucusu Kurulumu ve Güvenli Yapılandırma
Yıllar içinde onlarca Windows Server ortamında FTP kurulumu yaptım. Hepsinde aynı sorunlar çıktı: ya pasif mod yanlış yapılandırıldı, ya SSL sertifikası eklenmedi, ya da firewall kuralları eksik bırakıldı. Bu yazıda sıfırdan başlayıp production’a hazır bir IIS FTP sunucusu kuracağız. Hem temel kurulum adımlarını hem de gerçek hayatta karşılaşılan sorunların çözümlerini ele alacağız.
Neden IIS FTP?
Linux tarafında vsftpd veya ProFTPD gibi güçlü alternatifler varken Windows ortamında neden IIS FTP kullanmalısınız? Cevap basit: Active Directory entegrasyonu, Windows kimlik doğrulaması ve merkezi yönetim. Eğer ortamınız zaten Windows Server tabanlıysa, IIS FTP bu ekosisteme doğal olarak entegre olur. Ayrıca PowerShell ile tam otomasyon desteği sunar.
Ancak şunu da belirteyim: IIS FTP, güvenli kullanılmadığında ciddi bir saldırı yüzeyi oluşturur. Bu yazıda güvenliği es geçmeyeceğiz.
Ön Gereksinimler
Başlamadan önce şunların hazır olması gerekiyor:
- Windows Server 2016/2019/2022 (bu örneklerde 2022 kullanıyoruz)
- Yönetici yetkisine sahip bir hesap
- Sunucuya atanmış statik IP adresi
- İsteğe bağlı ama önerilir: SSL sertifikası (self-signed veya CA’dan alınmış)
PowerShell ile Windows sürümünü doğrulamak isterseniz:
Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer
IIS ve FTP Rolünün Kurulumu
Server Manager ile Kurulum
Server Manager üzerinden gitmek isteyenler için klasik yol hala geçerli. Ancak ben PowerShell tercih ediyorum, çünkü hem daha hızlı hem de tekrarlanabilir. Birden fazla sunucuya aynı konfigürasyonu uygulamanız gerektiğinde script’iniz hazır olur.
PowerShell ile IIS ve FTP servisini kurmak için:
Install-WindowsFeature -Name Web-Server, Web-Ftp-Server, Web-Ftp-Service, Web-Ftp-Extensibility -IncludeManagementTools -Verbose
Kurulum tamamlandıktan sonra IIS Manager’ın yüklendiğini doğrulayın:
Get-WindowsFeature | Where-Object {$_.Name -like "*FTP*" -or $_.Name -like "*Web-Server*"} | Select-Object Name, InstallState
Çıktıda InstallState değerinin Installed olduğunu görmelisiniz. Görmüyorsanız sunucuyu yeniden başlatmayı deneyin, bazı durumlarda reboot zorunlu oluyor.
FTP Sitesi Oluşturma
IIS Manager’ı açın (inetmgr komutunu çalıştırabilirsiniz). Sol panelde sunucu adına sağ tıklayın ve “Add FTP Site” seçeneğini seçin.
Ancak yine PowerShell ile yapalım. Önce FTP için kök dizini oluşturalım:
New-Item -ItemType Directory -Path "C:FTPRoot" -Force
New-Item -ItemType Directory -Path "C:FTPRootuploads" -Force
New-Item -ItemType Directory -Path "C:FTPRootshared" -Force
# NTFS izinlerini ayarlayın
$acl = Get-Acl "C:FTPRoot"
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("IIS_IUSRS", "ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow")
$acl.SetAccessRule($rule)
Set-Acl "C:FTPRoot" $acl
Şimdi FTP sitesini oluşturalım:
Import-Module WebAdministration
New-WebFtpSite -Name "MainFTP" -Port 21 -PhysicalPath "C:FTPRoot" -Force
# Siteyi başlatın
Start-WebSite -Name "MainFTP"
SSL/TLS Yapılandırması
Bu kısmı atlamayın. Plain-text FTP kullanan bir ortam, ağdaki herhangi birinin kullanıcı adı ve şifreleri görmesi anlamına gelir. Production ortamında kesinlikle SSL kullanmalısınız.
Self-Signed Sertifika Oluşturma
Eğer henüz bir sertifikanız yoksa, test veya iç ağ kullanımı için self-signed sertifika oluşturabilirsiniz:
$cert = New-SelfSignedCertificate `
-DnsName "ftp.sirketiniz.com" `
-CertStoreLocation "cert:LocalMachineMy" `
-FriendlyName "FTP SSL Sertifikasi" `
-NotAfter (Get-Date).AddYears(2)
$cert.Thumbprint
Thumbprint değerini bir kenara not alın, bir sonraki adımda kullanacağız.
FTP SSL Yapılandırması
IIS Manager üzerinden FTP sitesini seçin, “FTP SSL Settings”e çift tıklayın. Ancak PowerShell ile yapmak çok daha temiz:
$siteName = "MainFTP"
$thumbprint = "BURAYA_THUMBPRINT_DEGERI_GELECEK"
# SSL politikasını ayarla
Set-ItemProperty "IIS:Sites$siteName" -Name ftpServer.security.ssl.serverCertHash -Value $thumbprint
Set-ItemProperty "IIS:Sites$siteName" -Name ftpServer.security.ssl.controlChannelPolicy -Value "SslRequire"
Set-ItemProperty "IIS:Sites$siteName" -Name ftpServer.security.ssl.dataChannelPolicy -Value "SslRequire"
# Servisin yeniden başlatılması gerekebilir
Restart-Service ftpsvc
SslRequire yerine SslAllow kullanırsanız SSL olmayan bağlantılara da izin vermiş olursunuz. Üretim ortamında her zaman SslRequire kullanın.
Kimlik Doğrulama Yapılandırması
IIS FTP üç farklı kimlik doğrulama yöntemi sunar:
- Anonymous Authentication: Herkese açık dosya paylaşımı için. Güvenlik riski yüksek, dikkatli kullanın.
- Basic Authentication: Kullanıcı adı ve şifre ile. SSL ile birlikte kullanılmalı.
- Client Certificate Authentication: En güvenli yöntem. Sertifika tabanlı kimlik doğrulama.
Basic Authentication Yapılandırması
# Basic Authentication'ı etkinleştir
Set-ItemProperty "IIS:SitesMainFTP" -Name ftpServer.security.authentication.basicAuthentication.enabled -Value $true
# Anonymous Authentication'ı devre dışı bırak
Set-ItemProperty "IIS:SitesMainFTP" -Name ftpServer.security.authentication.anonymousAuthentication.enabled -Value $false
FTP Kullanıcı Yetkilendirmesi
Kullanıcıların hangi dizinlere erişebileceğini belirlemek için yetkilendirme kuralları eklemeniz gerekiyor:
# Belirli bir kullanıcıya okuma ve yazma yetkisi ver
Add-WebConfiguration -Filter "/system.ftpServer/security/authorization" `
-Value @{
accessType = "Allow"
users = "ftpkullanici"
roles = ""
permissions = "Read,Write"
} `
-PSPath "IIS:SitesMainFTP"
Pasif Mod Yapılandırması
En çok sorun çıkaran konu bu. Firewall arkasındaki istemcilerle çalışıyorsanız pasif mod zorunlu. Pasif modda sunucu, veri bağlantıları için kullanılacak port aralığını istemciye bildiriyor ve bu portların firewall’da açık olması gerekiyor.
# Pasif port aralığını ayarla (örnek: 49152-65535)
$ftpConfig = @"
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.ftpServer>
<firewallSupport>
<add key="passivePortRange" value="49152-65535" />
</firewallSupport>
</system.ftpServer>
</configuration>
"@
# PowerShell ile pasif port aralığını yapılandır
Set-WebConfiguration -Filter "/system.applicationHost/sites/site[@name='MainFTP']/ftpServer/firewallSupport" `
-Value @{
pasvMaxPort = 65535
pasvMinPort = 49152
externalIp4Address = "SUNUCUNUZUN_DISIP_ADRESI"
} `
-PSPath "IIS:"
Dış IP adresini doğru girmeniz kritik. NAT arkasındaysanız firewall’ın dış IP adresini buraya yazın, sunucunun iç IP adresini değil.
Windows Firewall Kuralları
# FTP kontrol portu (21)
New-NetFirewallRule -DisplayName "FTP Server Port 21" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 21 `
-Action Allow `
-Profile Any
# FTP pasif mod port aralığı
New-NetFirewallRule -DisplayName "FTP Pasif Mod Port Araligi" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 49152-65535 `
-Action Allow `
-Profile Any
# FTP servisi için özel kural
New-NetFirewallRule -DisplayName "FTP Servisi" `
-Direction Inbound `
-Program "C:WindowsSystem32svchost.exe" `
-Action Allow `
-Profile Any
Pasif mod port aralığını daraltmak isterseniz 49152-49252 gibi daha küçük bir aralık kullanabilirsiniz. Her port bir potansiyel bağlantı anlamına gelir, gereksiz yere geniş tutmayın.
Kullanıcı İzolasyonu
Bu özellik birden fazla kullanıcının aynı FTP sunucusunu paylaştığı senaryolarda kritik öneme sahip. Kullanıcı izolasyonu sayesinde her kullanıcı sadece kendi dizinini görür, diğer kullanıcıların dosyalarına erişemez.
IIS Manager’da FTP sitesini seçin, “FTP User Isolation”a tıklayın. Üç seçenek var:
- Do not isolate users: Tüm kullanıcılar aynı kök dizini görür. Güvenlik açısından zayıf.
- Isolate users: Her kullanıcı kendi home dizinine hapsolur. En yaygın kullanılan seçenek.
- Isolate users using Active Directory: AD ile entegre ortamlarda ideal çözüm.
PowerShell ile yapılandırmak için:
# Kullanıcı izolasyonunu etkinleştir
Set-ItemProperty "IIS:SitesMainFTP" `
-Name ftpServer.userIsolation.mode `
-Value "IsolateAllDirectories"
# Her kullanıcı için dizin oluştur (örnek)
$users = @("ahmet", "mehmet", "ayse")
foreach ($user in $users) {
$userPath = "C:FTPRootLocalUser$user"
New-Item -ItemType Directory -Path $userPath -Force
# NTFS izinlerini ayarla
$acl = Get-Acl $userPath
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
$user,
"FullControl",
"ContainerInherit,ObjectInherit",
"None",
"Allow"
)
$acl.SetAccessRule($rule)
Set-Acl $userPath $acl
}
Kullanıcı izolasyonu açık olduğunda dizin yapısı önemli. C:FTPRootLocalUserkullaniciadı formatına uymalısınız.
FTP Günlük Kaydı
Güvenlik olaylarını takip etmek ve sorun gidermek için log yapılandırması ihmal edilmemeli:
# Log dizinini ayarla
Set-ItemProperty "IIS:SitesMainFTP" `
-Name ftpServer.logFile.directory `
-Value "C:inetpublogsFTP"
# Log formatını W3C olarak ayarla
Set-ItemProperty "IIS:SitesMainFTP" `
-Name ftpServer.logFile.logFormat `
-Value "W3C"
# Loglanacak alanları belirle
Set-ItemProperty "IIS:SitesMainFTP" `
-Name ftpServer.logFile.logExtFileFlags `
-Value "Date,Time,ClientIP,UserName,ServerIP,Method,UriStem,FtpStatus,Win32Status,BytesSent,BytesRecv,TimeTaken"
Log dosyaları C:inetpublogsFTP dizininde günlük olarak oluşturulur. Disk dolmasını önlemek için log rotasyonu ve eski logların otomatik silinmesi için bir görev planlamayı unutmayın.
IP Adresi ve Domain Kısıtlamaları
Sadece belirli IP adreslerinden veya aralıklardan bağlantıya izin vermek güvenliği ciddi ölçüde artırır. Özellikle bilinen partner firmaların IP’leri varsa bu özelliği mutlaka kullanın:
# Varsayılan olarak tüm bağlantıları reddet
Add-WebConfiguration -Filter "/system.ftpServer/security/ipSecurity" `
-Value @{
allowUnlisted = $false
} `
-PSPath "IIS:SitesMainFTP"
# Belirli IP adresine izin ver
Add-WebConfiguration -Filter "/system.ftpServer/security/ipSecurity" `
-Value @{
ipAddress = "192.168.1.100"
allowed = $true
} `
-PSPath "IIS:SitesMainFTP"
# Bir subnet'e izin ver
Add-WebConfiguration -Filter "/system.ftpServer/security/ipSecurity" `
-Value @{
ipAddress = "10.0.0.0"
subnetMask = "255.255.0.0"
allowed = $true
} `
-PSPath "IIS:SitesMainFTP"
Bağlantı Limitleri ve Performans Ayarları
Brute force saldırılarına karşı bağlantı limitlerini yapılandırın:
# Maksimum eşzamanlı bağlantı sayısını sınırla
Set-ItemProperty "IIS:SitesMainFTP" `
-Name ftpServer.connections.maxConnections `
-Value 100
# Bağlantı zaman aşımını ayarla (saniye cinsinden)
Set-ItemProperty "IIS:SitesMainFTP" `
-Name ftpServer.connections.timeout `
-Value 120
# Maksimum band genişliği (bytes/saniye, 0 = sınırsız)
Set-ItemProperty "IIS:SitesMainFTP" `
-Name ftpServer.connections.maxBandwidth `
-Value 0
Yaygın Sorunlar ve Çözümleri
Pasif mod bağlantıları çalışmıyor: Firewall kurallarını kontrol edin. Dış IP adresinin doğru girildiğinden emin olun. NAT cihazında port yönlendirmesini (port forwarding) pasif mod port aralığı için yapılandırın.
530 – Giriş yapılamıyor hatası: Kullanıcı izolasyonu açıksa dizin yapısının LocalUserkullaniciadı formatında olduğunu kontrol edin. NTFS izinlerini gözden geçirin.
SSL bağlantısı kurulamıyor: Sertifikanın LocalMachineMy store’unda olduğunu doğrulayın. Thumbprint değerinin doğru girildiğini kontrol edin.
550 – Dosya bulunamadı hatası: NTFS izinleri yetersiz olabilir. IIS_IUSRS grubunun hedef dizine okuma yetkisi olduğundan emin olun.
Bağlantı sorunlarını debug etmek için FTP log dosyalarını inceleyin:
# Son 50 satır log kaydını görüntüle
Get-Content "C:inetpublogsFTPu_ex*.log" | Select-Object -Last 50
# Belirli bir kullanıcının loglarını filtrele
Get-Content "C:inetpublogsFTPu_ex*.log" | Where-Object {$_ -like "*kullaniciadı*"}
FTP Servis Durumu İzleme
Basit bir monitoring scripti işinize yarayabilir:
$ftpStatus = Get-Service -Name "ftpsvc"
$ftpSite = Get-WebSite -Name "MainFTP"
Write-Host "FTP Servis Durumu: $($ftpStatus.Status)"
Write-Host "FTP Site Durumu: $($ftpSite.State)"
if ($ftpStatus.Status -ne "Running") {
Write-Warning "FTP servisi calismıyor! Baslatiliyor..."
Start-Service -Name "ftpsvc"
Send-MailMessage -To "[email protected]" `
-From "[email protected]" `
-Subject "FTP Servisi Uyarisi" `
-Body "FTP servisi durdurulmus durumda ve yeniden baslatildi." `
-SmtpServer "mail.sirket.com"
}
Bu scripti Task Scheduler’a ekleyerek her 5 dakikada bir çalıştırabilirsiniz.
Sonuç
IIS FTP kurulumu teknik olarak karmaşık değil, ama doğru yapılandırılmazsa ciddi güvenlik açıkları bırakıyor. Bu yazıda anlattıklarımı özetleyecek olursam: SSL’i kesinlikle etkinleştirin, kullanıcı izolasyonunu açın, pasif mod port aralığını minimize tutun, IP kısıtlamalarını uygulayın ve logları düzenli inceleyin.
SFTP veya FTPS mi? Eğer yeni bir sistem kuruyorsanız ve seçim şansınız varsa SFTP’yi değerlendirin. Windows’ta OpenSSH Server ile SFTP hizmeti vermek artık çok daha kolay ve güvenlik açısından daha sağlam. Ama legacy sistemlerle uyumluluk gerektiren veya mevcut FTP altyapısını IIS üzerinde standardize etmek isteyen ortamlar için bu yazıda anlattıklarımız sizi iyi bir noktaya taşıyacaktır.
Üretim ortamına almadan önce bir checklist yapmanızı öneririm: SSL aktif mi, anonymous auth kapalı mı, kullanıcı izolasyonu açık mı, firewall kuralları doğru mu, log rotasyonu ayarlandı mı? Bu beş soruya evet diyebiliyorsanız devreye almaya hazırsınız.
