
Audyt .htaccess: dlaczego witryna zwraca 500 i które reguły nie działają
Przeciągnij plik — narzędzie znajdzie BOM, martwe dyrektywy, reguły z wysokim ryzykiem błędu 500 oraz ślady obcej ingerencji. Plik jest czytany w Twojej przeglądarce i nigdzie nie jest wysyłany.
Tekst wklejono ręcznie, więc blok kontroli bajtowych pominięto. Aby zobaczyć BOM, CRLF i niewidoczne znaki, przeciągnij sam plik.
Czysty .htaccess nie leczy włamania. Jeśli witryna jest przejęta, złośliwy kod żyje w PHP, a .htaccess jest tylko jego skutkiem: dropper nadpisze plik z powrotem w ciągu kilku minut od wyczyszczenia. Kolejność jest odwrotna — najpierw znaleźć wykonywalny kod, potem porządkować konfigurację.
Tutaj pojawi się plik źródłowy z numerami wierszy.
Wiersze ze znaleziskami oznaczono znakiem !: czerwone to błędy, bursztynowe to ostrzeżenia. Znaki niewidoczne i niedrukowalne pokazano kropką · — w samym pliku w ich miejscu jest pusto.
Czyszczenie usuwa BOM, zamienia znaki końca wiersza na LF, wycina znaki niedrukowalne, zastępuje spacje nierozdzielające zwykłymi i dopisuje znak nowej linii na końcu. Dyrektywy pozostają bez zmian. Plik jest zapisywany jako htaccess-clean.txt — zmień jego nazwę na .htaccess przed wysłaniem na serwer.
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Dokładnie to WordPress zapisuje sam. Własne reguły umieszczaj powyżej wiersza # BEGIN WordPress: wszystko między znacznikami jest nadpisywane za każdym razem, gdy zapisujesz ustawienia bezpośrednich odnośników.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [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
Dla multisite na subdomenach blok jest ten sam, ale bez prefiksu ^([_0-9a-zA-Z-]+/)? w trzech ostatnich regułach: RewriteRule ^(wp-(content|admin|includes).*) $1 [L] i RewriteRule ^(.*\.php)$ $1 [L].
Sama wymiana bloku nie przywraca bezpośrednich odnośników: po zmianie wejdź w Ustawienia → Bezpośrednie odnośniki i kliknij „Zapisz” — WordPress sprawdzi blok i w razie potrzeby go przepisze.
Plik jest czytany w Twojej przeglądarce — jego zawartość nigdzie nie jest wysyłana ani zapisywana.
Dlaczego plik, a nie wklejony tekst
Najczęstsza przyczyna błędu 500 po edycji .htaccess w ogóle nie jest widoczna w tekście. To BOM — trzy niewidzialne bajty na początku pliku, dodawane przez Notatnik Windows przy zapisie w UTF-8. Apache uznaje je za część pierwszej dyrektywy i nie potrafi jej przetworzyć. Dlatego narzędzie przyjmuje właśnie plik: tylko tak da się odczytać bajty i zobaczyć BOM, końce wierszy w stylu Windows oraz niewidzialne znaki wewnątrz wierszy. Druga grupa problemów to dyrektywy, które nic nie robią, ale wyglądają na działające. mod_gzip_on to składnia Apache 1.3; na współczesnych serwerach jest po cichu ignorowana, a ludzie latami sądzą, że kompresja jest włączona. Blok ExpiresByType opakowany w sprawdzenie mod_headers.c zamiast mod_expires.c też nie zadziała — i bez podpowiedzi tego nie widać. Trzecia sprawa to php_value i php_flag. Działają tylko wtedy, gdy PHP jest podłączony jako moduł Apache. Na nowoczesnych hostingach z PHP-FPM taki wiersz albo jest ignorowany, albo od razu daje 500. I osobno o bezpieczeństwie: jeśli w pliku znaleziono reguły przekierowujące odwiedzających w zależności od tego, z jakiej wyszukiwarki przyszli, albo ukrywające przekierowanie przed administratorem — to typowy objaw włamania. Ale czysty .htaccess nie leczy włamania: prawie zawsze gdzieś w plikach siedzi skrypt PHP, który zapisze go z powrotem.
