WordPress .htaccess: Performans, Güvenlik ve SEO için Eksiksiz Teknik Rehber
.htaccess (Hypertext Access) dosyası, web sunucusuna WordPress sitenize gelen istekleri nasıl işleyeceğini söyleyen dizin düzeyinde bir Apache yapılandırma dosyasıdır — global httpd.conf üzerinde değişiklik yapılmasını gerektirmez. .htaccess dosyasına yerleştirdiğiniz her direktif, bulunduğu dizine ve altındaki tüm alt dizinlere yinelemeli olarak uygulanır; bu da kök düzeyindeki dosyayı, sunucunun dışında bir WordPress yöneticisinin kullanabileceği en güçlü araç haline getirir.
WordPress için özellikle .htaccess, güzel kalıcı bağlantıların motoru, kötü amaçlı trafiğe karşı ilk savunma hattı ve bir eklentiye dokunmadan sıkıştırma ile tarayıcı önbelleğe alma yoluyla doğrudan bir performans çarpanıdır.
WordPress .htaccess Dosyası Gerçekte Ne Yapar?
Apache, .htaccess dosyasını her HTTP isteğinde işler. Bu, yazdığınız her direktifin gecikme, güvenlik durumu ve tarama davranışı üzerinde ölçülebilir bir etkisi olduğu anlamına gelir. WordPress, bir kalıcı bağlantı yapısı kaydettiğinizde .htaccess dosyasına otomatik olarak minimal bir yeniden yazma bloğu ekler; ancak bu blok yalnızca bir başlangıç noktasıdır. Dosya şunları işleyebilir:
mod_rewrite aracılığıyla URL yeniden yazma ve yönlendirmeler
mod_authz_host ve mod_access_compat aracılığıyla Erişim kontrolü
mod_headers aracılığıyla HTTP yanıt başlığı ekleme
mod_deflate aracılığıyla Çıktı sıkıştırma
mod_expires aracılığıyla Tarayıcı önbellek kontrolü
mod_auth_basic aracılığıyla Kimlik doğrulama kapıları
ErrorDocument direktifi aracılığıyla Özel hata belgeleri
Her direktifi hangi Apache modülünün desteklediğini anlamak kritik öneme sahiptir — modül sunucunuzda yüklü değilse direktif sessizce başarısız olur veya 500 hatası verir. Gelişmiş kuralları dağıtmadan önce her zaman modül kullanılabilirliğini barındırma sağlayıcınızla doğrulayın.
.htaccess Dosyası Nerede Bulunur ve Nasıl Erişilir?
Bir WordPress kurulumu için birincil .htaccess dosyası belge kökünde bulunur — genellikle /public_html/, /var/www/html/ veya barındırma sağlayıcınızın atadığı eşdeğer yolda. Bu, wp-config.php, wp-login.php ve wp-content/ klasörünü içeren dizinin aynısıdır.
Dosya adı nokta ile başladığından, çoğu işletim sistemi ve FTP istemcisi onu varsayılan olarak gizler.
FileZilla’da gizli dosyaları göstermek için:
Server menu > Force showing hidden files
cPanel Dosya Yöneticisi’nde gizli dosyaları göstermek için:
Settings > Show Hidden Files (dotfiles)
SSH erişiminizin bulunduğu bir VPS Hosting ortamında, dosyanın var olduğunu doğrulayabilir ve izinlerini doğrudan inceleyebilirsiniz:
ls -la /var/www/html/ | grep htaccess
Dosya, web sunucusu kullanıcısına (genellikle www-data veya apache) ait olmalı ve 644 izinlerine sahip olmalıdır. .htaccess üzerindeki herkese yazma izinleri (666 veya 777) ciddi bir güvenlik açığıdır — sunucudaki herhangi bir işlem kurallarınızın üzerine yazabilir.
Varsayılan WordPress .htaccess Bloğunun Açıklaması
WordPress panosunda Ayarlar > Kalıcı Bağlantılar bölümüne gidip kaydettiğinizde, WordPress aşağıdaki bloğu yazar:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Satır satır açıklama:
RewriteEngine On — bu dizin bağlamı için yeniden yazma motorunu etkinleştirir.
RewriteBase / — göreli yeniden yazmalar için temel URL yolunu ayarlar. Alt dizin kurulumlarında bunu /subdirectory/ olarak değiştirin.
RewriteRule ^index.php$ - [L] — istek tam olarak index.php içinse, işlemeyi durdurun ve doğrudan sunun.
RewriteCond %{REQUEST_FILENAME} !-f — yalnızca istenen yol mevcut bir dosya değilse devam edin.
RewriteCond %{REQUEST_FILENAME} !-d — yalnızca istenen yol mevcut bir dizin değilse devam edin.
RewriteRule . /index.php [L] — diğer her şeyi WordPress’in ön denetleyicisine yönlendirin.
Kritik kural: # BEGIN WordPress ve # END WordPress işaretçileri arasındaki hiçbir şeyi manuel olarak düzenlemeyin. WordPress bu bloğu otomatik olarak yeniden oluşturur ve değişikliklerinizin üzerine yazar. Tüm özel direktifleri # BEGIN WordPress yorumunun üstüne veya # END WordPress yorumunun altına yerleştirin.
Eksik Olduğunda .htaccess Dosyası Nasıl Oluşturulur?
Eksik bir .htaccess dosyası, ana sayfa dışındaki tüm WordPress URL’lerinin 404 hatası döndürmesine neden olur; çünkü Apache’nin istekleri index.php üzerinden yönlendirme talimatı yoktur.
Yöntem 1: Pano Üzerinden Yeniden Oluşturma
Ayarlar > Kalıcı Bağlantılar bölümüne gidin ve herhangi bir şeyi değiştirmeden Değişiklikleri Kaydet‘e tıklayın. Dizin yazılabilir durumdaysa WordPress dosyayı otomatik olarak yazmayı deneyecektir.
Yöntem 2: SSH Üzerinden Manuel Oluşturma
nano /var/www/html/.htaccess
Yukarıda gösterilen varsayılan bloğu yapıştırın, Ctrl+O ile kaydedin ve Ctrl+X ile çıkın. Ardından doğru izinleri ayarlayın:
chmod 644 /var/www/html/.htaccess
chown www-data:www-data /var/www/html/.htaccess
Yöntem 3: FTP Üzerinden Oluşturma
Yerel olarak düz metin dosyası oluşturun, adını .htaccess koyun (.htaccess.txt değil — uzantı olmamalıdır), varsayılan bloğu yapıştırın ve ASCII aktarım modunda belge köküne yükleyin.
URL Yönlendirmeleri: 301, 302 ve Yeniden Yazma Kuralları
Kalıcı 301 Yönlendirmeleri
301 yönlendirmesi, arama motorlarına bir URL’nin kalıcı olarak taşındığını bildirir. Google, bağlantı değerinin yaklaşık %90–99’unu 301 üzerinden aktarır. Bir gönderi slug’ını yeniden adlandırdığınızda, HTTP’den HTTPS’e geçiş yaptığınızda veya yinelenen içeriği birleştirdiğinizde kullanın.
# Redirect a single old page to a new URL
Redirect 301 /old-page/ https://yourdomain.com/new-page/
# Redirect an entire old directory
Redirect 301 /old-category/ https://yourdomain.com/new-category/
Geçici 302 Yönlendirmeleri
302’yi yalnızca hedef gerçekten geçiciyse kullanın — örneğin A/B testi veya bakım pencereleri sırasında. Arama motorları bağlantı değerini 302 üzerinden aktarmaz.
Redirect 302 /sale/ https://yourdomain.com/promo-page/
mod_rewrite ile HTTPS’i Zorla
Bu, herhangi bir üretim WordPress sitesi için en önemli kurallardan biridir. Bunu WordPress bloğunun üstüne yerleştirmek, tüm HTTP trafiğinin WordPress isteği işlemeden önce kalıcı olarak HTTPS’e yönlendirilmesini sağlar:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
Siteniz SSL’i sonlandıran bir yük dengeleyici veya CDN’nin arkasındaysa (bulut altyapısında yaygındır), bunun yerine X-Forwarded-Proto kullanın:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
Bunu geçerli bir SSL Sertifikası ile eşleştirmek hem güvenlik hem de Google’ın sıralama sinyalleri için zorunludur.
Dizin Olmayan URL’lerden Sondaki Eğik Çizgiyi Kaldır
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} s(.+?)/+s
RewriteRule ^(.+)/$ /$1 [R=301,L]
</IfModule>
Kategori URL’lerinden “category” İfadesini Kaldır
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^category/(.+)$ https://yourdomain.com/$1 [R=301,L]
</IfModule>
Uyarı: Bu kural, WordPress’in dahili yönlendirmesini de güncellemek için WP No Category Base gibi bir eklenti gerektirir; aksi takdirde yönlendirme döngüleri oluşturursunuz.
.htaccess ile Güvenlik Sertleştirme
wp-config.php’yi Koruma
wp-config.php veritabanı kimlik bilgilerinizi, kimlik doğrulama anahtarlarınızı ve tuzlarınızı içerir. Doğrudan tarayıcı erişimi koşulsuz olarak engellenmelidir:
<Files wp-config.php>
Order Allow,Deny
Deny from all
</Files>
.htaccess Dosyasının Kendisini Koruma
.htaccess dosyasının tarayıcı isteğiyle okunmasını engelleyin:
<Files .htaccess>
Order Allow,Deny
Deny from all
</Files>
Dizin Taramasını Devre Dışı Bırakma
Bir dizin index.php veya index.html içermiyorsa, Apache varsayılan olarak içeriğini listeler — bu da dosya yapınızı saldırganlara açık hale getirir:
Options -Indexes
XML-RPC Kötüye Kullanımını Engelleme
xmlrpc.php, kaba kuvvet amplifikasyon saldırıları için sık hedef alınan bir dosyadır. Jetpack, uzaktan yayımlama veya pingback kullanmıyorsanız tamamen engelleyin:
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>
wp-login.php Erişimini Belirli IP Adreslerine Kısıtlama
IP’nizin statik olduğu bir cPanel’li VPS veya herhangi bir özel ortamda bu, mevcut en yüksek etkili güvenlik önlemlerinden biridir:
<Files wp-login.php>
Order Deny,Allow
Deny from all
Allow from 203.0.113.10
Allow from 198.51.100.25
</Files>
IP adreslerini gerçek statik IP’lerinizle değiştirin. Birden fazla konumdan çalışıyorsanız veya dinamik IP kullanıyorsanız, bunun yerine sabit çıkış düğümlü bir VPN kullanmayı düşünün.
Kötü Amaçlı Kullanıcı Aracılarını Engelleme
Kazıyıcılar, güvenlik açığı tarayıcıları ve yorum spam botları genellikle tanınabilir kullanıcı aracısı dizeleriyle kendilerini tanımlar:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (ahrefsbot|semrushbot|mj12bot|dotbot|nikto|sqlmap) [NC]
RewriteRule .* - [F,L]
</IfModule>
Not: Ahrefs ve SEMrush gibi meşru SEO tarayıcılarını engellemek, bu araçlardaki kendi geri bağlantı verilerinizi görmenizi engeller. Bu değiş tokuşu kullanım durumunuza göre değerlendirin.
IP Adresine Göre Erişimi Engelleme
<Limit GET POST HEAD>
Order Allow,Deny
Allow from all
Deny from 192.0.2.50
Deny from 198.51.100.0/24
</Limit>
CIDR gösterimi (örn. /24), tek bir IP aralığından koordineli saldırılarla uğraşırken kullanışlı olan tüm alt ağları engellemenizi sağlar.
Görsel Hotlinking’i Önleme
Hotlinking, size herhangi bir fayda sağlamadan bant genişliğinizi tüketir. Harici sitelerin görsellerinizi doğrudan yerleştirmesini engelleyin:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https://(www.)?yourdomain.com/ [NC]
RewriteRule .(jpg|jpeg|png|gif|webp|svg)$ - [F,NC]
</IfModule>
.htaccess ile Güvenlik Başlıkları Ekleme
HTTP güvenlik başlıkları, .htaccess dosyasının herhangi bir eklenti olmadan ekleyebileceği, sıklıkla göz ardı edilen bir savunma katmanıdır:
<IfModule mod_headers.c>
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
</IfModule>
İçerik Güvenlik Politikası (CSP) için başlık değeri, sitenizin özel varlık kaynaklarına göre uyarlanmalıdır — genel bir CSP, satır içi komut dosyalarını ve üçüncü taraf yerleştirmelerini bozar.
Performans Optimizasyonu
mod_deflate ile Gzip Sıkıştırmayı Etkinleştirme
Gzip sıkıştırma, HTML, CSS ve JavaScript yanıtlarının boyutunu %60–80 oranında azaltarak İlk Bayta Kadar Geçen Süreyi (TTFB) ve Core Web Vitals puanlarını doğrudan iyileştirir:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE image/svg+xml
# Remove browser bugs for older clients
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.0[678] no-gzip
BrowserMatch bMSIE !no-gzip !gzip-only-text/html
Header append Vary User-Agent
</IfModule>
Zaten sıkıştırılmış formatları sıkıştırmayın: image/jpeg, image/png, image/gif, image/webp, application/zip, application/pdf. Bunları sıkıştırmaya çalışmak CPU döngülerini boşa harcar ve yanıt boyutunu gerçekten artırabilir.
mod_expires ile Tarayıcı Önbelleğe Alma
Tarayıcı önbelleğe alma, geri dönen ziyaretçilerin tarayıcılarına statik varlıkları sunucunuzdan yeniden indirmek yerine yerel önbellekten sunmalarını söyler:
<IfModule mod_expires.c>
ExpiresActive On
# Images
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
# Fonts
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType font/woff "access plus 1 year"
ExpiresByType application/font-woff "access plus 1 year"
# CSS and JavaScript
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
# HTML and XML (short cache — content changes frequently)
ExpiresByType text/html "access plus 1 hour"
ExpiresByType application/xml "access plus 1 hour"
ExpiresByType application/rss+xml "access plus 1 hour"
# Default fallback
ExpiresDefault "access plus 1 month"
</IfModule>
Önbellek temizleme değerlendirmesi: CSS ve JS için uzun önbellek süreleri, önbellek sona erene kadar tarayıcıların güncellemeleri almayacağı anlamına gelir. Sürümlü dosya adları veya sorgu dizeleri kullanın (örn. style.css?ver=2.1) — WordPress’in wp_enqueue_style() fonksiyonu bunu $ver parametresi aracılığıyla otomatik olarak yönetir.
Ayrıntılı Kontrol için Cache-Control Başlıkları
mod_expires, Expires başlığını ayarlar. Modern HTTP/1.1 ve HTTP/2 uyumluluğu için Cache-Control başlığını da açıkça ayarlayın:
<IfModule mod_headers.c>
<FilesMatch ".(ico|jpg|jpeg|png|gif|webp|css|js|woff2|woff)$">
Header set Cache-Control "max-age=31536000, public, immutable"
</FilesMatch>
<FilesMatch ".(html|php)$">
Header set Cache-Control "max-age=3600, must-revalidate"
</FilesMatch>
</IfModule>
immutable direktifi, destekleyen tarayıcılara (Firefox, Chrome) kaynağı ömrü boyunca yeniden doğrulamamalarını söyler ve koşullu GET isteklerini tamamen ortadan kaldırır.
Keep-Alive’ı Etkinleştirme
Kalıcı bağlantılar, aynı sayfadaki birden fazla varlık için TCP el sıkışma yükünü azaltır:
<IfModule mod_headers.c>
Header set Connection keep-alive
</IfModule>
Karşılaştırma: .htaccess ile Eklenti Tabanlı Yapılandırma
Özellik
.htaccess Direktifi
WordPress Eklenti Karşılığı
Performans Etkisi
URL yeniden yazma
mod_rewrite kuralları
Yoast SEO, Redirection
.htaccess daha hızlı (PHP yükü yok)
Gzip sıkıştırma
mod_deflate
WP Super Cache, W3 Total Cache
.htaccess daha hızlı (Apache düzeyinde)
Tarayıcı önbelleğe alma
mod_expires
WP Rocket, LiteSpeed Cache
.htaccess daha hızlı (Apache düzeyinde)
IP engelleme
Deny from
Wordfence, iThemes Security
.htaccess daha hızlı (PHP öncesi)
Güvenlik başlıkları
mod_headers
HTTP Headers eklentisi
.htaccess daha hızlı (Apache düzeyinde)
wp-login.php koruması
<Files> bloğu
Limit Login Attempts Reloaded
.htaccess daha hızlı (PHP öncesi)
İçerik Güvenlik Politikası
mod_headers
CSP eklentileri
Eşdeğer — her ikisi de başlık ekler
Veritabanı tabanlı yönlendirmeler
Geçerli değil
Redirection eklentisi
Büyük yönlendirme setleri için eklenti kazanır
GUI yönetimi
Geçerli değil
All In One WP Security
Teknik olmayan kullanıcılar için eklenti kazanır
Temel mimari içgörü: .htaccess kuralları, PHP çağrılmadan önce Apache modül düzeyinde çalışır. Bu, engellenen bir isteğin neredeyse hiç sunucu kaynağı tüketmediği anlamına gelir. Eklenti tabanlı bir engelleme, WordPress’i başlatmak, eklentiyi yüklemek ve ardından isteği reddetmek zorundadır — engellenen istek başına 10–50 kat daha fazla bellek ve CPU tüketir. Bot saldırısı altındaki yüksek trafikli sitelerde bu fark, çevrimiçi kalma ile çökme arasındaki sınırdır.
Hassas Dizinleri Koruma
wp-includes Dizinini Kilitleme
wp-includes dizini hiçbir zaman PHP dosyalarını doğrudan tarayıcılara sunmamalıdır:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-includes/[^/]+.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>
Uploads Dizinine Erişimi Kısıtlama
wp-content/uploads/ dizini medya dosyalarını sunmalı ancak hiçbir zaman PHP çalıştırmamalıdır. Savunmasız bir eklenti aracılığıyla yüklenen ve bu dizinden çalıştırılan bir PHP dosyası, klasik bir web kabuğu saldırı vektörüdür:
<Directory "/var/www/html/wp-content/uploads">
<FilesMatch ".php$">
Order Deny,Allow
Deny from all
</FilesMatch>
</Directory>
Paylaşımlı Web Hosting kullanıyorsanız ve .htaccess içinde <Directory> bloklarını kullanamıyorsanız, wp-content/uploads/ içinde ayrı bir .htaccess dosyası oluşturun:
<FilesMatch ".php$">
Order Deny,Allow
Deny from all
</FilesMatch>
Özel Hata Sayfaları
Apache’nin varsayılan hata sayfalarını markalı, kullanıcı dostu alternatiflerle değiştirin:
ErrorDocument 400 /400.html
ErrorDocument 401 /401.html
ErrorDocument 403 /403.html
ErrorDocument 404 /404.html
ErrorDocument 500 /500.html
WordPress için 404 sayfası genellikle index.php tarafından temanın 404.php şablonuna yönlendirilerek işlenir — ancak 500 hataları için statik bir yedek bulundurmak değerlidir; çünkü 500 hatası PHP’nin kendisinin bozuk olabileceği anlamına gelir.
WordPress Multisite .htaccess Yapılandırması
WordPress Multisite, alt dizin veya alt alan adı ağ yapıları kullanıp kullanmadığınıza bağlı olarak farklı bir yeniden yazma bloğu gerektirir.
Alt dizin tabanlı Multisite:
# BEGIN WordPress Multisite
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
# Uploaded files
RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]
# Add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*.php)$ $2 [L]
RewriteRule . index.php [L]
</IfModule>
# END WordPress Multisite
Alt alan adı tabanlı Multisite, alan adı kayıt şirketi düzeyinde joker karakter DNS yapılandırması gerektirir — yalnızca .htaccess değişikliği yeterli değildir. Kendi DNS’inizi yönetiyorsanız, bu işlem joker karakter A kaydıyla (*.yourdomain.com) Alan Adı Kaydı sağlayıcınızın DNS paneli üzerinden gerçekleştirilir.
Gelişmiş Teknikler: Hız Sınırlama ve İstek Filtreleme
Sorgu Dizelerindeki Yaygın Saldırı Kalıplarını Engelleme
<IfModule mod_rewrite.c>
RewriteEngine On
# Block SQL injection attempts
RewriteCond %{QUERY_STRING} (union.*select|select.*from|insert.*into|drop.*table) [NC]
RewriteRule .* - [F,L]
# Block script injection
RewriteCond %{QUERY_STRING} (<script|javascript:|vbscript:) [NC]
RewriteRule .* - [F,L]
# Block base64 encoded payloads in query strings
RewriteCond %{QUERY_STRING} base64_encode.*(.*) [NC]
RewriteRule .* - [F,L]
</IfModule>
Önemli uyarı: Bu regex kalıpları kullanışlı bir ilk katmandır ancak Web Uygulama Güvenlik Duvarı’nın (WAF) yerini tutmaz. Gelişmiş saldırganlar, basit dize eşleştirmeyi atlayan kodlama varyasyonları kullanır. Bu kuralları kapsamlı bir savunma değil, gürültü filtresi olarak değerlendirin.
İstek Yöntemlerini Sınırlama
WordPress yalnızca GET, POST ve HEAD yöntemlerine ihtiyaç duyar. Diğer tüm HTTP yöntemlerini engelleyin:
<LimitExcept GET POST HEAD>
Order Deny,Allow
Deny from all
</LimitExcept>
En İyi Uygulamalar ve Operasyonel Disiplin
Her düzenlemeden önce:
Mevcut .htaccess dosyasını tarihli bir yedek olarak yerel makinenize indirin (örn. htaccess-backup-2025-01-15.txt).
Mümkünse değişikliği önce bir hazırlık ortamında test edin.
Tek seferde yalnızca bir mantıksal değişiklik yapın — tek bir düzenleme oturumunda birden fazla ilgisiz direktifi asla toplu olarak eklemeyin.
Her düzenlemeden sonra:
Tarayıcıda test etmeden önce sözdiziminin geçerli olduğunu doğrulamak için Apache’yi yeniden yükleyin:
apachectl configtest
configtest geçerse, düzgün bir şekilde yeniden yükleyin:
systemctl reload apache2
Değiştirdiğiniz belirli işlevselliği test edin, ardından yanıt başlıklarını doğrulamak için curl -I https://yourdomain.com gibi bir araçla tam site kontrolü yapın.
Sunucu erişimi olmadan sözdizimi doğrulama:
apachectl -t -f /path/to/.htaccess
Apache yapılandırmasını kontrol ettiğiniz Dedicated Sunucularda, performans açısından kritik direktifleri .htaccess dosyasından sanal ana bilgisayar yapılandırmasına (<VirtualHost> veya siteye özgü bir conf dosyasındaki httpd.conf bloğu) taşımayı düşünün. Apache, AllowOverride etkinleştirildiğinde her istekte .htaccess dosyasını okur — direktifleri ana yapılandırmaya taşımak bu istek başına yükü tamamen ortadan kaldırır.
Yaygın .htaccess Hatalarını Giderme
500 Dahili Sunucu Hatası
En yaygın neden .htaccess dosyasındaki sözdizimi hatasıdır. Apache’nin hata günlüğü tam satır numarasını içerecektir:
tail -n 50 /var/log/apache2/error.log
Yaygın sözdizimi hataları:
Eksik kapanış </IfModule> etiketi
Unix (LF) yerine Windows stili satır sonları (CRLF) kullanmak — dosyaları BOM olmadan UTF-8, LF satır sonlarıyla kaydedin
Yüklü olmayan bir modüle başvurma (örn. mod_rewrite devre dışı)
Yönlendirme Döngüsü
Yönlendirme döngüsü (ERR_TOO_MANY_REDIRECTS) genellikle şu durumlarda oluşur:
HTTPS yönlendirme kuralınız bağlantının zaten güvenli olduğunu doğru şekilde algılamıyor
.htaccess ve WordPress ayarlarınızda (Ayarlar > Genel URL’ler) çakışan yönlendirme kuralları var
Bir CDN veya proxy HTTPS sunucu değişkenini kaldırıyor
Tanı:
curl -I -L http://yourdomain.com 2>&1 | grep -E "HTTP|Location"
Yeniden Yazma Kuralları Çalışmıyor
mod_rewrite kuralları hiçbir etkisi yokmuş gibi görünüyorsa:
mod_rewrite modülünün etkin olduğunu doğrulayın: apache2ctl -M | grep rewriteAllowOverride All (veya en azından AllowOverride FileInfo) ayarlandığını doğrulayınRewriteEngine On direktifinin aynı bağlamdaki herhangi bir RewriteRule direktifinden önce geldiğini doğrulayınIP Kısıtlamaları Ekledikten Sonra Sayfalar 403 Yasak Hatası Döndürüyor
Kendi IP adresinizde yazım hatası içeren bir IP kısıtlama kuralı ekleyerek kendinizi kilitlediyseniz, dosyaya barındırma kontrol panelinin Dosya Yöneticisi üzerinden erişin (Apache’yi atlayarak dosya sistemi düzeyinde çalışır) ve kuralı düzeltin ya da kaldırın.
Karar Matrisi: .htaccess ile Alternatifleri Ne Zaman Kullanmalı?
| Senaryo | En İyi Yaklaşım | Neden |
|---|---|---|
| Az sayıda yönlendirme (< 50) | .htaccess Redirect veya RewriteRule | Sıfır eklenti yükü, anında çalışma |
| Büyük yönlendirme seti (> 200) | Veritabanı depolamalı Redirection eklentisi | .htaccess hantal hale gelir; eklenti GUI ve günlük kaydı sunar |
| Aktif saldırı sırasında IP engelleme | .htaccess Deny from | PHP öncesi çalışma, minimal sunucu yükü |
| Karmaşık WAF kuralları | Özel WAF (Cloudflare, ModSecurity) | .htaccess içindeki regex, gelişmiş saldırılar için yetersiz |
| Paylaşımlı hostingde performans optimizasyonu | .htaccess mod_deflate + mod_expires | Sunucu düzeyinde erişim yok; .htaccess tek seçenek |
| VPS/dedicated’da performans optimizasyonu | Sanal ana bilgisayar yapılandırması (httpd.conf) | İstek başına .htaccess ayrıştırma yükünü ortadan kaldırır |
| Güvenlik başlıkları | .htaccess mod_headers | Eklentiden daha basit; Apache düzeyinde çalışır |
| Multisite alt alan adı yönlendirme | .htaccess + joker karakter DNS | WordPress Multisite mimarisi tarafından gerekli |
Teknik Temel Çıkarımlar Kontrol Listesi
- Tüm özel direktifleri
# BEGIN WordPress/# END WordPressişaretçilerinin dışına yerleştirin — üstüne veya altına, asla içine değil. - Her
<IfModule>sarmalayıcısının dağıtmadan önce sunucunuzda gerçekten yüklü olan bir modülle eşleştiğini doğrulayın. .htaccessdosya izinlerini her zaman644olarak ayarlayın — asla666veya777olarak değil.wp-config.php,.htaccessdosyasının kendisini,xmlrpc.phpvewp-includes/*.phpdosyalarını açık reddetme kurallarıyla koruyun.- Sıkıştırma için
mod_deflateve statik varlıklar içinCache-Control: immutableile birliktemod_expireskullanın — bu iki değişiklik tek başına Core Web Vitals puanlarını önemli ölçüde iyileştirebilir. - HTTPS’i yalnızca WordPress ayarlarında değil,
.htaccessdüzeyinde zorunlu kılın; böylece PHP yüklenmeden önce istekler yakalanır. - VPS veya dedicated ortamlarda, istek başına dosya ayrıştırmasını ortadan kaldırmak için kararlı direktifleri
.htaccessdosyasından sanal ana bilgisayar yapılandırmasına taşıyın. - Her düzenleme oturumundan önce
.htaccessdosyasını tarihli bir dosya adıyla yedekleyin ve her değişiklikten sonraapachectl configtestile sözdizimini doğrulayın. wp-content/uploads/içinde PHP çalıştırmasını engelleyen ayrı bir.htaccessdosyası oluşturun — bu tek kural kritik bir web kabuğu saldırı vektörünü kapatır..htaccessgüvenlik kurallarını kapsamlı bir WAF değil, gürültü azaltma katmanı olarak değerlendirin — üretim ortamları için bunları ModSecurity veya CDN tabanlı WAF gibi sunucu düzeyindeki araçlarla eşleştirin.
Sıkça Sorulan Sorular
.htaccess dosyasını düzenlemek Apache’nin yeniden başlatılmasını gerektirir mi?
Hayır. AllowOverride etkinleştirildiğinde Apache, .htaccess dosyasını her HTTP isteğinde okur; bu nedenle değişiklikler sunucu yeniden başlatılmadan hemen geçerli olur. Ancak, üretimde 500 hatasına neden olmadan önce sözdizimi hatalarını yakalamak için düzenlemeden önce ve sonra apachectl configtest çalıştırılması kesinlikle önerilir.
.htaccess kuralları Nginx sunucularında çalışır mı?
Hayır. .htaccess Apache’ye özgü bir mekanizmadır. Nginx, .htaccess dosyalarını hiç okumaz. Eşdeğer kurallar, ana yapılandırma dosyasındaki Nginx’in server {} veya location {} bloklarında yazılmalıdır. Birçok yönetilen WordPress barındırma hizmeti Nginx kullanır ve yeniden yazma kurallarını sunucu yapılandırma düzeyinde yönetir; bu da .htaccess dosyasını bu platformlarda alakasız kılar.
.htaccess kullanmanın performans maliyeti nedir?
AllowOverride etkinleştirildiğinde Apache, her istekte belge kökünden istenen dosyaya kadar her dizinde .htaccess dosyası olup olmadığını kontrol eder. Derin dizin yapılarına sahip sitelerde bu, istek başına 4–6 dosya sistemi okuması anlamına gelebilir. Yüksek trafikli sitelerde direktifleri sanal ana bilgisayar yapılandırmasına taşımak ve AllowOverride None ayarlamak bu yükü tamamen ortadan kaldırır.
.htaccess kuralları WordPress kalıcı bağlantı ayarlarıyla çakışabilir mi?
Evet. En yaygın çakışma, özel bir RewriteRule kuralının WordPress’in ön denetleyici kalıbıyla çakışması durumunda oluşur. Özel yeniden yazma kurallarını her zaman # BEGIN WordPress bloğunun üstüne yerleştirerek önce değerlendirilmelerini sağlayın ve yeni yeniden yazma mantığı ekledikten sonra tüm kalıcı bağlantı yapılarını test edin.
Beklendiği gibi çalışmayan bir .htaccess kuralını nasıl hata ayıklarım?
Sanal ana bilgisayar yapılandırmanızda LogLevel alert rewrite:trace3 ile Apache’nin mod_rewrite günlüğünü geçici olarak etkinleştirin, ardından isteği yeniden oluşturun ve /var/log/apache2/error.log dosyasını inceleyin. İzleme çıktısı, hangi koşulların değerlendirildiğini, hangi kuralların eşleştiğini ve son yeniden yazılan URL’nin ne olduğunu tam olarak gösterir. Hata ayıklamadan hemen sonra izleme günlüğünü devre dışı bırakın — son derece ayrıntılı çıktı üretir ve performansı etkiler.
