htaccess dosyanız 500 hatası veriyor ve hangi satırın sorumlu olduğunu bilmiyorsunuz
Az önce .htaccess dosyanıza yeni bir komut eklediniz ve şimdi site 500 Internal Server Error ile çöktü. Yaptığınız ilk şey dosyayı FTP üzerinden indirip satır satır incelemek. Sorun şu ki Apache tam hatayı göstermiyor ve hangi komutun tüm siteyi erişilemez yaptığını bilmiyorsunuz.
Hızlı çözüm: Dosyayı .htaccess.bak gibi farklı bir adla kaydedin ve yeni boş bir dosya oluşturun. Site geri gelir. Şimdi 500 hatası dönene kadar komutları tek tek ekleyin. Eklediğiniz son komut suçludur. Bu satır satır test yöntemi, paylaşımlı ortamda işe yarayan tek yoldur çünkü Apache hata günlükleri genellikle sizin erişiminize açık değildir.
htaccess komutlarının işlem sırası: her şeyin bozulduğu yer
Apache, .htaccess komutlarını yukarıdan aşağıya çalıştırmaz. Bu yaygın yanlış kanı, çoğu yönlendirme hatasının kaynağıdır. RewriteRule kuralları görünüş sırasına göre çalışır, ancak mod_alias modülündeki Redirect kuralları tam tersi şekilde çalışır: son kural önce çalışır.
Bu, birbiriyle çakışan iki yönlendirme kuralınız varsa sonucun beklediğinizden farklı olacağı anlamına gelir. Bu yüzden aynı dosyada Redirect ve RewriteRule karıştırmak neredeyse her zaman öngörülemez sonuçlar verir. İşte burada hata yaparlar: alan adı değişikliği için bir Redirect 301 kuralı ve www kaldırmak için bir RewriteRule koyarlar. Sonuç, zincirleme yönlendirmeler ve yavaş sitedir.
Kuralımı unutmayın: her iş için yalnızca bir modül kullanın. Yönlendirme yapmak istiyorsanız, tüm kuralları RewriteRule ile yazın. Belirli bir sayfayı taşımak istiyorsanız, Redirect kullanın. Bu ikisini karıştırmak, pratikte sürekli gördüğüm bir hatadır.
Bilmeniz gereken temel komutlar
Her şeyden önce temel yapıyı inceleyelim. .htaccess dosyası public_html kök dizininde bulunur ve kendi dosyaları olmadığı sürece tüm alt klasörlere uygulanır. Bu basamaklı (cascading) davranış, kökteki bir komutun tüm alt dizinleri etkilediği anlamına gelir.
# Yeniden yazma motorunu etkinleştir
RewriteEngine On
# Özel hata sayfası ayarla
ErrorDocument 404 /404.html
ErrorDocument 403 /forbidden.html
# htaccess dosyasına erişimi engelle
<Files ".htaccess">
Require all denied
</Files>
Require all denied komutu Apache 2.4'te eski sürümlerde kullanılan Deny from all yerine geçmiştir. Hosting'iniz Apache 2.2 kullanıyorsa, yeni komut çalışmaz ve tam tersi. Sürümü tespit etmek için bir phpinfo.php dosyası oluşturun ve SERVER_SOFTWARE değerine bakın.
301 Yönlendirmeleri: alan adı taşıma ve www kaldırma
301 yönlendirmesi arama motorlarına sayfanın kalıcı olarak taşındığını söyler. Bu, .htaccess dosyasına yazacağınız en önemli komuttur, özellikle sitenizin alan adını değiştirdiğinizde. Bunu yanlış yaparsanız, yılların SEO'sunu kaybedersiniz.
# www'den www olmayana yönlendirme
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
# HTTP'den HTTPS'ye yönlendirme
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
www kaldırma kuralının HTTPS kuralından önce gelmesi gerektiğine dikkat edin. Tersi olursa, önce HTTPS'ye yönlendirilirsiniz ve sonra www kaldırılır, bu da arka arkaya iki yönlendirme oluşturur. Her ekstra yönlendirme, tam bir round-trip ve TTFB'de 100 ila 300 milisaniyelik bir artış demektir.
Alan adını tamamen yeni bir alan adına taşımak için kural daha basittir:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^old-domain\.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www\.old-domain\.com$ [NC]
RewriteRule ^(.*)$ https://new-domain.com/$1 [R=301,L]
Önünüzde bir alan adı taşıma varsa, SEO kaybı olmadan site alan adını değiştirme rehberini okuyun. Bu rehber, dizine eklenmiş sayfaların değerini koruması için yönlendirmelerde hangi sırayı izlemeniz gerektiğini tam olarak gösterir.
Tarayıcı önbelleği ve sıkıştırma: hızı kurtaran iki komut
Paylaşımlı hostingdeki çoğu WordPress sitesi, tarayıcı düzeyinde hiçbir önbellek olmadan çalışır. Sonuç, her ziyaretçinin görselleri ve CSS ile JavaScript dosyalarını yeniden indirmesidir. İki basit blokla bu durumu değiştirebilirsiniz.
# Statik dosyalar için tarayıcı önbelleği
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
# Gzip sıkıştırma
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css application/javascript image/svg+xml
</IfModule>
Görseller için bir yıl abartı değildir. Görsel dosya adı değişmezse, tarayıcı bir yıla kadar yerel önbelleği kullanır ve sunucuya istek göndermez. Ancak HTML için asla bir yıllık önbellek koymayın, çünkü sayfa içeriği güncel kalmalıdır.
İşte burada hata yaparlar: mod_deflate modülü tüm hostinglerde etkin değildir. Komutu koyarsanız ve modül yoksa, 500 hatası alırsınız. Bu yüzden komutları <IfModule> içine koyarız. Bu etiket Apache'ye modül yoksa sessizce geç ve hata verme der.
Paylaşımlı hostingde izin verilmeyen komutlar
Paylaşımlı hosting, üzerinde onlarca başka sitenin de çalıştığı bir sunucuda kiracı olduğunuz anlamına gelir. Bu nedenle, herkesin güvenliği ve istikrarı için bazı komutların devre dışı bırakılması doğaldır. Bu komutlar genellikle 500 hatası veya günlükte Invalid command mesajıyla karşılaşır.
| Komut | Devre dışı kalma nedeni | Alternatif |
|---|---|---|
php_value memory_limit |
Dizin düzeyinde PHP'ye ayrılan belleği değiştirme | php.ini'de değiştirme veya destekten talep etme |
Options +FollowSymLinks |
Güvenlik: sembolik bağlantıları takip etmeye izin verme | Genellikle zaten etkindir veya gerekmez |
public_html dışında hedef ile RewriteRule |
Web kök dizini dışındaki dosyalara erişim | Dosyayı public_html içine taşıma |
Belirli başlıklar için SetEnvIf |
Sunucu güvenlik ayarlarıyla çakışabilir | .user.ini veya php.ini kullanma |
Bir komut yazdıysanız ve 500 hatası aldıysanız, önce komutun sunucu düzeyinde devre dışı olduğunu varsayın, syntax hatası olduğunu değil. Hızlı bir test yöntemi: komutu <IfModule> içine koyun. Hata düzelirse, modül veya komut kullanılamıyor demektir.
Paylaşımlı hostingdeki kaynakların tam sınırlarını görmek için hosting kaynak sınırları kapsamlı referansını inceleyin. Bu belge, yönetim panelindeki her sayının neyi saydığını ve nerede sınıra ulaştığınızı gösterir.
Klasörleri parola ile koruma
Bazen bir klasörü genel görünümden gizlemeniz gerekir, örneğin test ortamı veya yönetim paneli. Standart yöntem, public_html dışında bulunan ve indirilemeyen .htpasswd kullanmaktır.
# İlgili klasördeki .htaccess dosyasında
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /home/username/.htpasswd
Require valid-user
/home/username/.htpasswd yolunu hosting'inizdeki gerçek yolla değiştirin. Parola dosyası oluşturmak için SSH'de aşağıdaki komutu kullanın:
htpasswd -c /home/username/.htpasswd admin
SSH'ınız yoksa, çevrimiçi .htpasswd oluşturma araçları da çalışır, ancak parola hash'inin bcrypt veya apr1 türünde olduğundan emin olun. Eski düz MD5 hash'leri Apache 2.4'te desteklenmez ve kimlik doğrulama hatası verir.
Test ortamı veya alt alan adı için bu işlemi yapmak istiyorsanız, hostingde klasör şifreleme kapsamlı rehberine bakın. Bu yöntem tüm Linux hostinglerde çalışır ve eklenti veya ek araç gerektirmez.
IP engelleme ve kötü amaçlı istekleri önleme
Sunucu günlüğüne bakarsanız, botların ve tarayıcıların sürekli olarak savunmasız yolları aradığını görürsünüz. Belirli IP'leri .htaccess düzeyinde engellemek basittir ancak sınırlamaları vardır.
# Belirli IP'yi engelle
<RequireAll>
Require all granted
Require not ip 123.45.67.89
Require not ip 203.0.113.0/24
</RequireAll>
Bu yöntemin sınırlaması: saldırgan dinamik IP kullanıyorsa veya farklı ağlardan geliyorsa, bu liste işe yaramaz. Gerçek saldırılar için, Wordfence gibi uygulama düzeyinde güvenlik duvarı veya hosting'inizin kendi güvenlik araçlarını kullanmak daha iyidir. .htaccess, belirli birkaç rahatsız edici IP'yi engellemek için iyidir, bir saldırıya karşı savunma için değil.
Ayrıca istek başlıklarını kontrol edebilir ve kötü botları engelleyebilirsiniz:
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (ahrefsbot|mj12bot|semrushbot) [NC]
RewriteRule ^ - [F,L]
[F] komutu 403 kodu döndürür ve [L] sonraki kuralların işlenmesini durdurur anlamına gelir. Bu kombinasyon belirli botları engellemek için etkilidir, ancak Googlebot gibi faydalı botları yanlışlıkla engellememeye dikkat edin.
Yaygın hataları giderme: beyaz ekran ve yönlendirme döngüsü
Destekte en çok gördüğümüz iki hata beyaz ekran ve yönlendirme döngüsüdür. Beyaz ekran genellikle .htaccess ile ilgili değildir ve PHP hatasından kaynaklanır. Ancak bazen php_flag display_errors on gibi yanlış bir komut sorunu daha da kötüleştirebilir.
Yönlendirme döngüsü ise neredeyse her zaman .htaccess kaynaklıdır. Tarayıcıdaki belirtisi: ERR_TOO_MANY_REDIRECTS mesajı. Genellikle HTTPS kuralınızın zaten HTTPS olan isteklere de uygulanmasıdır. Çözüm, yeniden kontrol koşulu eklemektir:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
İkinci satırdaki koşul, X-Forwarded-Proto başlığını kontrol eder. Siteniz CDN veya proxy arkasındaysa, bu başlık orijinal bağlantının HTTPS olduğunu ve tekrar yönlendirilmemesi gerektiğini gösterir. Bu koşul olmadan, sunucu ile CDN arasında sonsuz bir döngü oluşur.
Beyaz ekranla karşılaşırsanız, WordPress ve PHP'de beyaz ekran giderme rehberini izleyin. Çoğu zaman sorun PHP belleğinden kaynaklanır, .htaccess'ten değil. Ancak .htaccess değişikliğinden sonra beyaz ekran oluştuysa, önce dosyayı önceki haline döndürün.
Ana sitede uygulamadan önce komutları test etme
Yeni bir komutu asla doğrudan ana sitede test etmeyin. Bir test klasörü oluşturun, .htaccess dosyasını oraya koyun ve davranışı inceleyin. Bu işlem iki dakika sürer ve sizi bir saatlik hata ayıklamadan kurtarır.
Yönlendirme kurallarının doğru çalışıp çalışmadığını kontrol etmek için curl komut satırı aracını kullanın:
curl -I -L https://example.com/old-page
Çıktı, tüm zincirleme yönlendirmeleri gösterir. Arka arkaya ikiden fazla yönlendirme görürseniz, kurallarınız optimize değildir. Her ekstra yönlendirme, gerçek kullanıcılar için yükleme süresini artırır.
DNS'i kontrol etmek ve kayıtların doğru ayarlandığından emin olmak için DNS ve ağ kontrolü aracını kullanın. Bazen yönlendirme sorunu .htaccess'ten değil DNS'ten kaynaklanır. Alan adı eski sunucuya işaret ediyorsa, kuralı ne kadar doğru yazarsanız yazın, kullanıcı doğru yere ulaşamaz.
htaccess çalışmadığında: ne yapmalısınız
Bazen komut doğrudur, syntax da doğrudur, ancak hiçbir etkisi yoktur. Bu genellikle Apache'nin o dizinde .htaccess işlemesine izin vermediği anlamına gelir. Sunucu yapılandırmasındaki AllowOverride None ayarı, tüm .htaccess dosyalarını etkisiz kılar.
Paylaşımlı hostingde bu durum nadirdir ancak bazı klasörler için oluşabilir. Basit test: dosyaya kasıtlı bir hata koyun, örneğin fazladan bir karakter. Site 500 hatası vermezse, dosya hiç okunmuyor demektir. Hata verirse, dosya işleniyor ve sorun başka yerde demektir.
Özel sunucudaysanız, sanal host yapılandırma dosyasındaki AllowOverride ayarlarını değiştirebilirsiniz. Ancak paylaşımlı hostingde bu sizin elinizde değildir ve destekle iletişime geçmeniz gerekir. Çoğu zaman sorun başka yerdedir: site önbelleği. Sayfa önbelleği kullanıyorsanız, .htaccess değişiklikleri önbellek temizlenene kadar uygulanmayabilir.
Sitenizin komutları etkisiz kılan sunucu tarafı önbellek kullanıp kullanmadığını kontrol etmek için yanıt başlıklarını curl -I ile inceleyin. X-Cache: HIT veya benzeri bir başlık görürseniz, önbelleği temizleyin ve tekrar test edin.
Sık sorulan sorular
htaccess değişikliğinden sonra neden 500 hatası alıyorum?
.htaccess değişikliğinden sonraki 500 hatası neredeyse her zaman bir syntax hatasından veya hosting'inizde devre dışı bırakılmış bir komut kullanmaktan kaynaklanır. Site geri gelsin diye dosyayı farklı bir adla kaydedin, ardından 500 hatası dönene kadar komutları tek tek ekleyin. Eklediğiniz son komut suçludur.
htaccess'te Redirect ve RewriteRule arasındaki fark nedir?
Redirect, mod_alias modülündendir ve yalnızca bir URL'den diğerine basit aktarım için kullanılır. RewriteRule, mod_rewrite'dandır ve RewriteCond ile koşul belirleme imkanı sunar. www kaldırma veya HTTPS'ye geçiş gibi koşullu yönlendirmeler için RewriteRule kullanın. Bu ikisini aynı dosyada karıştırmak öngörülemez sonuçlar verir.
htaccess'te HTTP'den HTTPS'ye 301 yönlendirmesini nasıl yaparım?
Standart kural şudur: RewriteCond %{HTTPS} off ve ardından RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]. Site CDN arkasındaysa, yönlendirme döngüsü oluşmaması için ikinci koşul RewriteCond %{HTTP:X-Forwarded-Proto} !https ekleyin.
htaccess'te PHP bellek sınırını değiştirebilir miyim?
php_value memory_limit komutu çoğu paylaşımlı hostingde devre dışıdır çünkü sunucu güvenliğini tehlikeye atar. Daha fazla belleğe ihtiyacınız varsa, hosting desteğinden isteyin veya .user.ini dosyasını kullanın. ServerNet Linux hostingde bu sınırlar şeffaf bir şekilde belirtilmiştir ve tam olarak ne kadar kaynağa sahip olduğunuzu bilirsiniz.