icomHOST

Wszystko o domenach i hostingach

Co to jest mod_rewrite i jak go używać

Co to jest mod_rewrite i jak go używać

mod_rewrite to moduł serwera Apache, który pozwala przechwytywać i przekształcać adresy URL zanim żądanie trafi do właściwego zasobu (pliku, katalogu, skryptu). W praktyce oznacza to możliwość tworzenia „ładnych” adresów, kierowania ruchu między wersjami strony, wymuszania HTTPS, zmiany domeny, obsługi błędów, a nawet blokowania niepożądanych botów. Na hostingach współdzielonych jest to jeden z najczęściej wykorzystywanych elementów konfiguracyjnych, ponieważ wiele ustawień można realizować bez dostępu do pełnej konfiguracji serwera, wyłącznie przez plik .htaccess.

Co to jest mod_rewrite i gdzie działa

mod_rewrite jest częścią serwera Apache i wykorzystuje tzw. „silnik przepisywania” (RewriteEngine), oparty o reguły dopasowania wyrażeń regularnych. Gdy użytkownik lub bot wywołuje dany adres URL, Apache może – na podstawie reguł – zmienić ścieżkę żądania lub wysłać przekierowanie do przeglądarki. Najważniejsze jest rozróżnienie dwóch działań:

  • Rewrite „wewnętrzny” (internal rewrite) – przeglądarka nadal widzi ten sam adres, a serwer mapuje go na inny plik/skrypt. To typowe w CMS-ach: /produkt/123 może w środku trafić do index.php?product=123.
  • Redirect (zewnętrzne przekierowanie) – serwer odpowiada kodem 301/302 i przeglądarka dostaje nowy adres, np. przejście z http:// na https://.

mod_rewrite może działać na dwóch poziomach konfiguracji:

  • w konfiguracji globalnej VirtualHost (dostępne na serwerach dedykowanych/VPS),
  • w plikach .htaccess (często jedyna opcja na hostingu współdzielonym).

Wymagania po stronie hostingu

Żeby reguły w .htaccess faktycznie działały, muszą być spełnione warunki:

  • Moduł mod_rewrite musi być włączony na serwerze.
  • Dla katalogu musi być dopuszczone nadpisywanie ustawień, zwykle dyrektywą AllowOverride (np. AllowOverride All lub przynajmniej AllowOverride FileInfo).
  • Apache musi w ogóle czytać .htaccess (czasem administrator wyłącza to dla wydajności w konfiguracji globalnej).

Na typowym hostingu WWW mod_rewrite jest aktywne, bo korzystają z niego WordPress, Joomla, Drupal czy różne frameworki PHP. Jeżeli jednak przekierowania „nie chwytają”, warto zacząć od sprawdzenia, czy plik .htaccess znajduje się w odpowiednim katalogu (zwykle katalog główny domeny), ma poprawną nazwę (z kropką na początku) i jest odczytywany (czasem problemem są uprawnienia lub brak wsparcia u dostawcy).

Podstawy składni: RewriteEngine, RewriteRule i RewriteCond

Konfiguracja mod_rewrite opiera się na kilku dyrektywach. Najważniejsze to:

  • RewriteEngine On – włącza silnik przepisywania.
  • RewriteRule – opisuje regułę: co dopasować i na co zamienić.
  • RewriteCond – warunek, który musi być spełniony, aby następna RewriteRule została zastosowana.
  • Flagi (np. [L], [R=301], [NC]) – modyfikują zachowanie reguły.

Jak czytać RewriteRule

Najczęściej spotkasz zapis w formie:

RewriteRule wzorzec cel [flagi]

Wzorzec jest zwykle wyrażeniem regularnym dopasowywanym do ścieżki URL (bez domeny). Cel może być ścieżką wewnętrzną (np. index.php) albo pełnym adresem (np. https://example.com/…), jeśli robisz przekierowanie. Flagi są podawane w nawiasach kwadratowych.

Najpopularniejsze flagi

  • L (last) – jeśli reguła zadziała, zatrzymaj dalsze przetwarzanie kolejnych reguł w tym kontekście.
  • R=301 – zrób przekierowanie z kodem 301 (stałe). Dla tymczasowych zmian używa się R=302.
  • NC (no case) – dopasowanie bez rozróżniania wielkości liter.
  • QSA (query string append) – dołącz istniejące parametry zapytania, zamiast je nadpisywać.
  • F – zwróć 403 Forbidden (blokada).
  • G – zwróć 410 Gone (zasób trwale usunięty).

RewriteCond i zmienne serwerowe

Warunki operują na zmiennych, np.:

  • REQUEST_URI – ścieżka żądania,
  • QUERY_STRING – parametry po znaku ?,
  • HTTP_HOST – domena (host),
  • HTTPS – informacja, czy połączenie jest szyfrowane,
  • REQUEST_FILENAME – fizyczna ścieżka do pliku na dysku po mapowaniu.

Typowy scenariusz: najpierw sprawdzasz warunek (np. „czy to nie jest HTTPS”), a potem wykonujesz przekierowanie.

Najczęstsze zastosowania na serwerach i hostingach

1) Wymuszenie HTTPS

Po wdrożeniu certyfikatu TLS (np. Let’s Encrypt) warto wymusić ruch po HTTPS. Popularna reguła w .htaccess:

RewriteEngine On

RewriteCond %{HTTPS} !=on

RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

To przekierowanie 301. Na hostingach za reverse proxy bywa konieczna inna zmienna (np. X-Forwarded-Proto), ale w klasycznym Apache powyższe rozwiązanie działa często poprawnie.

2) Przekierowanie z www na bez www (lub odwrotnie)

Ujednolicenie adresu jest ważne dla SEO i spójności linkowania. Przykład przekierowania z www na bez www:

RewriteEngine On

RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]

RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]

Analogicznie da się wymusić wersję z www.

3) Migracja domeny na nową

Jeśli zmieniasz domenę (rebranding, zmiana TLD), mod_rewrite pozwoli przenieść ruch z zachowaniem ścieżek:

RewriteEngine On

RewriteCond %{HTTP_HOST} ^stara-domena\.pl$ [NC]

RewriteRule ^(.*)$ https://nowa-domena.pl/$1 [R=301,L]

To jedno z najważniejszych przekierowań w praktyce administracji hostingiem: utrzymuje działające linki i ogranicza utratę ruchu.

4) „Ładne adresy” i front controller (CMS/framework)

Wiele aplikacji opiera routing o jeden plik, np. index.php. Dzięki mod_rewrite możesz ukryć parametry i rozszerzenia. Częsty schemat:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -f [OR]

RewriteCond %{REQUEST_FILENAME} -d

RewriteRule ^ – [L]

RewriteRule ^ index.php [L]

To oznacza: jeśli żądany zasób jest istniejącym plikiem (-f) lub katalogiem (-d), nie ruszaj go; w przeciwnym razie przekaż do index.php. Jest to fundament działania wielu instalacji WordPressa i innych systemów, bo pozwala obsługiwać adresy typu /kategoria/produkt zamiast /index.php?page=….

5) Usuwanie index.php z URL

Jeżeli aplikacja historycznie generowała adresy z index.php, możesz je „wyczyścić” przekierowaniem:

RewriteEngine On

RewriteCond %{THE_REQUEST} \s/+index\.php[?\s] [NC]

RewriteRule ^index\.php$ / [R=301,L]

Warunek THE_REQUEST sprawdza, co naprawdę przyszło od klienta. To pomaga uniknąć pętli przekierowań, bo internal rewrite do index.php nie powinien powodować redirectu w drugą stronę.

6) Przekierowania pojedynczych podstron i mapowanie starych adresów

Przy przebudowie serwisu często trzeba zachować stare linki. Najprostszy zapis:

Redirect 301 /stary-artykul https://example.com/nowy-artykul

To dyrektywa z innego modułu (mod_alias), ale w praktyce często wystarczy i jest czytelniejsza. Gdy jednak potrzebujesz warunków, masowych reguł lub wyrażeń regularnych, wtedy mod_rewrite bywa niezastąpione.

7) Obsługa błędów i stron zastępczych

Wiele hostingów pozwala ustawić własne strony błędów (404, 403). Sam mod_rewrite może pomóc np. zwracać 410 dla usuniętych treści:

RewriteEngine On

RewriteRule ^stara-oferta$ – [G,L]

Kod 410 jest sygnałem, że zasób zniknął na stałe, co bywa korzystne przy porządkowaniu indeksu wyszukiwarki.

8) Proste zabezpieczenia: blokady, hotlinking, ograniczanie dostępu

mod_rewrite może wspierać bezpieczeństwo, choć nie zastąpi WAF-a ani dobrych praktyk aplikacyjnych. Przykłady:

  • Blokada dostępu do plików konfiguracyjnych:

RewriteRule (^|/)\.(env|git|svn) – [F,L]

  • Ochrona przed hotlinkingiem obrazków (w uproszczeniu):

RewriteEngine On

RewriteCond %{HTTP_REFERER} !^$

RewriteCond %{HTTP_REFERER} !^https?://(www\.)?twojadomena\.pl/ [NC]

RewriteRule \.(jpg|jpeg|png|gif|webp)$ – [F,NC,L]

To blokuje serwowanie plików graficznych, jeśli referer wskazuje na obcą domenę (z zastrzeżeniem, że referer może być pusty lub fałszowany).

mod_rewrite w praktyce hostingu: wydajność, pułapki i diagnostyka

Plik .htaccess a wydajność

Na serwerach o dużym ruchu administratorzy często wolą przenosić reguły z .htaccess do konfiguracji VirtualHost. Powód jest prosty: Apache, obsługując żądanie, może wędrować po strukturze katalogów i sprawdzać, czy gdzieś po drodze nie ma .htaccess. To generuje dodatkowe operacje wejścia/wyjścia. Na hostingu współdzielonym, gdzie nie masz dostępu do VirtualHost, .htaccess pozostaje standardem, ale warto pamiętać o kilku zasadach:

  • Trzymaj reguły możliwie proste i unikaj nadmiarowych warunków.
  • Nie dubluj przekierowań (np. osobno www->non-www i http->https w taki sposób, by robiły dwa „skoki”). Lepiej złożyć je tak, aby robić jedno przekierowanie do wersji kanonicznej.
  • Uważaj na reguły łapiące „wszystko” bez wyjątków dla plików i katalogów.

Pętle przekierowań i kanonikalizacja

Najczęstszy błąd to pętla (redirect loop). Powstaje, gdy warunki są zbyt ogólne albo reguły wzajemnie się wyzwalają. Przykład: jedna reguła dodaje ukośnik na końcu, druga go usuwa. Albo reguła wymusza HTTPS, ale serwer jest za proxy, a Apache „widzi” żądanie jako HTTP – wtedy każda odpowiedź kończy się ponownym przekierowaniem.

W praktyce warto budować jeden „kanoniczny” adres:

  • HTTPS zawsze,
  • www lub bez www konsekwentnie,
  • spójna wielkość liter (zależnie od potrzeb),
  • ustalona polityka slash/no-slash.

RewriteBase i kontekst katalogu

Na hostingach, gdzie strona działa z podkatalogu (np. domena kieruje do /public_html/subdir), czasem pojawia się konieczność użycia RewriteBase. To dyrektywa, która pomaga Apache poprawnie rozwiązać ścieżki docelowe w regułach. Błędy w RewriteBase potrafią objawiać się tym, że przekierowania „doklejają” nieprawidłową część ścieżki albo aplikacja nagle dostaje 404 mimo poprawnej reguły.

Różnice między 301 i 302 oraz wpływ na cache

Na serwerach i hostingach ważne jest, by świadomie dobierać kody odpowiedzi:

  • 301 – przekierowanie stałe; przeglądarki i roboty potrafią je zapamiętywać, co utrudnia szybkie wycofanie zmian.
  • 302 – przekierowanie tymczasowe; lepsze podczas testów i wdrożeń.

W realnych wdrożeniach częstą praktyką jest uruchomienie nowej reguły jako 302, sprawdzenie zachowania (logi, analityka, brak pętli), a dopiero później zmiana na 301.

Debugowanie: logi i narzędzia

Jeśli masz dostęp do logów serwera, szukaj informacji w access.log i error.log. Przy trudniejszych przypadkach pomocne jest użycie narzędzi klienckich:

  • curl -I https://twojadomena.pl/sciezka – pokazuje nagłówki, kody 301/302 i Location,
  • curl -IL … – podąża za przekierowaniami i ujawnia, czy jest więcej niż jeden skok,
  • narzędzia deweloperskie w przeglądarce (zakładka Network) – pozwalają zobaczyć łańcuch przekierowań.

Jeśli hosting korzysta z dodatkowej warstwy (CDN, proxy, panelowe „wymuś SSL”), pamiętaj, że przekierowania mogą dublować się z tym, co robisz w .htaccess. W takim przypadku najlepiej zdecydować, gdzie trzymać logikę: albo w panelu hostingu/CDN, albo w Apache – aby uniknąć konfliktów.

Przykładowe, praktyczne zestawy reguł .htaccess

Wersja kanoniczna: HTTPS + bez www w jednym kroku

Poniższy zestaw robi jedno przekierowanie do wersji https://twojadomena.pl/… niezależnie od tego, czy użytkownik wszedł po HTTP lub z www:

RewriteEngine On

RewriteCond %{HTTPS} !=on [OR]

RewriteCond %{HTTP_HOST} ^www\.twojadomena\.pl$ [NC]

RewriteRule ^ https://twojadomena.pl%{REQUEST_URI} [R=301,L]

To dobry przykład „porządkującej” reguły, często wdrażanej na początku pliku .htaccess.

Usunięcie końcowego slasha (bez psucia katalogów)

Jeśli chcesz, aby adresy kończyły się bez „/” (np. /kontakt zamiast /kontakt/), ale jednocześnie nie chcesz łamać działania prawdziwych katalogów:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.+)/$ $1 [R=301,L]

Warunek !-d pilnuje, aby nie usuwać slasha dla istniejących katalogów na dysku.

Dodanie końcowego slasha (gdy aplikacja tego oczekuje)

Odwrotny wariant, przydatny w niektórych konfiguracjach CMS lub gdy chcesz jednolity styl URL:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_URI} !(.*)/$

RewriteRule ^(.+)$ $1/ [R=301,L]

Tu kluczowe jest wykluczenie plików (!-f), aby nie dopisywać slasha do nazw typu style.css.

Mapowanie parametrów na „ładny” adres

Jeśli masz stary schemat /produkt.php?id=123 i chcesz używać /produkt/123, możesz zrobić dwie rzeczy: przepisywanie do starego skryptu oraz przekierowanie ze starego URL do nowego. Przepisanie (aplikacja nadal używa produkt.php):

RewriteEngine On

RewriteRule ^produkt/([0-9]+)/?$ produkt.php?id=$1 [L,QSA]

Użytkownik widzi /produkt/123, a serwer pod spodem uruchamia produkt.php?id=123.

Blokada wywołań podejrzanych ścieżek (prosty „brudny ruch”)

Na hostingach współdzielonych często widać skany botów na /wp-admin, /phpmyadmin, pliki backupów itd. mod_rewrite potrafi je ucinać:

RewriteEngine On

RewriteRule ^(phpmyadmin|pma|wp-config\.php|\.git) – [F,L,NC]

To rozwiązanie proste, ale czasami zaskakująco skuteczne w zmniejszaniu „szumu” w logach. W rozbudowanych przypadkach lepiej użyć narzędzi typu fail2ban, WAF lub reguł na poziomie serwera/proxy.

mod_rewrite a alternatywy: kiedy warto, a kiedy lepiej użyć czegoś innego

Choć mod_rewrite jest potężne, nie zawsze jest najwygodniejsze:

  • Dla prostych przekierowań pojedynczych ścieżek często czytelniejsze jest użycie Redirect/RedirectMatch z mod_alias.
  • Jeśli aplikacja ma własny routing, wiele zmian URL można realizować w warstwie aplikacji (np. w frameworku), a mod_rewrite ograniczyć do front controllera i kanonikalizacji domeny/protokołu.
  • Na serwerach Nginx nie używa się .htaccess – tam analogiczne rzeczy robi się w konfiguracji serwera (rewrite, return 301, try_files). Przy migracji hostingu z Apache na Nginx trzeba reguły przetłumaczyć.

W środowiskach hostingowych mod_rewrite pozostaje jednak standardem, bo działa „blisko” serwera WWW i pozwala szybko reagować na potrzeby: od SEO i porządkowania adresów po awaryjne przekierowania podczas utrzymania.

Dobre praktyki układania reguł

  • Ustal jedną strategię adresów (kanoniczny host, protokół, slash/no-slash) i realizuj ją możliwie jedną regułą.
  • Testuj nowe reguły najpierw jako 302, dopiero później zamieniaj na 301.
  • Dodawaj wyjątki dla istniejących plików i katalogów, jeśli stosujesz reguły „łapiące wszystko”.
  • Unikaj skomplikowanych wyrażeń regularnych, jeśli można to zrobić prościej – ułatwia to utrzymanie na hostingu.
  • Pamiętaj, że kolejność reguł ma znaczenie: reguły bardziej szczegółowe zwykle powinny być wyżej niż ogólne.
  • Kontroluj łańcuch przekierowań; każdy dodatkowy skok to opóźnienie i potencjalne problemy z cache.

Umiejętnie użyte przekierowania i przepisywanie URL w Apache potrafią uprościć administrację serwisem, poprawić strukturę adresów, ułatwić migracje na nowy hosting oraz zwiększyć spójność działania strony. Z drugiej strony, kilka niepozornych linijek w .htaccess może wywołać pętle, błędy 500 lub nagłe problemy z dostępnością. Dlatego najlepsze rezultaty daje podejście: proste reguły, konsekwentna kanonikalizacja, testy na kopii serwisu oraz regularna kontrola logów.