IIS URL Rewrite Modülü Kurulumu ve Kural Yazımı

Üretim ortamında IIS yönetiyorsanız, er ya da geç URL Rewrite modülüyle yüz yüze gelirsiniz. Bir müşterinin eski CMS’inden yeni sisteme geçiş yaparken tüm SEO değerini korumak, HTTP’den HTTPS’e zorlamak ya da çirkin query string’leri temiz URL’lere çevirmek… Bunların hepsi URL Rewrite olmadan yapılamaz. Bu yazıda hem kurulumu hem de gerçek dünyada işe yarayan kural yazımını ele alacağız.

URL Rewrite Modülü Nedir ve Neden Gereklidir

IIS, varsayılan kurulumda URL yönlendirme konusunda oldukça kısıtlıdır. Microsoft’un bu boşluğu doldurmak için geliştirdiği URL Rewrite modülü, Apache’nin mod_rewrite modülüne benzer işlevsellik sunar. Ancak IIS’in grafik arayüzü sayesinde kural yönetimi çok daha görsel bir hal alabilir; tabii asıl güç yine XML tabanlı web.config dosyasında gizlidir.

Modülün temel kullanım alanları şunlardır:

  • SEO dostu URL’ler: /urun.aspx?id=45 yerine /urun/ahsap-masa gibi temiz adresler
  • HTTPS yönlendirmesi: HTTP gelen her isteği HTTPS’e zorlamak
  • www/non-www standardizasyonu: www.domain.com ile domain.com arasında tutarlılık sağlamak
  • Geriye dönük uyumluluk: Site taşıma sonrası eski URL’leri yeni yapıya yönlendirmek
  • Canonical URL yönetimi: Duplicate content sorunlarını engellemek
  • Erişim kontrolü: Belirli IP aralıklarını veya user-agent’ları filtrelemek

Kurulum Adımları

Web Platform Installer ile Kurulum

En temiz yol, Microsoft Web Platform Installer üzerinden gitmektir. Ancak güncel Windows Server sürümlerinde Web PI’ı bulmak giderek zorlaştığı için doğrudan MSI kurulumuna geçmek daha pratik.

Microsoft’un resmi indirme sayfasından rewrite_amd64_en-US.msi dosyasını indirin. 64-bit sistem kullanıyorsanız mutlaka amd64 versiyonunu tercih edin. Sunucu ortamında indirme işlemini PowerShell ile yapmak daha kontrollü bir yaklaşım:

# PowerShell ile URL Rewrite MSI indir
$url = "https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_en-US.msi"
$output = "C:Temprewrite_amd64.msi"
Invoke-WebRequest -Uri $url -OutFile $output

# Sessiz kurulum
Start-Process msiexec.exe -ArgumentList "/i C:Temprewrite_amd64.msi /quiet /norestart" -Wait

Kurulum sonrası IIS Manager’ı yeniden başlatmanıza gerek yoktur, doğrudan yansıyacaktır. Modülün başarıyla kurulduğunu doğrulamak için:

# Modül varlığını kontrol et
Get-WebGlobalModule -Name "RewriteModule"

# Ya da IIS modül listesinden kontrol
appcmd list module /name:RewriteModule

Offline Ortamlarda Kurulum

İnternet erişimi olmayan üretim sunucularında modülü başka bir makinede indirip kopyalamanız gerekir. Bu senaryo oldukça yaygın, özellikle güvenlik politikası sıkı olan kurumlarda. MSI dosyasını USB veya ağ paylaşımı üzerinden alıp aynı msiexec komutunu çalıştırabilirsiniz.

Kurulum başarılı olduktan sonra %windir%System32inetsrvrewrite.dll dosyasının var olduğunu görmelisiniz. Bu dosya yoksa kurulum tamamlanmamış demektir.

web.config Dosyasının Anatomisi

URL Rewrite kuralları web.config dosyasının bölümü içindeki elementine yazılır. Temel yapı şu şekildedir:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <!-- Kurallarınız buraya gelecek -->
      </rules>
      <outboundRules>
        <!-- Giden yanıtlar için kurallar -->
      </outboundRules>
    </rewrite>
  </system.webServer>
</configuration>

Kuralların işlenme sırası önemlidir. IIS kuralları yukarıdan aşağıya doğru işler. Bir kural eşleşirse ve stopProcessing="true" işaretliyse sonraki kurallara bakılmaz. Bu yüzden genel kuralları altta, spesifik olanları üstte tutmak iyi bir pratiktir.

Temel Kural Tipleri

Redirect vs Rewrite Farkı

Bu ayrımı anlamak kritik. Rewrite (yeniden yazma) isteği sunucu tarafında farklı bir kaynağa yönlendirir, tarayıcı URL değişikliğinin farkında olmaz. Redirect ise tarayıcıya yeni bir adrese git demektir, URL bar’da değişiklik görülür ve HTTP durum kodu döner (301, 302, vb.).

SEO açısından 301 kalıcı yönlendirme kullanmak şarttır. 302 geçici yönlendirmeyi yanlışlıkla 301 yerine kullanmak, link juice’un aktarılmamasına neden olur. Bunu acı deneyimle öğrenen site sahipleriyle çok karşılaştım.

HTTP’den HTTPS’e Yönlendirme

Günümüzde her site HTTPS kullanmak zorunda. Şöyle bir kural yazabilirsiniz:

<rule name="HTTP to HTTPS Redirect" stopProcessing="true">
  <match url="(.*)" />
  <conditions>
    <add input="{HTTPS}" pattern="^OFF$" />
  </conditions>
  <action type="Redirect" 
          url="https://{HTTP_HOST}/{R:1}" 
          redirectType="Permanent" />
</rule>

Buradaki {HTTPS} sunucu değişkenidir, OFF değeri taşıyorsa istek HTTP üzerinden geliyor demektir. {HTTP_HOST} domain adını tutar, {R:1} ise eşleşen URL’nin ilk grubunu (yani tüm path’i) temsil eder.

Load balancer veya reverse proxy arkasında çalışan IIS sunucularında dikkat etmeniz gereken bir nokta var: Bazı proxy yapılandırmalarında {HTTPS} değişkeni doğru çalışmaz. Bu durumda X-Forwarded-Proto başlığını kullanmanız gerekir:

<rule name="HTTPS behind Load Balancer" stopProcessing="true">
  <match url="(.*)" />
  <conditions logicalGrouping="MatchAll">
    <add input="{HTTP_X_FORWARDED_PROTO}" pattern="^http$" />
  </conditions>
  <action type="Redirect" 
          url="https://{HTTP_HOST}/{R:1}" 
          redirectType="Permanent" />
</rule>

www ve Non-www Standardizasyonu

Google, www.domain.com ile domain.com‘u farklı siteler olarak görür. Canonical tag’ler kısmen çözüm olsa da sunucu tarafında yönlendirme en kesin yoldur:

<!-- www'suz versiyona yönlendirme -->
<rule name="Remove WWW" stopProcessing="true">
  <match url="(.*)" />
  <conditions>
    <add input="{HTTP_HOST}" pattern="^www.(.+)$" />
  </conditions>
  <action type="Redirect" 
          url="https://{C:1}/{R:1}" 
          redirectType="Permanent" />
</rule>

Burada {C:1} koşul grubundaki ilk yakalama grubunu temsil eder. ^www.(.+)$ regex’inde (.+) kısmı domain.com bölümünü yakalar.

Gerçek Dünya Senaryoları

Eski CMS’ten Yeni Sisteme Geçiş

En zorlu senaryo budur. Diyelim ki WordPress’ten özel bir .NET uygulamasına geçiyorsunuz. Eski URL yapısı /category/post-name/ şeklindeyken yeni yapı /blog/post-name/ oldu. Yüzlerce URL için tek tek kural yazmak yerine pattern matching kullanın:

<rule name="WordPress to DotNet Blog Migration" stopProcessing="true">
  <match url="^category/([a-z0-9-]+)/([a-z0-9-]+)/$" />
  <conditions>
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
  </conditions>
  <action type="Redirect" 
          url="/blog/{R:2}" 
          redirectType="Permanent" />
</rule>

IsFile ve IsDirectory koşulları, gerçekten var olan dosya veya klasörlere kural uygulanmamasını sağlar. Bu olmadan CSS, JS, resim gibi statik dosyalar da kurala takılır.

Query String’den Temiz URL’e

E-ticaret sitelerinde sıkça görülen durum:

<rule name="Product Clean URL" stopProcessing="true">
  <match url="^urun/([a-z0-9-]+)$" />
  <conditions>
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
  </conditions>
  <action type="Rewrite" url="/urun.aspx?slug={R:1}" />
</rule>

Bu kural /urun/ahsap-masa gibi bir isteği sunucu tarafında /urun.aspx?slug=ahsap-masa‘ya yönlendirir. Tarayıcı temiz URL’yi görmeye devam eder.

Tersine, eski query string tabanlı URL’leri yeni temiz URL’lere yönlendirmek için:

<rule name="Old Query String to Clean URL" stopProcessing="true">
  <match url="^urun.aspx$" />
  <conditions>
    <add input="{QUERY_STRING}" pattern="id=([0-9]+)" />
  </conditions>
  <action type="Redirect" 
          url="/urun/{C:1}" 
          redirectType="Permanent" 
          appendQueryString="false" />
</rule>

appendQueryString="false" olmazsa query string yeni URL’e de eklenir, istemediğimiz bir durum.

IP Tabanlı Erişim Kontrolü

Bakım moduna alınan bir siteye sadece ofis IP’sinden erişim izni vermek:

<rule name="Maintenance Mode" stopProcessing="true">
  <match url="(.*)" />
  <conditions logicalGrouping="MatchAll">
    <add input="{REMOTE_ADDR}" pattern="^192.168.1." negate="true" />
    <add input="{REQUEST_URI}" pattern="^/bakim.html$" negate="true" />
  </conditions>
  <action type="Redirect" url="/bakim.html" redirectType="Temporary" />
</rule>

Dikkat: Bakım sayfasının kendisini de kurala dahil ederseniz sonsuz döngüye girersiniz. negate="true" ile bakım sayfasını kural dışı bırakıyoruz.

Trailing Slash Yönetimi

URL sonundaki / karakteri SEO açısından tutarsızlık yaratır. Hepsini standartlaştırmak için:

<rule name="Add Trailing Slash" stopProcessing="true">
  <match url="(.*[^/])$" />
  <conditions>
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    <add input="{REQUEST_URI}" pattern="^.+.[a-zA-Z]{2,4}$" negate="true" />
  </conditions>
  <action type="Redirect" 
          url="{R:1}/" 
          redirectType="Permanent" />
</rule>

Son koşul .html, .aspx, .php gibi uzantılı dosyalara trailing slash eklenmesini önler.

Outbound Rules: Yanıt İçeriğini Değiştirmek

Gelen isteklerin yanı sıra sunucu yanıtlarını da değiştirebilirsiniz. Örneğin response header’larına müdahale etmek ya da HTML içindeki URL’leri düzenlemek bu yolla mümkündür. Bir reverse proxy senaryosunda backend URL’lerini gizlemek için kullanılır.

<outboundRules>
  <rule name="Remove Server Header">
    <match serverVariable="RESPONSE_SERVER" pattern=".*" />
    <action type="Rewrite" value="" />
  </rule>
  <rule name="Add Security Headers">
    <match serverVariable="RESPONSE_X_Frame_Options" pattern=".*" />
    <action type="Rewrite" value="SAMEORIGIN" />
  </rule>
</outboundRules>

Güvenlik açısından Server header’ını gizlemek, sunucu hakkında bilgi sızdırmayı engeller. Bu küçük ama etkili bir güvenlik önlemidir.

Sık Yapılan Hatalar ve Çözümleri

Yıllardır IIS ile çalışırken gördüğüm en yaygın hataları şöyle sıralayabilirim:

  • Sonsuz yönlendirme döngüsü: Kural kendine de uygulandığında oluşur. stopProcessing="true" ve negatif koşullar bunu önler.
  • Regex hataları: IIS’in regex motoru .NET tabanlıdır, bazı özel karakterler farklı davranabilir. Kuralı yazmadan önce [regex101.com](https://regex101.com) gibi araçlarla test edin.
  • Büyük/küçük harf duyarlılığı: Windows dosya sistemi büyük/küçük harf duyarsızdır ama regex’leriniz öyle olmayabilir. Pattern’lara ignoreCase="true" eklemek güvenli bir yaklaşımdır.
  • Modül kurulu değil hatası: web.config kuralları varken modül yoksa site 500 hataları verebilir. Deployment sürecinizde modül varlığını kontrol etmeyi unutmayın.
  • Application Pool kimlik sorunu: Rewrite kuralları bazen App Pool kimliğinin erişemediği sunucu değişkenlerine başvurabilir. Bu durumda allowUnlisted="true" ayarını serverVariables bölümüne eklemeniz gerekir.

Kural Test Etme ve Debug

IIS Manager içindeki “Test Pattern” aracı temel testler için yeterlidir. Ancak üretim ortamına geçmeden önce daha kapsamlı bir test yapmak isterseniz:

# IIS loglarını gerçek zamanlı takip et
Get-Content "C:inetpublogsLogFilesW3SVC1u_ex$(Get-Date -Format 'yyMMdd').log" -Wait -Tail 20

# Failed Request Tracing'i etkinleştir
appcmd configure trace /site.name:"Default Web Site" /path:/ /enable:true

# URL Rewrite trace kuralı ekle
appcmd set config -section:system.webServer/tracing/traceFailedRequests /+[path='*']

Failed Request Tracing (FREB) URL Rewrite sorunlarını debug etmek için altın değerindedir. Hangi kuralın eşleştiğini, hangi koşulun geçildiğini adım adım görebilirsiniz. Özellikle karmaşık kural setlerinde bu araç olmadan debug yapmak çok zordur.

Performans Üzerine Bir Not

URL Rewrite modülü her istek için çalışır. Onlarca karmaşık regex kuralınız varsa bu bir performans maliyeti doğurur. Kural sıralamasını optimize edin: en sık eşleşen kuralları üste alın. Statik dosyalara (resim, CSS, JS) kural uygulanmasını genel bir koşulla engelleyin:

<conditions>
  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>

Bu tek koşul, statik dosyalar için diğer tüm koşulların değerlendirilmesini atlar ve performans üzerinde belirgin bir fark yaratır. Yüksek trafikli sitelerde bu optimizasyon küçük ama birikimli bir katkı sağlar.

Sonuç

URL Rewrite modülü, IIS’i gerçek anlamda üretim kaliteli bir web sunucusuna dönüştüren kritik bir bileşendir. Temel HTTP/HTTPS yönlendirmesinden karmaşık site migrasyonlarına kadar geniş bir kullanım yelpazesi sunar. Ancak yanlış yazılmış bir kural hem site erişilebilirliğini hem de SEO sıralamanızı ciddi biçimde etkileyebilir.

Her zaman şu sırayı izleyin: önce test ortamında deneyin, FREB ile doğrulayın, ardından üretime alın. Kurallarınızı web.config üzerinden yönetin ve bu dosyayı mutlaka versiyon kontrolüne (Git vb.) dahil edin. Bir sonraki sistemci geldiğinde ne yaptığınızı anlayabilsin diye kural adlarını anlamlı tutun.

IIS’in gücünü küçümsemeyin. Doğru yapılandırılmış bir IIS + URL Rewrite kombinasyonu, birçok modern web sunucusuyla rahatlıkla yarışabilir.

Bir yanıt yazın

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