Správa linuxového serveru: Konfigurace LAMP: PHP
V předchozím díle byla probrána instalace platformy LAMP (zkratka pro Linux, Apache, MySQL a PHP). Tento díl seriálu se bude věnovat základům konfigurace LAMP v prostředí Debianu, konkrétněji konfiguraci a možnostem zabezpečení PHP interpretu.

Úvod
Hlavním konfiguračním souborem PHP je php.ini, sídlící v adresáři /etc/php5/apache2. Všimněte si, že tento konkrétní konfigurační soubor je umístěn v podadresáři apache2. PHP interpret může mít odlišný konfigurační soubor pro různé typy použití, které jsou pak umístěny v podadresářích /etc/php5. Kupříkladu, pokud nainstalujete balíček php5-cli, který obsahuje interpret PHP pro příkazovou řádku, dojde k vytvoření konfiguračního souboru php.ini v adresáři /etc/php5/cli, který se použije v rámci tohoto interpretu. Jeho konfigurace tak bude oddělena od konfigurace PHP určené pro webový server Apache v umístění uvedeném výše.

PHP má řadu rozšíření (extensions), které jsou v Debianu k dispozici v podobě balíčků s prefixem php5-, popřípadě php-. Naleznete zde konektory k databázím (např. php5-mysql, php5-pgsql či php5-sqlite), rozšíření pro práci s obrázky (php5-gd a php5-imagick) a řadu dalších. Různé webové aplikace vyžadují nebo umí využít různá rozšíření, o čemž se obvykle dozvíte v jejich dokumentaci. Vhodnou strategií bývá instalovat rozšíření teprve, až když víte, že jej budete opravdu potřebovat.

php.ini
Konfigurační soubor php.ini je (nejen) v Debianu velmi dobře komentovaný, je tedy vhodné doporučit, abyste si jej celý prošli a nastavili podle svých požadavků. To platí dvojnásob, pokud konfigurujete produkční server. V souvislosti s tím vás raději znovu upozorním na to, že výchozí php.ini určený pro Apache je v Debianu nastavený spíše s ohledem na vývojové servery, nikoliv na produkční. Na produkčních serverech je vhodné konfiguraci upravit přinejmenším s ohledem na bezpečnost a na požadavky provozovaných aplikací. Debian Lenny nabízí php.ini určený pro produkční použití v /usr/share/doc/php5/examples/php.ini-recommended.

Samotná rozšíření pak naleznete jako samostatné .ini soubory v /etc/php5/conf.d, kde v některých případech naleznete kromě direktivy pro zavedení příslušného modulu i specifické konfigurační volby. V jednotlivých podadresářích s php.ini (např. /etc/php5/apache2) se pak nachází symbolický odkaz conf.d vedoucí na hlavní /etc/php5/conf.d, tzn. zavedení modulů je pro jednotlivé konfigurace společné, ale není problém symbolický odkaz nahradit adresářem, kde můžete sami rozhodnout, které moduly mají být v dané konfiguraci použity.

Mezi důležité konfigurační volby, kterým byste měli věnovat pozornost, patří následující:

expose_php přijímá jako parametr „On“ nebo „Off“ a umožňuje „skrýt“ přítomnost PHP v HTTP hlavičkách odpovědí webového serveru. Pokud je nastavena na „On“, ohlašuje Apache přítomnost PHP i verzi takto:

Server: Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny9 with Suhosin-Patch
Je-li volba expose_php nastavena na „Off“, přítomnost PHP není ohlašována vůbec:

Server: Apache/2.2.9 (Debian)
max_execution_time přijímá jako parametr čas v sekundách a určuje, jak dlouho může PHP skript běžet před tím, než bude násilně ukončen. Výchozí hodnotou je 30 (vteřin).

memory_limit přijímá jako parametr maximum paměti, kterou může PHP skript využít. Výchozí hodnotou je 128M, kde M znamená MB. Pokud skript požádá o více paměti, bude ukončen s chybou. Jak v případě volby max_execution_time, tak v případě této platí daná hodnota pro jeden běh skriptu, tedy jeden HTTP požadavek obsluhovaný PHP skriptem. Více požadavků naráz může tedy zabrat n-krát více paměti.

display_errors řídí zobrazování chyb a může nabývat dvou hodnot, „On“ nebo „Off“. Jeho výchozí hodnota je „On“, což představuje potenciální bezpečnostní problém - chyby, varování či hlášení v rámci běhu PHP skriptů se pak zobrazují v prohlížeči včetně některých možných zneužitelných informací (chybová hlášení při práci s databází atd.). Tuto volbu je tedy na produkčních serverech vhodné nastavit na „Off“. To, co se vlastně zobrazuje, tzn. zdali se zobrazují pouze chyby, nebo i varování a hlášení, řídí parametr error_reporting. Více k tomuto tématu naleznete např. v tomto článku.

display_startup_errors řídí zobrazování kritických chyb, ke kterým dochází při spouštění PHP skriptu. Nabývá stejných hodnot jako parametr display_errors, jeho výchozí hodnotou je „Off“ a na produkčních serverech doporučuji tuto hodnotu ponechat.

log_errors vám pomůže se k chybovým hlášením dostat, pokud vypnete jejich zobrazování. Nabývá hodnot „On“ nebo „Off“, přičemž hodnota „On“ zařídí logování chybových hlášení do chybového logu webového serveru. Pokud budete logování chybových hlášení povolovat, podívejte se i na další parametry ovlivňující logování, např. parametr ignore_repeated_errors, kterému nastavte hodnotu „On“, aby se zbytečně neplnil váš log opakovanými chybovými hláškami, či samotný výše zmíněný parametr error_reporting ovlivňující typy hlášení, na které se bude brát zřetel.

disable_functions umožňuje zakázat provádění jistých PHP funkcí ve skriptech, což může posloužit jako jedno z bezpečnostních opatření. Příkladem seznamu funkcí k zakázání může být tento:

disable_functions = shell_exec, exec, system, passthru, proc_close, proc_open, proc_get_status, proc_nice, proc_open, proc_terminate, shell_exec, dl, popen, pclose, chown, disk_free_space, disk_total_space, diskfreespace, fileinode, max_execution_time, set_time_limit, highlight_file, show_source, phpinfo, chgrp, symlink
Pokud budete tento parametr používat, dejte si pozor na funkce s obdobnou funkcionalitou, ale jiným názvem. Stejně tak doporučuji bezpečnostní dopad jednotlivých funkcí zvážit - v seznamu výše může být považována za diskutabilní např. funkce phpinfo, která „pouze“ umožňuje zobrazit podrobnou konfiguraci PHP.

allow_url_fopen a allow_url_include jsou vhodnými kandidáty na hodnotu „Off“. Umožňují v rámci některých funkcí určených pro práci se soubory získávat data z externích zdrojů (specifikováním URL místo cesty k souboru), což může posloužit k nejrůznějším útokům, pokud není v PHP aplikacích správně ošetřen uživatelský vstup (na což nebývá dobré se spoléhat).

open_basedir je Debianem označeno jako „defektní“ (broken) bezpečnostní opatření, a je tudíž v rámci Debianu nepodporované. open_basedir slouží k omezení operací se soubory na seznam adresářů uvedených jako hodnota této volby (adresáře je třeba oddělovat dvojtečkou). Pokud je tato volba ponechána jako neprázdná, nebude možné v rámci korektně ošetřených PHP funkcí použít cestu vedoucí mimo tyto adresáře (resp. použití takové cesty vyvolá chybu). Lepším (resp. jistějším) způsobem zabezpečení může být chroot na úrovni webového serveru (Apache má k tomuto účelu připraven modul chroot v balíčku libapache2-mod-chroot).

Na závěr výčtu důležitých voleb dodávám, že některé z výše uvedených navrhovaných změn mohou mít negativní dopad na některé PHP aplikace. Dodám také, že veškeré změny v php.ini se projeví teprve až se znovunačtením konfigurace webového serveru, tedy v případě Apache po vykonání příkazu:

/etc/init.d/apache2 reload
Staré a nepodporované volby
Ve výčtu důležitých konfiguračních voleb jsem vynechal dvě, které jsou obecně považovány za zastaralé (deprecated), nepodporované či dokonce za nebezpečné. Jejich výchozí hodnoty jsou obvykle nastaveny na „Off“ a bývá doporučeno je tak ponechat. Jedná se o volby register_globals a safe_mode. První z uvedených je dobře známá a historicky velmi kontroverzní funkce stojící za řadou bezpečnostních zranitelností, zatímco ta druhá je pokusem o zvýšení bezpečnosti na sdíleném hostingu, který se neujal, má některé problémy. Řada webových aplikací jej nemá ráda a je momentálně považován za zastaralý (deprecated) a nepodporovaný.

Dodatečné zabezpečení PHP: suhosin a suexec
Mezi dvě dodatečné možnosti zabezpečení PHP patří projekt Suhosin a nástroj (resp. modul) suexec. Projekt Suhosin se sestává jednak z bezpečnostního patche jádra PHP, který se snaží PHP interpret obrnit vůči některým typům útoků, a jednak z rozšíření PHP, které nabízí další možnosti zabezpečení. Interpret PHP v Debianu v sobě již Suhosin patch integruje, ale samotné rozšíření ve výchozí instalaci není. Toto rozšíření je k dispozici v balíku php5-suhosin. Po jeho instalaci budete mít k dispozici jeho konfiguraci v /etc/php5/conf.d/suhosin.ini. Samotnou konfigurací Suhosinu se tento díl zabývat nebude - pokud o toto téma máte zájem, podívejte se na odkazy v závěru článku.

Suexec je modul Apache určený k tomu, aby PHP skript běžel s oprávněními vlastníka daného webu. Tím je řešen bezpečnostní problém v konfiguraci s řadou webů (virtualhostů), kde průnik přes jeden z nich umožní útočníkovi dostat se i k ostatním. Suexec vyžaduje běh PHP v rámci Apache prostřednictvím CGI, tedy přesněji FastCGI. Toto řešení je popsáno třeba v tomto článku.