mod_rewrite
aneb pěkná URL
Jedním z nejpoužívanějších modulů pro Apache je mod_rewrite
, komplexní systém pro přepis či manipulaci s URL. Tento doplněk je využíván, v některých případech i přímo vyžadován řadou webových aplikací. I když jsou jeho možnosti velmi široké a je možné jej použít k mnoha účelům, nejčastěji je užíván pro tvorbu „pěkných“ URL, tzn. skrývání standardních mechanismů pro předávání parametrů webové aplikaci tak, aby URL vypadalo „pěkně“ a bylo přátelské pro roboty vyhledávačů (SEO). Pro představu, URL využívající standardního mechanismu pro předávání parametrů webové aplikaci vypadá třeba takto:
http://www.example.com/index.php?nazev_clanku=sprava_linuxoveho_serveru
Modul rewrite
umožňuje příslušný parametr korektně předat webové aplikaci, přičemž však navenek využívá úplně jiné URL, např.:
http://www.example.com/clanky/sprava_linuxoveho_serveru.html
Jak to vlastně funguje? Pravidlo pro přepis umí „přeložit“ výše uvedený příklad pěkného URL na původní, klasický tvar s parametrem pro index.php
, kde může sídlit jádro webové aplikace. Webové aplikace se pak obvykle postarají o to, aby generovaly správná, „pěkná“ URL, přičemž spoléhají na webový server, aby tato „pěkná“ URL přeložil interně do takové podoby, kterou očekává daná webová aplikace.
Pravidla pro mod_rewrite
je možné specifikovat jak v rámci konkrétního virtuálního webu, tak v souboru .htaccess
, který umožňuje (pokud je to povoleno) upravit konfiguraci webového serveru pro daný adresář a podadresáře. Tento soubor naleznete jako součást mnoha webových aplikací.
Modul rewrite
není ve výchozí konfiguraci Apache v Debianu aktivován, je tedy třeba jej nejprve povolit, takto:
a2enmod rewrite /etc/init.d/apache2 restart
Pro fungování modulu rewrite
jsou stěžejní čtyři direktivy: RewriteEngine
, RewriteBase
, RewriteCond
a RewriteRule
. Aby přepis URL fungoval, je třeba jej nejprve zapnout, buď na úrovni konfigurace daného virtuálního webu, nebo na úrovni .htaccess
:
RewriteEngine on
Poté je možné použít ostatních direktiv. Při nasazení webových aplikací na server budete patrně nastavovat hodnotu direktivy RewriteBase
, která upraví výchozí URL pro samotný přepis. Kupříkladu, pokud budete instalovat aplikaci do /appl
na web (tzn. URL aplikace bude např. http://www.example.org/appl
), specifikujete jako hodnotu v RewriteBase
právě /appl
. Toto umístění pak bude tvořit základnu pro všechny přepisy, které specifikujete pomocí RewriteCond
a RewriteRule
.
Samotný přepis URL je realizován pomocí určité podmínky (nebo podmínek), za kterých přepis nastane (ty jsou specifikovány pomocí direktivy RewriteCond
), a jednoho nebo více pravidel pro samotný přepis (k tomu slouží direktiva RewriteRule
). Syntax a možnosti obou direktiv jsou velice bohaté, já se omezím pouze na jediný příklad a odkážu vás v odkazech pod článkem na další zdroje, kde se dozvíte více.
RewriteCond %{HTTP_HOST} ^([^.]+)\.([^.]+)$ RewriteRule ^(.*)$ http://www.%{HTTP_HOST}$1 [L,R=301,QSA]
Výše uvedené pravidlo demonstruje, že mod_rewrite
můžete použít nejenom k zajištění pěkných URL, ale pro řadu jiných situací. Toto pravidlo vytvoří přesměrování na doménový tvar s „www“, pokud klient zadá do prohlížeče pouze doménu druhého řádu. Tzn. pokud klient zadá do prohlížeče třeba "example.com/index.html
", toto pravidlo prohlížeči vrátí přesměrování (HTTP kód 301) na URL "http://www.example.com/index.html
". V podmínce vidíte na prvním místě definici proměnné k porovnání, v tomto případě HTTP_HOST
, serverová proměnná obsahující hostname v HTTP požadavku. Hodnota se porovnává s regulárním výrazem (v syntaxi Perlu) specifikovaným jako druhý parametr RewriteCond
. Tento regulární výraz zachytí hostname obsahující pouze jednu tečku, tedy doménu druhého řádu. Pokud klient specifikuje libovolnou doménu třetího řádu, pak pravidlu nevyhoví a přepis se neprovede.
Samotné pravidlo pro přepis specifikované v RewriteRule
obsahuje na prvním místě regulární výraz, který bude aplikován na vstupní hodnotu RewriteRule
, což je u prvního pravidla samotná URL cesta (cesta relativní k DocumentRoot
), u dalších pravidel by to pak byl výstup z předchozího pravidla. V příkladu výše by to bylo /index.html
(z http://example.com/index.html
). Na druhém místě je řetězec pro substituci, který nahrazuje původní URL cestu. Na třetím místě, v hranatých závorkách, jsou značky (flags). Ty jsou zde tři, a sice značku „L“, která označuje poslední pravidlo, tzn. po tomto přepisu se již nebudou provádět žádná další pravidla, dále značku „R=301“ označující přesměrování pomocí kódu 301 (moved permanently), a QSA (query string append), která zajistí, že se na konec URL připojí i „query string“, tj. případný kus zdrojového URL začínajícího otazníkem. Dolar a jednička v URL se vztahuje k regulárnímu výrazu, který je aplikován na vstupní hodnotu RewriteRule
, zde bude odpovídat celé cestě relativní k DocumentRoot
, tedy v příkladu výše /index.html
.
mod_chroot
Tento modul je jednou z možností, jak do jisté míry zvýšit bezpečnost. Funguje tak, že uzavře Apache v chrootu, tedy v adresáři, který si zvolíte a který se pro Apache stane kořenovým adresářem. V takovém případě, i kdyby se útočník dostal přes nějakou zranitelnost v Apachi dál, bude uzavřen v izolované oblasti, ze které se nedostane do zbytku systému (dostane se ovšem k webovým prezentacím). Tolik teorie, i když je rozhodně nutné dodat, že bezpečnost chrootu není v žádném případě neomezená (např. proces s rootovskými právy se může z chrootu dostat).
Příslušný modul naleznete v balíčku libapache2-mod-chroot
, po jehož instalaci jej aktivujte obvyklým způsobem:
a2enmod mod_chroot /etc/init.d/apache2 restart
V tuto chvíli se kromě samotného zavedení modulu ještě nic nestalo, neboť chroot je potřeba nejprve nakonfigurovat, a to direktivou ChrootDir
, kterou můžete umístit třeba do /etc/apache2/httpd.conf
. Jejím parametrem je adresář, který se pro Apache stane kořenovým:
ChrootDir /var/www
Při implementaci chrootu se budete potýkat s řadou problémů, které jsou s ním spojené. Prvním problémem je umístění souboru s PID Apache, který Apache umisťuje do /var/run
. Pokud se však kořenovým adresářem stal /var/www
, pak se Apache snaží umístit tento soubor do /var/www/var/run
(který ve vašem systému patrně neexistuje). Tento adresář je tedy potřeba vytvořit.
Dalším problémem je nutnost změny konfigurace virtuálních webů, zejména veškerých direktiv DocumentRoot
. Možným rychlým řešením je vytvoření symbolického odkazu /var/www/var/www
, který bude ukazovat na kořenový adresář, tedy /:
ln -s / /var/www/var/www
Po vyřešení těchto dvou problémů by se vám mělo podařit Apache spustit a vaše weby by měly fungovat, tedy alespoň ty statické, popřípadě ty, které využívají mod_php
. Pokud budete chroot takto provozovat, jistě se setkáte se situací, kdy vaší webové aplikaci bude chybět něco, co se nachází mimo chroot. V té chvíli vám nezbude než potřebné soubory překopírovat do chrootu.
Posledním problémem, na který vás upozorním, je problém s ukončováním a restartem Apache. Je to dáno tím, že PID soubor se přesunul, ale init-skript v /etc/init.d/apache2
jej očekává ve /var/run
. To můžete vyřešit opět symbolickým odkazem:
ln -s /var/www/var/run/apache2.pid /var/run/apache2.pid
V zásadě, použití chrootu má potenciál zvýšit bezpečnost vámi provozovaného webového serveru, ale za cenu možných problémů, na které patrně narazíte, pokud neprovozujete pouze statické weby. Na úplný závěr ještě zmíním alternativy, kterými je jistě mechanismus suexec
a bezpečnostní řešení na úrovni jádra, jako je SELinux, AppArmor, Tomoyo apod.