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.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir