Linux E X P R E S

Facebook

Konfigurace a optimalizace Apache - dokončení

O nesporných kvalitách HTTP serveru Apache ví téměř každý, kdo se pohybuje v oblasti webhostingu a webových technologií obecně. Přesto tyto kvality často zůstávají zbytečně nevyužity - přestože stačí tak málo. Vhodným nastavením můžeme poměrně snadno získat vyšší výkon, nové funkce nebo lepší využití těch stávajících. Bylo by chybou nesnažit se vytěžit z tohoto vynikajícího serveru maximum.


MIME

Standard MIME (podle RFC 2045, 2046 a dalších) představuje u HTTP serveru výborný nástroj, jak určit druh obsahu (přestože některé prohlížeče mají tendenci toto určení ignorovat). MIME typ dat posílá server v HTTP hlavičkách a lze to do značné míry ovlivnit konfigurací. O obsluhu se stará modul mod_mime.

Za normálních okolností je MIME typ určen z přípony (např. image/jpeg ze souboru obrazek.jpg). Pokud je přípon více, vstupuje do hry ještě handler, např. pro výběr jazyka (přípony en, cs apod.), ale na pořadí přípon nezáleží. Pokud výběr podle přípony není úspěšný, může vypomoci ještě modul mod_mime_magic, pokud je povolen (určením souboru direktivou MimeMagicFile) - ten zkusí správný typ zjistit z obsahu souboru. Jako poslední záchrana se použije typ určený direktivou DefaultType (a pokud ta chybí, pak text/plain).

Handler je mechanismus nakládající s obsahem přenášeným klientovi. Kromě standardního handleru lze používat i řadu jiných, např. send-as-is (posílá data beze změny, včetně HTTP hlaviček) nebo cgi-script (naloží s daty jako s CGI skriptem).

Podíváme se na několik důležitých věcí. První je přidávání typů (lze i odebírat). Mapování z přípon na typy Apache načte ze souboru určeného v direktivě TypesConfig (obvykle se využívá soubor /etc/mime.types). Ten ale nemusí obsahovat některé méně obvyklé typy - a protože bychom je chtěli správně identifikovat, přidáme je přímo do konfigurace (třeba jen pro jediný adresář):

AddType image/jpeg jfif jfi

Podobně lze přidávat (a odebírat) i tzv. filtry. Máme filtry vstupní a výstupní - většinou nás zajímají spíše ty výstupní. Nejčastějším filtrem je totiž "on-the-fly" komprese dat. Používá se např. takto (zapne kompresi pro soubory s příponami .html a .xml):

AddOutputFilter DEFLATE html xml

Nastavováním filtrů se zabývají také direktivy SetOutputFilter, SetInputFilter a AddOutputFilterByType (všechny ze základního modulu Apache), ale doporučuji používat spíše ty z modulu mod_mime. Podobně lze přidávat i znakové sady, jazyky a handlery.

Optimalizace výkonu

Ve výchozím nastavení je server nakonfigurován kompromisně. Tedy pro dostatek funkcí, rozumnou stabilitu a dobrý výkon. Lze z něj ale získat mnohem víc, pokud vyjdeme z aktuálních potřeb a vyladíme ho právě pro konkrétní účel.

Obecná doporučení

Vytvořte zvláštní oddíl pro uložení dat. Nejlépe je mít pro webová data samostatný disk, nebo aspoň jiný, než kde je umístěn odkládací oddíl. Na příslušném datovém oddílu doporučuji vypnout záznam posledního času přístupu (mount volba noatime), pokud není nějaký zvláštní důvod ho ponechat zapnutý.

Vypněte všechny nepotřebné moduly Apache - nechte pouze ty, které se skutečně používají. Volbu UseCanonicalName ponechte na Off (pro virtuální servery to stejně bude potřeba). Podobný, ale ještě mnohem větší význam má vypnutí zpětných překladů klientských adres (tedy: HostnameLookups Off).

Pokud používáte řízení přístupu (Allow a Deny), používejte co nejjednodušší pravidla a namísto jmenných adres používejte IP adresy. Vyhýbejte se používání symbolických odkazů, a pokud už je používáte, zapněte jejich následování volbou FollowSymlinks, a nikoli SymLinksIfOwnerMatch.

Značnou brzdou je používání souborů .htaccess. Pokud to není nezbytně nutné, nepoužívejte je a jejich používání zakažte (AllowOverride None).

Logování

Vypnutí logování přístupů by sice zvýšilo výkon, ale výrazně by zkomplikovalo řešení případných technických problémů (nehledě na případné právní důsledky - viz Bezpečnostní aspekty), proto nemá smysl se k němu uchylovat. Úroveň chybových záznamů (LogLevel) nastavíme na error, při menší důvěře v systém na warn. Doplňkové logovací soubory (např. pro referrery) nepoužíváme, lepší je tyto informace zahrnout do běžného logu (např. v podobě formátu combined). Taktéž je vhodné vypnout (nezapínat) záznamy modulu Rewrite a skriptů CGI.

(Pseudo)paralelní zpracování

V Linuxu lze momentálně používat dva modely pro paralelní (pseudoparalelní) zpracování. Je to původní "procesový" model (prefork) a dále pak nový "vláknový", resp. hybridní (worker). Vláknový je ve většině případů rychlejší, ale řada modulů Apache s ním není kompatibilní, takže buď nefungují vůbec, nebo se mohou chovat podivně.

V nové verzi 2.2 byl do Apache přidán další model pro paralelní zpracování - event. Výrazně zlepšuje obsluhu perzistentních spojení, protože procesy/vlákna nezůstávají nečinně "viset" na otevřených socketech. Zatím se jedná o výrazně experimentální záležitost, nevhodnou pro vážnou práci.

Mezi takové moduly patří bohužel i PHP (v distribuční podobě nejde ani spustit, kompilované ze zdrojáků sice ano, ale často padá), což je velice nepříjemné. Proto v tuto chvíli lze vláknový model (spustitelný soubor má na FC 4 název httpd.worker) doporučit pouze pro experimentální účely - pro produkční nasazení se mnohem lépe hodí osvědčená procesová verze.

Velice ale záleží na konfiguraci. Podíváme se na ni blíže a pak uvedu i výsledky provedeného experimentu. Nejprve se vypořádáme s perzistentním spojením, které jsem na začátku doporučoval. Pokud server slouží klasickým účelům (tedy poskytování HTML dokumentu + souvisejících objektů), je většinou lepší ho nechat zapnuté (případně ale upravit timeout a počet požadavků - direktivami KeepAliveTimeout a MaxKeepAliveRequests). Pokud ale provozujeme např. download server (stahují se jednotlivé soubory), zbytečně by ubíralo prostředky, proto ho vypneme.

Dále tu máme nastavení počtu požadavků (resp. relací), které jeden serverový proces během svého života obslouží. Je to direktiva MaxRequestsPerChild. Výchozí hodnotu můžeme většinou bez problémů ještě podstatně zvýšit, klidně na desítky tisíc. Opatrnost v nastavení pochází z dob, kdy kvůli chybám v implementaci docházelo hlavně na některých platformách k únikům paměti.

Klíčovým nastavením, ale současně nejsložitějším, je nastavení počtu procesů. Nejprve vyladíme hodnotu MaxClients - ta říká, kolik obslužných procesů smí maximálně běžet. Nastavíme ji tak, aby systém nemusel swapovat (spíš s rezervou). Není to jednoduché, protože předem nevíme, kolik paměti budou procesy potřebovat. Asi nejlepší je nastavit nějakou hodnotu, pak provést test s typickou zátěží, spočítat průměrnou náročnost jednoho procesu, a podle toho hodnoty upravit.

Druhým krokem je konfigurace rezervy procesů - tedy určení, kolik nejméně a nejvíce nevyužitých procesů má být k dispozici, a také kolik procesů spustit při startu. Opět to chce experimentovat. Dobrou pomůckou je monitorování stavu serveru z prohlížeče pomocí handleru poskytovaného modulem mod_status.

Virtuální servery

Máme-li velké množství unifikovaných virtuálních serverů (vytvářených pomocí VirtualDocumentRoot), není příliš moudré, aby byly všechny uloženy v jednom adresáři - procházení takového adresáře je zbytečně zdlouhavé. Místo toho využijeme možnosti servery rozptýlit.

Direktiva VirtualDocumentRoot nám k tomu poskytuje dostatečné prostředky. Můžeme používat adresáře např. podle počátečního písmena domény. Při skutečně velkém počtu serverů lze jít i do několika úrovní. Zde je příklad takového nastavení:

VirtualDocumentRoot /var/www/vhosts/%-2.1/%-2.2/%-2.0.%-1.0/

Tímto bychom získali dvě úrovně podle prvních dvou písmen domény (tedy pro doménu linuxexpres.cz by to bylo /var/www/vhosts/l/i/linuxexpres.cz/).

Bezpečnostní aspekty

Když se hovoří o bezpečnosti, lze si pod tím představit leccos. Od hledisek stability, odolnosti a zabezpečení serveru proti místním i dálkovým útokům až po bezpečnostní služby poskytované umístěnému obsahu. O tom všem bude řeč - navíc trochu zabrousíme i do oblasti českého práva v souvislosti se záznamem komunikačních dat.

Nastavení přístupových práv

Apache se typicky spouští s právy roota (kvůli použití privilegovaného portu 80), kterých se vzápětí zbaví. Uživatel a skupina se nastaví (direktivami User a Group) na hodnoty uvedené v konfiguraci. Běžně není důvod nastavení měnit - ale pokud už k tomu nějaký důvod nastane, nikdy se jako uživatel nebo skupina nesmí nastavit root! Mnohem častěji se ale nastavují tyto parametry pro spouštění programů CGI. Virtuální servery mohou mít vlastní nastavení, proto lze snadno separovat práva vlastníků jednotlivých serverů. K nastavení slouží direktiva SuexecUserGroup.

Jinak snad není třeba zdůrazňovat, že všechny soubory a adresáře používané serverem Apache by měly mít nastavena nejmenší použitelná práva. Ostatně, při instalaci v rámci linuxové distribuce se to většinou provede automaticky.

Na co si dát pozor

Spouštění Apache s rootovskými právy přináší několik závažných skutečností. Jednou z nich je, že se logy otevírají ještě s rootovskými právy. To je nebezpečné v případě, že výstup posíláme do roury. Cílový program se totiž spustí také s právy roota, což není příliš bezpečné. Je proto žádoucí, aby se takový program svých práv zbavil, a to co nejdříve po spuštění.

Druhé riziko plyne ze samotného Apache - pokud by obsahoval chybu (např. typu buffer overrun), mohlo by to mít dalekosáhlé důsledky. Tím nechci říct, že takovou chybu obsahuje, jen si dovoluji připomenout nutnost pravidelné aktualizace.

Jiný druh rizika plyne ze způsobu práce se souborovým systémem. Pomocí symbolického odkazu se lze dostat v adresářovém stromě kamkoliv. Tomu lze zabránit zákazem přístupu definovaným v sekci pro kořenový adresář (ve výchozím nastavení to tak je). Na druhou stranu, když někdo linkuje na nějaký soubor a diví se, že to nefunguje, často si nevzpomene, že je to způsobeno právě tímto zákazem. Stačí přidat záznam pro konkrétní sekci, tam přístup povolit a vše začne fungovat.

Autentizace a autorizace

První úroveň je povolování/zakazování přístupu z určitých adres nebo sítí. Pracujte vždy raději s IP adresami místo jmenných, a to jak z důvodu bezpečnosti (pharming a další útoky), tak kvůli vyššímu výkonu. Navíc berte v úvahu, že je to (kvůli proxy serverům) velice slabý nástroj - rozumné použití se pohybuje pouze v rovině místní adresa/místní síť/všechno ostatní. A to ještě jen v případech, kdy nejsou velké nároky na zabezpečení.

Pharming je využití chyby v DNS serveru takovým způsobem, že cracker přesměruje záznamy na tomto serveru (doslova jej "zamoří") na jiné počítače tak, aby mohl provést útok man in the middle, případně využít situace ke svému prospěchu.

Man in the middle (doslova muž uprostřed komunikace) je útok, při kterém cracker nastaví svůj systém tak, aby se choval naprosto stejně jako systém, do kterého se uživatel hlásí a se kterým pracuje. Typicky se snaží cracker získat například heslo a scénář může být úplně prostý. Na svém WWW serveru vytvoří například věrnou kopii přihlašovací obrazovky a nějakým způsobem (např. modifikací DNS záznamu) přinutí uživatele, aby se na WWW server připojil a pokusil se přihlásit. Systém může například odpovědět, že je v poruše a heslo uložit. Vhodnou obranou proti MITM je ověřování pravosti systémů, například technologií SSL a certifikáty.

K povolování a zakazování se používají direktivy Allow a Deny (umísťované typicky do sekcí adresářů). Viz příklad:

Order Deny,Allow
Allow from 127.0.0.1
Allow from 10.0.0
Deny from all

Povolujeme přístup z místní adresy a ze sítě ve vyhrazeném prostoru - všechno ostatní je zakázáno. Pozor ale, aby poslední pravidlo nevypadlo. V tomto pořadí (direktiva Order) je totiž implicitně povolen přístup odkudkoli. Při vyšších požadavcích na bezpečnost lze použít HTTP autentizaci. Není to nejlepší řešení, ale k jeho použití nepotřebujeme (kromě Apache a jeho modulů) nic dalšího. Zdaleka nejrozšířenější je metoda Basic, i když ji zvolna vytlačuje lepší metoda Digest (viz RFC 2617). HTTP autentizaci můžeme ovládat i přes .htaccess soubory, pokud je to v konfiguraci povoleno. Nejprve příklad:

AuthType Basic
AuthName "abcd - oblast s omezenim pristupu"
AuthUserFile /var/www/passwd/passwords
Require user uzivatel1 uzivatel2 uzivatel3

Název autentizace se zobrazuje v dialogu v browseru, také podle něj prohlížeč může rozhodovat, které z údajů (z těch, které má k dispozici) bude posílat. Důležitý je údaj o autentizačním souboru - obsahuje jména a hesla uživatelů a spravuje se utilitou htpasswd. Konečně poslední řádek uvádí seznam uživatelů, kteří mají do oblasti přístup. Lze uvést i valid-user pro všechny uživatele uvedené v daném souboru.

Pokud potřebujeme trochu silnější nástroj na autentizaci, přidáme práci se skupinami (přístup mají členové určité skupiny). Vypadalo by to takto:

AuthGroupFile /var/www/passwd/groups
Require group Uzivatele

Soubor skupin obsahuje seznam uživatelů pro každou skupinu. Přístup můžeme samozřejmě povolit více skupinám najednou. Uvedené příklady se týkaly metody Basic, pro metodu Digest by se mírně lišily.

SSL

Apache pro účely SSL využívá knihovnu OpenSSL. Z toho samozřejmě vyplývá, že případné chyby nalezené v této knihovně se projeví i zde.

Tuto část bych zahájil příkladem, který následně vysvětlím:

SSLEngine On
SSLProtocol -all +SSLv3
SSLCipherSuite SSLv3-LOW
SSLRequireSSL
SSLVerifyClient require

Nejprve SSL zapneme. Druhý řádek říká, že se má použít pouze protokol SSL 3. Na třetím řádku určujeme použitelné šifrovací algoritmy - v tomto případě všechny, které podporuje SSL 3, ovšem kromě slabých šifer. Pak tu máme vynucení použití SSL (zákaz přístupu do oblasti bez použití SSL) a konečně poslední řádek říká, že je nutné ověřit totožnost klienta.

SSLCertificateFile conf/ssl.crt/server.crt
SSLCertificateKeyFile conf/ssl.crt/server.key
SSLCACertificatePath conf/ssl.crt/ca/
SSLCARevocationPath  conf/ssl.crt/rev/

Tyto direktivy udávají umístění důležitých souborů. V prvním případě jde o certifikát serveru, na druhém řádku je cesta k soukromému klíči serveru. Druhé dvě direktivy nastavují umístění certifikátů certifikační autority (pro ověřování klientských certifikátů), resp. seznam odvolaných certifikátů.

Pro SSL lze konfigurovat ještě řadu dalších věcí (logování, SSL cache, dialog pro zadání hesla serveru apod.). Zájemce odkazuji na dokumentaci.


Výlet do českého práva

Zákon 127/2005 Sb. o elektronických komunikacích ukládá provozovatelům veřejných komunikačních služeb (kam patří např. i veřejný webhosting), aby ukládali provozní a lokalizační údaje a na vyžádání je poskytli oprávněným orgánům. Rozsah stanovuje vyhláška 485/2005 Sb.

I když je to nepříjemné, ten, koho se to týká, by měl ve vlastním zájmu tato pravidla respektovat. Z hlediska nastavení Apache to znamená v podstatě jen to, aby se logovaly všechny informace požadované vyhláškou a aby se logy uchovávaly šest měsíců.

Vzhledem k tomu, že výchozí formát logu (common) náležitosti splňuje (formát combined samozřejmě taktéž), není třeba si s tím dělat starosti. Jen ten, kdo by chtěl používat svůj vlastní formát, by si měl zkontrolovat, zda obsahuje vše podstatné.


Hodně štěstí!

Apache je velice rozsáhlý program. Svědčí o tom i to, že o něm byla napsána řada knih, každá s rozsahem stovek stránek - a přesto nebylo vše vyčerpáno. Proto jsem si ani v tomto článku nemohl klást za cíl dokonalé seznámení s tímto silným prostředkem. Spíše jsem chtěl vzbudit zájem o poznání a využití některých méně známých schopností Apache a samozřejmě o lepší porozumění těm známějším.

Pochopit funkce Apache znamená věnovat mu hodně času a úsilí. Nebude to zbytečná námaha, Apache ji dokáže kvalitně odměnit. Ne nadarmo je nejoblíbenějším webovým serverem na světě.



Diskuze (0) Nahoru