Konfiguracja PHP na serwerach

Jednym z najczęstszych problemów z jakim można się spotkać w rozmowie na linii administrator – programista jest dyskusja związana z działaniem PHP. Nawet nie liczę ile razy tłumaczyłem, że PHP może mieć wiele różnych konfiguracji i to, że skrypt zadziała na jednym serwerze nie znaczy, że zadziała wszędzie. Nie ma lepszego czy gorszego sposobu na konfigurację PHP. Każdy z nich ma swoje plusy i minusy. Co ciekawe, nawet na tym samym serwerze wchodząc przez przeglądarkę i wywołując plik z konsoli za pomocą polecenia php uruchamiamy PHP w zupełnie inny sposób.

PHP-FPM, CLI, CGI itd.

Jednym z problemów, jaki może wystąpić podczas rozmowy z klientem, jest polecenie, żeby zrobić konfigurację na serwerze tak, jak ma developer u siebie, a jednocześnie jak w panelach administracyjnych typu Direct Admin. I tutaj nie mam pretensji do klienta. W końcu on ma się skupić na biznesie, a ja na działaniu serwera. Problem w tym, że na to nie ma jednego standardu. A i sam panel Direct Admin podczas instalacji pyta, który template instalacji chcemy wybrać. Dlatego postanowiłem opisać kilka możliwości konfiguracji nie od strony jak to zrobić, ale jakie to pociąga za sobą konsekwencje.

Apache modułem mod_php

Jest to najczęściej spotykana konfiguracja na komputerze developera. Jest najprostsza pod względem konfiguracji i jednocześnie, z racji integracji z apache, ma dość wysoką wydajność. Można też ją spotkać na serwerach gdzie działa jedna strona. Główną cechą takiej konfiguracji jest to, że PHP działa na niej na uprawnieniach serwera apache (czyli np. www-data). Jeżeli na serwerze mamy jedną stronę umieszczoną w katalogu głównym serwera apache (/var/www/html lub /var/www zależnie do dystrybucji) jest to całkiem dobre i szybkie rozwiązanie. Tak samo jest dla pakietów typu phpmyadmin czy roundcube. Niestety, w przypadków gdzie na serwerze mamy wiele stron, a co za tym idzie – wielu użytkowników, zaczynają się problemy. Ponieważ strona ma uprawnienia użytkownika strony (czyli np. user1), a PHP działa jako www-data mogą pojawić się problemy z uprawnieniami. Najczęściej rozwiązuje się to poprzez danie katalogowi uprawnienia 777, ale jest to mało bezpieczne. Przy wielu użytkownikach musimy wtedy stosować dodatkowe zabezpieczenia typu open_basedir. To z kolei powoduje, że musimy dać każdemu użytkownikowi osobny plik php.ini. Z punktu widzenia bezpieczeństwa takie rozwiązanie ma jednak także pewien plus. Jeżeli ktoś wgra nam do katalogu upload plik z własnym kodem php, nie będzie mógł zmodyfikować plików php strony nie będących własnością serwera apache. Jest to marny plus, ale potrafiło to utrudnić życie włamywaczom. Niestety open_basedir nie zabezpiecza nas przed dostępem w shellu do katalogu innego użytkownika. Dlatego też taka konfiguracja sprawdza się w developerce czy w szczególnych przypadkach, ale nie widuje się jej na hostingach. Inną istotną cechą tego trybu jest to, że po zmianie pliku php.ini musimy zrestartować serwer apache w celu odświeżenia konfiguracji. Dodatkowo, jeżeli mamy wielu użytkowników w systemie, to ciężko znaleźć konto które powoduje nadmierne obciążenie serwera, gdyż wszystkie procesy PHP widoczne są jako jeden użytkownik (zazwyczaj www-data).

CLI

Ten skrót oznacza Command Line Interface, co po polsku oznacza polecenie wykonane z konsoli. Do tego możemy zaliczyć zarówno polecenie php wykonane ręcznie, jak i uruchomione przez crona. Dodam, że jest różnica między takim wykonaniem. W przypadku Linuksa w konsoli używa się bash, a cron wykonuje plik z shella sh. Dlatego też w przypadku crona warto używać ścieżek bezwzględnych. Taką formę PHP mamy wszędzie, niezależnie od tego jak PHP jest wywoływane przez serwer webowy (apache, nginx). PHP przez CLI posiada osobny plik php.ini z powodu pewnych różnic w działaniu samego php w tym trybie (nie ma tutaj mowy np. o zdalnym IP). Dość częstym problem o jakim słyszę jest to, że gdy wywoła się php ze strony to działa, a z konsoli już nie. Najczęściej jest to spowodowane modyfikacją pliku php.ini w konfiguracji serwera webowego bez ruszania pliku php.ini dla CLI. W przypadku modyfikacji tego pliku nie trzeba nic przeładowywać, bo plik jest sprawdzany przy każdym odpaleniu polecenia php. Samo php jest tutaj uruchamiane na uprawnieniach użytkownika na którego jesteśmy zalogowani. Często występuje tu konflikt uprawnień, jeżeli używamy PHP jako moduł mod_php do apache.

PHP CGI/CGI

Z racji tego, że konfiguracja mod_php jest dość problematyczna, postanowiono jakoś problem rozwiązać za pomocą połączenia serwera webowego z mod_fastcgi, który wywołuje php jako osobny program. Nie jest jednak to dokładnie to samo co CLI (osobne pliki php.ini). Jest to dość dobre i często stosowane rozwiązanie na hostingach, jednak jest pomału zastępowane przez php-fpm. Wydajnościowo jest wolniejsze od mod_php w apache, ale za to rozwiązuje wiele problemów bezpieczeństwa. Każde wywołanie strony powoduje, że apache czy inny serwer webowy wywołuje polecenie php na uprawnieniach pliku php (czyli już nie mamy konfliktu uprawnień). Minusem tego rozwiązania jest tworzenie nowego procesu przy każdym wywołaniu i lekki problem z jednakowym plikiem php.ini dla wszystkich użytkowników. Da się ten problem jak najbardziej rozwiązać, ale wymaga to od nas dodatkowej konfiguracji. Zmiana konfiguracji pliku php.ini nie wymaga tutaj restartu niczego, gdyż podobnie jak w przypadku CLI, plik php.ini jest odczytywany przy każdym wywołaniu php.

PHP-FPM

Najnowszy sposób konfiguracji zdobywający rynek. Jeżeli mamy serwer webowy, serwer mysql, to dlaczego by nie stworzyć serwera PHP. Jest to rozwiązanie idealne dla dużych serwisów. Jest wydajne, ale przez swoją budowę też ma swoje minusy. Każdy dodatkowy użytkownik w systemie ma swoją konfigurację PHP (nie tylko osobno php.ini, bo to może, ale nie musi być wspólne). Dla każdego użytkownika określamy ile procesów PHP-FPM ma czekać (może to być wartość dynamiczna). Z jednej strony przyśpiesza to działanie PHP poprzez wbudowany cache dla samego serwera PHP-FPM, a z drugiej przy dużej ilości użytkowników systemowych powoduje duże zużycie pamięci RAM. Zmiana konfiguracji pliku php.ini albo pliku konfiguracji samego PHP-FPM wymaga od nas zrestartowania serwera PHP-FPM.

Wspólne problemy

Niezależnie od tego jak skonfigurowany jest serwer, musimy zdać sobie sprawę z pewnych zależności i problemów, jakie występują przy jakże popularnej platformie LAMP (Linux Apache Mysql PHP), ale też dotyczy się innych serwerów jak nginx.

Pliki statyczne są odczytywane przez serwer webowy, pliki PHP różnie.

W przypadku konfiguracji z mod_php pliki html i php są odczytywane i wykonywane przez użytkownika www-data. Oznacza to, że nikt w systemie naszych plików poza serwerem webowym nie odczyta. Jednak w przypadku innych rozwiązań powstanie problem i musimy dać pliki do odczytu minimum grupie apache, a najczęściej – wszystkim. Powoduje to problemy bezpieczeństwa. Trochę ratuje nas tutaj open_basedir, który ogranicza wykonywanie plików php do wskazanego katalogu. Jednak nie samym php człowiek żyje i mając dostęp do shella, da się odczytać pliki innych użytkowników. Oczywiście można to zabezpieczyć, ale domyślnie ustawieniu systemu są tutaj mało bezpieczne.

Zależnie od konfiguracji brane pod uwagę są rożne pliki php.

Najprostszym sposobem na sprawdzenie trybu pracy i tego, który plik php.ini jest brany pod uwagę, jest stworzenie pliku phpinfo.php z zawartością

<?php

phpinfo();

?>

Jednym z parametrów jest „Server API”, który powie nam, jaki tryb został użyty. Nie ma tutaj ścisłego rozróżnienia między FastCGI i FPM, bo oba z poziomu serwera webowego wywołuje się poprzez moduł mod_fastcgi. Drugi parametr „Loaded Configuration File” wskazuje nam, gdzie znajduje się plik php.ini. Oprócz tego parametr „Scan this dir for additional .ini files” pokazuje katalog z dodatkowymi konfiguracjami PHP.

Należy pamiętać o usunięciu pliku kiedy nie jest on potrzebny, bo zdradza światu sporo o konfiguracji serwera i jest chętnie wykorzystywany przez włamywaczy.

Dlaczego pewne funkcje są wyłączone na współdzielonym hostingu?

Domyślnie na serwerze programisty można niemal wszystko, ale to samo na serwerze już możne nie działać. Takie funkcje jak mail, passthru,shell_exec,system,proc_open,popen,pcntl_exec,pcntl_fork są często wyłączone, bo dzięki nim można obejść zabezpieczenia php, pozwalając odczytać więcej, niż powinien nasz użytkownik. W przypadku funkcji mail ciężko zlokalizować, kto tak naprawdę wysłał maila.

Moduły PHP

Domyślnie PHP nie ma wszystkiego dostępnego i mieć nie będzie. O ile na hostingach współdzielonych zainstalowane jest całkiem sporo, to na serwerze dedykowanym instaluje się tylko to, co jest wymagane (z powodów i bezpieczeństwa i wydajności). I dlatego programista powinien wiedzieć, jakie moduły PHP są wymagane na serwerze.

Scroll to top