Plik .htaccess to jedno z najważniejszych narzędzi konfiguracyjnych na serwerach Apache, szczególnie przy hostingu współdzielonym.
- Fundamenty i definicja pliku .htaccess
- Lokalizacja, struktura i zasady działania pliku .htaccess
- Tworzenie i edycja pliku .htaccess
- Aplikacje bezpieczeństwa i kontroli dostępu
- Optymalizacja wydajności i cachowanie
- Przekierowania i przepisywanie adresów URL
- Niestandardowe strony błędów i zarządzanie błędami
- Specyficzne zastosowania w WordPressie
- Najlepsze praktyki i wytyczne bezpieczeństwa
- Zaawansowane techniki i regex
W praktyce to zwykły plik tekstowy (nazwa od „Hypertext Access”), który pozwala zarządzać funkcjonalnością, bezpieczeństwem i wydajnością witryny bez edycji globalnej konfiguracji serwera. Dzięki .htaccess wdrożysz przekierowania, logikę rewrite, zabezpieczenia hasłem, kompresję oraz cache – bez dostępu do plików głównych Apache.
Najczęstsze i najpraktyczniejsze zastosowania pliku .htaccess obejmują:
- przekierowania adresów i kanonizację domeny,
- wdrażanie przyjaznych URL-i (rewrite),
- ochronę katalogów i plików (np. wp-config.php),
- blokowanie botów, IP oraz hotlinkowania,
- kompresję GZIP i nagłówki cache,
- wymuszanie HTTPS i dodatkowe reguły bezpieczeństwa.
Niniejszy przewodnik wyjaśnia fundamenty oraz praktyczne przykłady użycia .htaccess – od podstaw po rozwiązania produkcyjne.
Fundamenty i definicja pliku .htaccess
Czym dokładnie jest plik .htaccess
Plik .htaccess to lokalny plik konfiguracyjny Apache HTTP Server, przetwarzany przy każdym żądaniu dotyczącym katalogu, w którym się znajduje (oraz jego podkatalogów).
To zwykły plik tekstowy ze zrozumiałymi dla Apache dyrektywami – każda w osobnej linii. Komentarze poprzedza się znakiem #. Pozwala to precyzyjnie sterować zachowaniem serwera bez edycji konfiguracji globalnej.
W systemach Unix/Linux nazwa rozpoczynająca się kropką oznacza plik ukryty. Warto uniemożliwić jego publiczne wyświetlanie, ponieważ może zdradzać szczegóły zabezpieczeń. .htaccess działa głównie na Apache, ale jest obsługiwany również m.in. przez LiteSpeed (z drobnymi różnicami w implementacji).
Historia i znaczenie w ekosystemie Apache
.htaccess powstał, aby umożliwić elastyczne modyfikacje konfiguracji w środowiskach z wieloma witrynami na jednym serwerze, gdzie użytkownicy nie mają dostępu do plików globalnych.
Do dziś jest powszechnie używany – prosty, skuteczny i dostępny dla milionów stron. Dokumentacja Apache zaleca jednak, by przy dostępie do konfiguracji głównej wdrażać reguły właśnie tam (lepsza wydajność). Dla hostingu współdzielonego .htaccess pozostaje podstawowym narzędziem.
Lokalizacja, struktura i zasady działania pliku .htaccess
Gdzie się znajduje i jak działa
Najczęściej umieszcza się go w katalogu głównym witryny (np. public_html). Reguły obowiązują w tym katalogu i we wszystkich podkatalogach – możesz zatem tworzyć ogólne zasady wyżej i nadpisywać je lokalnie niżej.
Hierarchia ma znaczenie: reguły z .htaccess w podkatalogu mają pierwszeństwo w tym podkatalogu. To umożliwia granularną kontrolę, np. blokadę wykonywania PHP tylko w /uploads/.
Apache musi pozwalać na działanie .htaccess. Odpowiada za to dyrektywa AllowOverride w konfiguracji głównej. Jeśli ustawisz AllowOverride None – .htaccess będzie ignorowany. Często stosuje się AllowOverride FileInfo lub AllowOverride All, zależnie od potrzeb.
Składnia i edycja bez pułapek
Edytuj .htaccess w czystym trybie tekstowym, bez BOM. Zwróć uwagę na wielkość liter w nazwie – .htaccess to co innego niż .HTACCESS. Na macOS pliki z kropką są domyślnie ukryte – utwórz plik i nazwij go poprawnie po stronie serwera (np. przez FTP).
Używaj komentarzy – pomagają dokumentować reguły i szybciej diagnozować problemy.
Tworzenie i edycja pliku .htaccess
Proces tworzenia pliku .htaccess
Otwórz edytor tekstu (np. Notepad++, Sublime Text), wpisz minimalny zestaw dyrektyw i testuj etapami. Po każdej zmianie sprawdzaj działanie witryny.
Przykładowy .htaccess dla WordPress (pretty permalinks) wygląda tak:
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Zapisz plik dokładnie jako .htaccess i prześlij na serwer (FTP/menedżer plików w panelu hostingu).
Przed wprowadzeniem jakichkolwiek zmian wykonaj pełną kopię zapasową .htaccess i witryny. Błąd składni może spowodować 500 Internal Server Error.
Edycja i modyfikacja istniejącego pliku
Pobierz plik, zrób kopię, wprowadź zmiany, a następnie prześlij z powrotem. Dokumentuj modyfikacje w komentarzach i testuj je pojedynczo. W razie wątpliwości wyczyść cache przeglądarki i ewentualny cache serwera.
Aplikacje bezpieczeństwa i kontroli dostępu
Zabezpieczenie pliku .htaccess i plików krytycznych
Aby zablokować publiczny dostęp do .htaccess, dodaj do pliku regułę (składnia Apache 2.2):
<Files ".htaccess">
order allow,deny
deny from all
</Files>
Nowa składnia dla Apache 2.4+ (zalecana):
<Files ".htaccess">
Require all denied
</Files>
Aby chronić wp-config.php w WordPressie (2.2):
<Files "wp-config.php">
order allow,deny
deny from all
</Files>
Wersja dla Apache 2.4+:
<Files "wp-config.php">
Require all denied
</Files>
Blokowanie dostępu na podstawie adresów IP
Aby zablokować konkretny adres IP (Apache 2.2):
order allow,deny
deny from 203.0.113.10
allow from all
Odpowiednik dla Apache 2.4+:
Require all granted
Require not ip 203.0.113.10
Aby zezwolić tylko wybranym adresom IP (2.2):
order deny,allow
deny from all
allow from 198.51.100.5
allow from 203.0.113.10
Wersja dla Apache 2.4+:
Require ip 198.51.100.5 203.0.113.10
Ochrona katalogów hasłem
Najpierw utwórz plik .htpasswd poza katalogiem publicznym. Przykładowa zawartość wygląda tak:
uzytkownik:zaszyfrowane_haslo
inny_uzytkownik:inne_zaszyfrowane_haslo
Następnie w .htaccess wskaż lokalizację .htpasswd. Aby chronić konkretny plik:
<Files "nazwa_pliku.html">
AuthType Basic
AuthName "Ograniczony dostęp"
AuthUserFile /sciezka/do/.htpasswd
Require valid-user
</Files>
Aby chronić cały katalog:
AuthType Basic
AuthName "Ograniczony dostęp"
AuthUserFile /sciezka/do/.htpasswd
Require valid-user
Blokowanie botów i hotlinkowania
Aby zablokować określonego bota po nagłówku User-Agent:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^.*BadBot.* [NC]
RewriteRule .* - [F,L]
</IfModule>
Aby zapobiec hotlinkowaniu obrazów z innych domen:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?twoja-domena\.pl [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]
</IfModule>
Optymalizacja wydajności i cachowanie
Włączenie kompresji GZIP
Kompresja GZIP potrafi zmniejszyć rozmiar transferu nawet o 70% i dać natychmiastowy efekt.
Włącz GZIP dla typowych zasobów tekstowych:
<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/xhtml+xml
AddOutputFilterByType DEFLATE application/xml
</IfModule>
Obrazy (JPEG/PNG/WebP) są już skompresowane – nie kompresuj ich ponownie. Moduł doda też nagłówek Vary: Accept-Encoding.
Implementacja cachowania w przeglądarce
Ustaw daty wygaśnięcia nagłówkami Expires oraz zasady Cache-Control – dla zgodności ze starszymi i nowszymi przeglądarkami.
Przykład nagłówków Expires dla różnych typów zasobów:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 month"
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
Przykład nagłówka Cache-Control z długą ważnością statycznych plików:
<IfModule mod_headers.c>
<FilesMatch "\.(js|css|png|jpg|jpeg|gif|webp|svg)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
</IfModule>
Stosowanie obu rodzajów nagłówków maksymalizuje skuteczność cache i kompatybilność.
Przekierowania i przepisywanie adresów URL
Fundamentalne przekierowania HTTP
Najpopularniejsze kody to 301 (trwałe) i 302 (tymczasowe). 301 przenosi wartość SEO na nowy adres, 302 – nie.
Porównanie najważniejszych cech przekierowań 301 i 302:
| Typ | Znaczenie | Przeznaczenie | Wpływ SEO |
|---|---|---|---|
| 301 | Stałe przeniesienie | Zmiana struktury, migracje, kanonizacja | Przekazuje większość autorytetu na nowy URL |
| 302 | Tymczasowe przeniesienie | Testy A/B, sezonowe kampanie | Nie przenosi w pełni autorytetu |
Najprostszy przykład 301:
Redirect 301 /stara-strona.html https://przyklad.com/nowa-strona.html
Dla bardziej złożonych scenariuszy użyj mod_rewrite i RewriteRule.
Przekierowania domeny i wersji z/bez www
Aby wymusić wersję bez www dla konkretnej domeny:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.domena\.pl$ [NC]
RewriteRule ^(.*)$ https://domena.pl/$1 [L,R=301]
Aby wymusić wersję z www dla konkretnej domeny:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.domena\.pl$ [NC]
RewriteRule ^(.*)$ https://www.domena.pl/$1 [L,R=301]
Wymuszenie HTTPS i szyfrowanego połączenia
HTTPS jest standardem bezpieczeństwa i rankingowym czynnikiem SEO. Przekierowanie całego ruchu na HTTPS:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Niestandardowe strony błędów i zarządzanie błędami
Definiowanie niestandardowych stron błędów
Aby wyświetlić własną stronę dla błędu 404:
ErrorDocument 404 /error404.html
Przykładowe definicje dla kilku popularnych kodów:
ErrorDocument 400 /errors/400.html
ErrorDocument 401 /errors/401.html
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html
Możesz wskazać również pełny adres URL (np. dla 403):
ErrorDocument 403 https://inna-strona.com/
Specyficzne zastosowania w WordPressie
Standardowa konfiguracja WordPressa
Pretty Permalinks wymagają aktywnego mod_rewrite. Oto standardowa konfiguracja generowana przez WordPress:
# 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
Dodatkowe bezpieczeństwo dla WordPressa
Zabezpieczenie wp-config.php (Apache 2.4+):
<Files "wp-config.php">
Require all denied
</Files>
Blokowanie wykonywania PHP w katalogu /wp-content/uploads/ – uwaga: w .htaccess nie używamy <Directory>. Wgraj poniższy plik .htaccess bezpośrednio do katalogu uploads:
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
Wyłączenie XML-RPC (częsty cel ataków brute force):
<Files "xmlrpc.php">
Require all denied
</Files>
Blokada skanowania autorów po parametrze ?author=:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} ^author=([0-9]+) [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]
</IfModule>
Wymuszenie SSL dla panelu administratora:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^wp-admin(.*)$ https://example.com/wp-admin$1 [R=301,L]
Naprawianie problemów z plikiem .htaccess w WordPressie
Jeśli pojawia się 500 lub 404 dla permalinków, tymczasowo zmień nazwę pliku na .htaccess-old i sprawdź, czy problem ustępuje. Przywróć domyślną sekcję WordPress lub w panelu przejdź do Ustawienia > Bezpośrednie odnośniki i kliknij „Zapisz zmiany”, aby zregenerować plik.
Najlepsze praktyki i wytyczne bezpieczeństwa
Ostrożność i planowanie
W pracy z .htaccess stosuj trzy kluczowe zasady:
- Kopie zapasowe – zawsze rób backup pliku i bazy danych przed zmianami;
- Testowanie etapami – dodawaj reguły pojedynczo i natychmiast je sprawdzaj;
- Dokumentacja zmian – opisuj i datuj reguły w komentarzach dla przyszłych prac.
Nawet drobna literówka może „położyć” stronę – ostrożność to podstawa.
Optymalizacja wydajności
.htaccess jest wygodny, ale każda reguła to dodatkowy koszt parsowania przy każdym żądaniu. Jeśli masz dostęp do konfiguracji głównej, przenoś reguły poza .htaccess. Na hostingu współdzielonym trzymaj plik możliwie krótki i aktualny.
Uwzględnianie uprawnień plików
Zalecane uprawnienia dla WordPressa wyglądają następująco:
- 755 – katalogi (przechodzenie i odczyt, bez zapisu przez innych);
- 644 – pliki (odczyt dla wszystkich, zapis tylko dla właściciela);
- 600 – plik
wp-config.php(maksymalne ograniczenie dostępu); - 644 – plik
.htaccess(edytowalny dla właściciela, czytelny dla serwera).
Poniższe polecenia (uruchamiane przez SSH) pomogą ustawić właściwe uprawnienia:
find /ścieżka/do/wordpress -type d -exec chmod 755 {} \;
find /ścieżka/do/wordpress -type f -exec chmod 644 {} \;
chmod 600 /ścieżka/do/wordpress/wp-config.php
chmod 644 /ścieżka/do/wordpress/.htaccess
Zaawansowane techniki i regex
Wprowadzenie do wyrażeń regularnych w .htaccess
mod_rewrite obsługuje wyrażenia regularne, dzięki czemu możesz precyzyjnie mapować i transformować adresy URL. Oto najważniejsze symbole:
^– początek ciągu,$– koniec ciągu,.– dowolny pojedynczy znak,*– zero lub więcej poprzedniego znaku,+– jeden lub więcej poprzedniego znaku,?– zero lub jeden poprzedni znak,[abc]– dowolny z znaków a, b lub c,(xyz)– grupa, którą można przywołać później,\.– literalna kropka (ucieczka przed kropką).
Przykład zamiany /post-123 na /index.php?p=123:
RewriteRule ^post-([0-9]+)$ /index.php?p=$1 [L]
Warunki rewrite i logika przetwarzania
RewriteCond poprzedza RewriteRule i warunkuje jej wykonanie. Domyślnie warunki łączą się logicznym AND. Przykład wymuszenia HTTPS dla konkretnego hosta:
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Najczęściej używane zmienne w RewriteCond to:
%{HTTP_HOST}– nazwa domeny,%{REQUEST_URI}– żądana ścieżka,%{HTTPS}– status HTTPS,%{REQUEST_METHOD}– metoda HTTP (GET/POST itd.),%{QUERY_STRING}– parametry zapytania,%{HTTP_USER_AGENT}– identyfikator przeglądarki/bota.
Dzięki warunkom unikniesz pętli przekierowań i niepożądanych efektów ubocznych.