piątek, 23 października 2009

Konfiguracja Apachea

Domyślny plik konfiguracyjny serwera jest bardzo rozbudowany i warto z niego zrezygnować, tworząc jednocześnie od podstaw swój własny zbiór z ustawieniami. Z racji tego, że jest to dość trudne, warto posłużyć się tutaj gotowymi wpisami z oryginalnego pliku.

W tym miejscu skupimy się na kwestiach najbardziej istotnych, czyli parametrach, które mają wpływ na bezpieczeństwo systemu. Pierwszą opcją, o której już zresztą wspomnieliśmy, jest konto użytkownika, na którym działa serwer. Zakładamy więc, że opcje User i Group zostały już poprawnie ustawione.

Ograniczenie dostępu do konfiguracji serwera można wymusić przez zablokowanie użycia plików .htaccess. Pisaliśmy o tym wcześniej w artykule „Jak używać plików .htaccess”. Przypomnijmy tylko w skrócie, że jeżeli nie chcemy, aby użytkownicy mogli samodzielnie zmieniać niektóre parametry pracy Apache’a, to w wybranej sekcji ustawiamy wartość dyrektywy AllowOverride na None. Warto to zrobić na poziomie struktury całego dysku, zamieszczając odpowiedni wpis w sekcji root:

AllowOverride None


Zabieg ten sprawi, że użycie .htaccess nie będzie możliwe, o ile dla innego katalogu nie zostanie to jawnie wskazane. Wspomnianą wcześniej dyrektywę warto rozszerzyć o dodatkowe wpisy limitujące dostęp do serwera:

Order Deny,Allow
Deny from All
AllowOverride None


W ten sposób zablokowaliśmy dostęp do serwera na poziomie wszystkich zasobów. W pozostałych sekcjach Directory należy go oczywiście odblokować, tak by dana strona była dostępna dla wszystkich lub tylko wybranych adresów IP. Dokładniejsze wyjaśnienie tego zagadnienia jest zawarte w rozdziale „Blokowanie dostępu do strony” wspomnianego już artykułu o .htaccess. Warto tylko przypomnieć ogólną zasadę tworzenia polityki dostępu: najpierw blokujemy wszystkie komputery, a dopiero później jawnie przyznajemy dostęp wybranym komputerom (osobom) lub ich grupie.

Gdy zdecydujemy się przyznać użytkownikom możliwość tworzenia plików .htaccess, powinniśmy zadbać o to, aby nikt postronny nie miał do nich dostępu. Inaczej mówiąc, należy zablokować pobieranie tego typu plików z serwera. Służy do tego dyrektywa Files:

Order allow,deny


Uwaga: dyrektywa ta zapewne jest już zapisana w domyślnej konfiguracji serwera. Warto zatem zamieścić tam tylko dodatkową regułę, ograniczającą dostęp do plików .inc, które są używane w skryptach:

Order allow,deny


HTTP pod kontrolą, czyli mod_security

Wszystkie omówione do tej pory mechanizmy związane były z zapewnieniem bezpieczeństwa na poziomie serwera WWW lub systemu, w którym jest on uruchomiony. Prawdziwe pole do popisu dla sieciowych włamywaczy stanowią jednak aplikacje internetowe. Przyczyn jest wiele, a do najważniejszych należą błędy w implementacjach usług i języków, niewłaściwa konfiguracja serwera i jego rozszerzeń, a przede wszystkim źle napisany kod. W artykule „Siedem najgroźniejszych ataków na serwisy WWW" omówiliśmy najczęściej wykorzystywane luki w aplikacjach WWW oraz sposoby radzenia sobie z nimi. Błędów i pomyłek w kodzie nie da się jednak uniknąć, dlatego do ochrony programów sieciowych warto podejść także z drugiej strony.

reklama


Firewall najwyższego poziomu

Większość typowych zapór ogniowych pracuje na poziomie protokołu TCP/IP. Przy ich użyciu możemy skutecznie odfiltrować wybrane hosty i porty. W wypadku aplikacji sieciowych taka analiza nie wystarcza, bo ataki mogą być przeprowadzane poprzez protokół HTTP. Wystarczą źle napisana strona WWW i umiejętnie spreparowane zapytanie, by skasować lokalną bazę danych, pobrać z niej tajne dane (np. numery kart kredytowych) czy po prostu wykonać jakiś program na serwerze. Do ochrony przed tego typu zagrożeniami niezbędne są zatem analizowanie ruchu po protokole HTTP, wykrywanie danych przychodzących w zapytaniach i blokowanie tych, które potencjalnie stanowią zagrożenie.

Osłonę taką stanowią programy nazywane firewallami aplikacji sieciowych (ang. web application firewall lub application layer firewall). Tego typu narzędzia analizują ruch po protokołach siódmej warstwy modelu OSI, czyli warstwy aplikacji (tu: protokołu HTTP). Na podstawie analizy przesyłanych danych zapory mogą monitorować, logować czy po prostu blokować ruch sieciowy.

Znakomitym firewallem aplikacyjnym dla serwera WWW jest ModSecurity. Program ten działa jako moduł serwera, w pełni integrując się z Apache’em (może zostać skompilowany wewnątrz serwera lub jako moduł dynamicznie ładowany na żądanie). ModSecurity analizuje zarówno ruch przychodzący, jak i wychodzący. W pierwszym wypadku jest w stanie wykryć nieuprawnione zapytania w metodach GET, POST i ciasteczkach. Działanie ModSecurity opiera się na zdefiniowanych przez administratora zestawach reguł wraz z przypisanymi im akcjami. Baza reguł (sygnatur) stanowi podstawę do wnioskowania na temat zagrożeń – niebezpiecznych ciągów znaków przekazywanych w sesjach HTTP, które powinny zostać zablokowane, zarejestrowane itd.

Instalacja ModSecurity

ModSecurity kompilujemy ze źródeł (do pobrania ze strony ModSecurity) lub instalujemy z gotowej paczki binarnej. Pakiety binarne są przygotowywane przez niezależnych autorów. Ze względów licencyjnych wiele dystrybucji zrezygnowało z dostarczania ModSecurity we własnych systemach. Odnośniki do paczek przeznaczonych dla kilku najpopularniejszych odmian Linuksa znajdziemy na stronie ModSecurity Download. Na przykład pakiety dla Debiana przygotowuje Alberto Gonzalez Iniesta i są one dostępne na stronie http://etc.inittab.org/~agi/debian/libapache-mod-security2/. Możemy pobrać je samodzielnie i zainstalować w systemie lub skorzystać z repozytorium APT. W drugim wypadku do pliku /etc/apt/sources.list dopisujemy wiersz:
deb http://etc.inittab.org/~agi/debian/libapache-mod-security2/etch ./

Na koniec poleceniem apt-get update odświeżamy listę pakietów gotowych, po czym możemy przystąpić do właściwej instalacji ModSecurity. Kolejne komendy wyglądają tak:
apt-get install mod-security2-common libpapache2-mod-security2
a2enmod mod-security
/etc/init.d/apache2 force-reload

Pierwsze polecenie zainstalowało wszystkie wymagane pakiety. Druga komenda, specyficzna dla Debiana, uaktywniła moduł ModSecurity w Apache’u, trzecia natomiast spowodowała jego ponowne uruchomienie. W zależności od dystrybucji składnia tych poleceń może być różna, a w szczególności inny może być sposób włączenia ModSecurity do konfiguracji Apache’a. W większości przypadków w pliku ustawień serwera wystarczy dopisać wiersze:
LoadFile /usr/lib/libxml2.so.2
LoadModule security_module /usr/lib/apache2/modules/mod_security2.so

Teraz możemy przystąpić do konfiguracji ModSecurity. Ustawienia modułu zamieszczamy wewnątrz dyrektywy . Szybkie rozpoczęcie pracy z serwerem jest możliwe dzięki obecności w katalogu /usr/share/doc/mod-security2-common/examples proponowanych plików ustawień dla Apache’a zarówno w wersji podstawowej (-minimal), jak i rozbudowanej (podkatalog rules). W pierwszym wypadku wystarczy przekopiować zawartość wybranej konfiguracji do pliku ustawień serwera (httpd.conf lub apache2.conf), a następnie ponownie uruchomić Apache’a. Domyślna konfiguracja ModSecurity (wersja rozbudowana) pozwala w dość szybki sposób zabezpieczyć serwer WWW przed podstawowymi typami ataków SQL Injection, Path Traversal czy XSS. Dlatego warto podjąć wysiłki, aby ją wdrożyć w naszym serwerze. W pliku konfiguracyjnym Apache’a dopisujemy wiersz:
Include conf/modsecurity/*.conf

a następnie kopiujemy zawartość podkatalogu rules do katalogu /etc/apache2/conf/modsecurity. Równie dobrze możemy jednak użyć innych ścieżek do plików z sygnaturami, jak zostanie to pokazane w dalszej części artykułu.

ModSecurity z paczki

W Sieci znajdziemy wiele innych rozbudowanych zestawów reguł, gotowych do użycia wraz z ModSecurity. Wystarczy w Google'u wpisać wyrażenie mod_security rules, by otrzymać kilka interesujących wyników. Bez wątpienia do najlepszych należą paczki udostępnione w serwisie Got Root?. Obejmują one reguły chroniące przed atakami, o których wspomnieliśmy wcześniej, ale także zawierają dodatkowe sygnatury bezpieczeństwa, specyficzne dla konkretnych serwisów WWW/PHP, takich jak fora internetowe czy systemy CMS. Reguły Got Root? potrafią także zablokować znane rootkity, robaki internetowe oraz „niepożądane” przeglądarki-roboty (UserAgents).

reklama


Sygnatury, o których mowa, są dostępne na stronie http://www.gotroot.com/tiki-index.php?page=mod_security+rules. Można pobrać paczki przeznaczone dla serwera Apache w wersjach 1.x i 2.x oraz modułu ModSecurity 1.9 oraz 2.x.

Procedura instalacji sygnatur jest bardzo prosta. Najpierw trzeba już mieć właściwy moduł ModSecurity skonfigurowany do współpracy z Apache'em. W pliku ustawień serwera WWW sprawdzamy, czy istnieje dyrektywa włączająca zewnętrzne pliki konfiguracyjne z katalogu /etc/apache2/conf.d. Jeżeli nie, dopisujemy w nim następujący wiersz:
Include conf.d/*.conf

Teraz w katalogu /etc/apache2/conf.d tworzymy plik mod_security.conf, w którym zamieszczamy podstawową konfigurację ModSecurity. My posłużymy się tą dostarczoną przez serwis Got Root? i opatrzymy własnymi komentarzami. Oczywiście w tym miejscu równie dobrze możemy użyć dowolnej innej konfiguracji lub po prostu napisać własną od podstaw:


SecFilterEngine On
# Włącza działanie mechanizmu filtrującego.

SecFilterDefaultAction "deny,log,status:500"
# Domyślna akcja podejmowana w przypadku wykrycia nieuprawnionych
zapytań. Tutaj jest to blokowanie (deny), rejestrowanie zdarzenia
(log) oraz zwrócenie komunikatu - statusu serwera o numerze 500
(Internal Server Error).

SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckCookieFormat On
SecFilterCheckUnicodeEncoding Off
SecFilterNormalizeCookies On
SecFilterCookieFormat 1
# Włącza filtrowanie zapytań POST. Kilka domyślnych ustawień
związanych ze sprawdzaniem poprawności adresów URL,
kodowaniem UNICODE itp.

SecServerResponseToken Off

SecFilterScanOutput On
SecFilterOutputMimeTypes "(null) text/html text/plain"
# Filtrowanie danych wychodzących z serwera.

SecFilterForceByteRange 1 255
# Dopuszcza bajty o wartości z zakresu 1-255.

SecServerSignature "Prywatny serwer"
# Ukrywanie nazwy serwera. Apache będzie się przedstawiał
jako "Prywatny serwer".

SecAuditEngine RelevantOnly
SecAuditLog logs/audit_log
# Logowanie naruszeń polityki bezpieczeństwa. Wskazanie pliku
z logami.

SecFilterDebugLevel 0
SecFilterDebugLog logs/modsec_debug_log
# Opcje debugowania - wyłączone. Wskazanie pliku z logami
z operacji debugowania.

Include /etc/modsecurity/exclude.conf
# Dołącza reguły - wyjątki filtrowania. Reguły te muszą występować
przed pozostałymi.

Include /etc/modsecurity/rules.conf
# Dołącza reguły związane z ochroną aplikacji internetowych.

Include /etc/modsecurity/blacklist.conf
# Dołącza reguły związane z ochroną przed spamem w formularzach.

Include /etc/modsecurity/blacklist2.conf
# Dołącza reguły związane z blokowaniem niepożądanych komputerów
i serwerów proxy.

Include /etc/modsecurity/useragents.conf
# Dołącza reguły związane z blokowaniem niepożądanych klientów,
przeglądarek-robotów itd.

Include /etc/modsecurity/rootkits.conf
# Dołącza reguły związane z ochroną przed rootkitami, malware'em
i innym szkodliwym oprogramowaniem.

Include /etc/modsecurity/proxy.conf
# Dołącza reguły dotyczące blokowania prób używania serwera
jako proxy.

Include /etc/modsecurity/apache2-rules.conf
# Dołącza dodatkowe reguły specyficzne dla serwera Apache
w wersji 2.X.


Ostatnie osiem parametrów konfiguracyjnych z tego listingu stanowi dyrektywa Include. Włącza ona dodatkowe reguły ModSecurity z zewnętrznych plików konfiguracyjnych. Sygnatury Got Root? dystrybuowane są w postaci kilku plików. Należy je rozpakować do katalogu /etc/modsecurity/, a później właśnie dyrektywą Include jawnie włączyć do konfiguracji Apache’a. Po każdej zmianie w ustawieniach serwera pamiętajmy o jego ponownym uruchomieniu.

Dyrektywy ModSecurity

Zestaw reguł ModSecurity opiera się na kilkudziesięciu predefiniowanych dyrektywach. Pełną ich listę znajdziemy w dokumentacji umieszczonej na stronie http://www.modsecurity.org/documentation/index.html. Trzeba tu podkreślić, że między edycjami 1.x a 2.x zaszły znaczące zmiany w nazewnictwie i strukturze dyrektyw. I tak przykładowo: dyrektywa SecFilter została zastąpiona bardziej elastyczną dyrektywą SecRule. Należy o tym pamiętać, zaglądając do przykładowych plików konfiguracyjnych.

reklama


Dostępny na wymienionej wyżej stronie ModSecurity Reference Manual jest pierwszym dokumentem, od którego rozpoczynamy zapoznawanie się z dyrektywami. Każda z nich została opatrzona opisem, informacjami o składni i zakresie użycia, a także przykładami. Nie sposób omówić ich wszystkich w tym artykule. W uproszczeniu można natomiast założyć, że część ogólnych dyrektyw przyjmuje wartości z ustalonego zakresu parametrów lub jest jedynie włączona/wyłączona. Po takie informacje należy sięgnąć właśnie do podręcznika ModSecurity.

Dyrektywą wartą odnotowania w tym miejscu jest natomiast SecRule, stosowana do analizy danych, do której administrator może przypisać akcję podejmowaną na podstawie wyników tejże analizy. Składnia SecRule jest następująca:
SecRule ZMIENNA OPERATOR [AKCJA]

Parametr AKCJA jest opcjonalny – jeżeli go nie ma, podejmowane jest działanie domyślne, zapisane w konfiguracji modułu dyrektywą SecFilterDefaultAction. W dalszej części artykułu omówimy kilka innych akcji (lista dostępnych składa się z kilkudziesięciu pozycji). I tu ponownie odsyłamy do podręcznika ModSecurity, aby się z nimi zapoznać. Do najczęściej stosowanych bez wątpienia należą:
deny – zablokuj zapytanie,
allow – pozwól na wykonanie zapytania,
status:xxx – zwróć status serwera o numerze, gdzie xxx jest kodem statusu serwera,
redirect:url – przekieruj do adresu url,
log – zapisz zapytanie do pliku dziennika,
nolog – nie rejestruj zapytania w dzienniku.

W jednej regule można zadać wiele akcji, np. zablokuj i zaloguj, oddzielonych od siebie przecinkiem. OPERATOR stanowi ciąg znaków lub wyrażenie regularne. Dopasowanie zapytania do operatora powoduje, że dana reguła jest prawdziwa i należy zastosować przypisaną do niej akcję lub akcję domyślną. ZMIENNA określa „miejsce”, w którym dana reguła ma być sprawdzana. Najczęściej stosowaną zmienną jest REQUEST_URI, która nakazuje sprawdzanie reguł w adresie, a raczej parametrach zapytania przekazywanych do serwera.

Przykładem użycia może być zablokowanie próby odczytania plików shadow i passwd zawierających hasła w systemach Unix:
SecRule REQUEST_URI "/etc/shadow"
SecRule REQUEST_URI "/etc/passwd"

W podobny sposób uniemożliwimy wykonanie niektórych programów:
SecRule REQUEST_URI "/bin/bash"
SecRule REQUEST_URI "/bin/chmod"

Bardziej złożona reguła uchroni nas przed atakami typu SQL Injection zarówno w przypadku zapytań przekazywanych przez adres (REQUEST_URI), jak i w ciele wywołania (REQUEST_BODY). Wychwytywane przez nią zapytania zawierające słowa kluczowe SQL-a (jak DELETE, DROP itd.) są przez nią blokowane:
SecRule REQUEST_URI|REQUEST_BODY "((select|grant|delete|insert|
drop|alter|replace|truncate|update|create|rename|describe)
[[:space:]]+[A-Z|a-z|0-9|\*| |\,]+[[:space:]]
+(from|into|table|database|index|view)
[[:space:]]+[A-Z|a-z|0-9|\*| |\,]|
UNION SELECT.*\'.*\'.*,[0-9].*INTO.*FROM)"

I na deser reguła mogąca nas uchronić przed atakami typu Path Traversal, czyli wędrowaniu po katalogach na dysku:
SecRule REQUEST_URI "\.\./"

Przedstawione powyżej przykłady stanowią jedynie wierzchołek góry lodowej. Zachęcamy do samodzielnego przestudiowania domyślnych reguł dostarczanych standardowo wraz z ModSecurity lub z zewnętrznych źródeł.

Gadatliwy Apache

Informacja o tym, z którą wersją serwera WWW mamy do czynienia oraz jakie dodatki są na nim zainstalowano, może być punktem zaczepienia dla atakującego. Tym bardziej że potrzeba zaledwie kilku prostych czynności, aby to sprawdzić. W tym celu wystarczy udać się na stronę główną serwisu. Komunikat „It works!” nie daje złudzeń: na tym komputerze pracuje Apache. Idąc dalej tym tropem: w przeglądarce wpisujemy adres wymyślonej, nieistniejącej podstrony. Wraz z informacją o komunikacie błędu (404 – Nie znaleziono) w stopce wygenerowanego dokumentu znajdziemy pełne informacje o wersji Apache’a, systemie, na którym go zainstalowano, oraz dodatkowych modułach dołączonych do serwera – także z dokładnym numerem wersji.

Te same informacje uzyskamy, łącząc się telnetem na port 80 i wydając dowolną komendę HTTP, np. HEAD:
telnet adres_serwera 80
HEAD / HTTP/1.0

Aby wykonać komendę HTTP, należy następnie dwukrotnie nacisnąć klawisz [Enter].

W łatwy sposób możemy wyeliminować ilość informacji udostępnianych na zewnątrz przez Apache’a. Odpowiada za to dyrektywa ServerTokens, która przyjmuje jedną z sześciu wartości: Full, OS, Minor, Minimal, Major oraz Prod. Domyślnie przypisano jej wartość Full, co oznacza, że serwer jest najbardziej „gadatliwy”. Aby zwiększyć bezpieczeństwo systemu, ustalamy zatem poziom tej opcji na możliwie najniższy:
ServerTokens Prod

Dodatkowo powinniśmy przypisać dyrektywie ServerSignature wartość Off (wyłączona). W ten sposób ograniczymy podawanie informacji przez serwer podczas listowania katalogów FTP, generowania wewnętrznych stron błędów dokumentów itp.
ServerSignature Off

Dyrektywy ServerTokens i ServerSignature pozwalają ograniczyć liczbę przekazywanych na zewnątrz informacji o serwerze.

Należy natomiast pamiętać, że obie dyrektywy nie zablokują definitywnie wyświetlania przez serwer danych o nim samym. W najprostszej postaci odwiedzający serwis otrzyma informacje o tym, że na komputerze zainstalowano Apache’a. Jeżeli chcemy to ominąć, pozostaje nam zmiana w źródłach serwera i jego rekompilacja. Dane o wydaniu Apache’a przechowywane są w pliku include/ap_release.h. Najbardziej istotną definicją jest AP_SERVER_BASEPRODUCT, gdzie potencjalnie możemy zastąpić słowo „Apache” czymś innym, np. „Microsoft IIS”. Numery wersji przechowywane są w symbolach AP_SERVER_MAJORVERSION_NUMBER, AP_SERVER_MINORVERSION_NUMBER i AP_SERVER_PATCHLEVEL_NUMBER. Ale uwaga: zmiana wersji może pociągać za sobą problemy z kompilacją innych modułów serwera.

Sposób, w jaki serwer przedstawia się na zewnątrz, zmienimy także za pomocą modułu mod_security. Brak identyfikacji Apache’a wiąże się także z koniecznością usunięcia domyślnych stron startowych oraz komunikatów błędów. Kasujemy zatem katalog /var/www/apache2-default oraz ustawiamy własne komunikaty błędów. Tutaj ponownie odwołamy się do artykułu „Jak używać plików .htacces”, gdzie szerzej omówiliśmy to zagadnienie. Przypomnijmy jedynie, że wpisy allow i deny możemy stosować na poziomie konfiguracji całego serwera, poszczególnych katalogów (dyrektywa ), serwerów wirtualnych (dyrektywa ) oraz zamieszczać je w pliku .htaccess. Warto też pamiętać, że wielu włamywaczy stosuje inne techniki uzyskania informacji o zainstalowanych produktach, jak chociażby HTTP Fingerprinting.

Moduły absolutnie niezbędne do pracy z Apache’em jako serwerem WWW to core, http_core oraz jedna wybrana implementacja MPM (prefork, worker itd.). Wszystkie pozostałe możemy wyłączyć, choć tak przygotowany serwer będzie tylko w niewielkim stopniu użyteczny. Apache powinien zostać skompilowany z modułem mod_so, jeżeli pozostałe moduły chcemy ładować dynamicznie.

Z punktu widzenia bezpieczeństwa Apache’a należy skompilować moduły mod_access (kontrola dostępu do serwera), mod_auth (mechanizmy autoryzacji użytkowników) oraz mod_log_config (mechanizmy logowania zdarzeń serwera). W odniesieniu do funkcjonalności serwera warto natomiast dołączyć do niego moduły mod_dir (obsługa stron startowych), mod_mime (obsługa MIME) czy mod_userdir (strony domowe użytkowników). W Apache’u możemy zrezygnować, o ile nie zamierzamy stosować tych funkcjonalności, z mod_cgi (obsługa skryptów CGI), mod_include (funkcja Server Side Includes) czy mod_status (monitorowanie stanu serwera).

Logi, logi, logi

Dane o zdarzeniach serwera przechowywane są w pliku access.log, natomiast te o błędach samego serwera w pliku error.log. Ścieżkę do pierwszego z nich wskazuje dyrektywa CustomLog, do drugiego – Error.log. Obie dyrektywy mogą zostać zapisane w konfiguracji głównej serwera lub w ustawieniach poszczególnych serwerów wirtualnych.

O tym, które informacje o zdarzeniach są rejestrowane, a które pomijane, decyduje natomiast dyrektywa LogLevel. Określa ona poziom ważności zapisywanych zdarzeń, przyjmując jedną z wartości: debug, info, notice, warn, error, crit, alert oraz emerg. Lista ta uporządkowana jest w kolejności malejącej: w trybie debug w dzienniku zdarzeń pojawia się najwięcej wpisów, włącznie z tymi służącymi do rozwiązywania problemów przez rozwijających serwer. Z kolei ustawienie poziomu emerg skutkuje tym, że do dziennika zapisywane są tylko informacje o krytycznych, najpoważniejszych błędach serwera.

W kontekście wpisów rejestrowanych w logach należy zwrócić uwagę na dyrektywę LogFormat. Pisaliśmy o niej szerzej w artykule „Witryna pod lupą, czyli jak korzystać z webalizera”. Domyślny plik konfiguracyjny Apache’a zawiera cztery definicje formatów zapisu logów: combined, common, referer oraz agent. Ten, który chcemy zastosować, wskazujemy we wspomnianej dyrektywie CustomLog:
CustomLog logs/access_log combined

Ptaszek na uwięzi, czyli chroot

Dość powszechnie stosowaną techniką zwiększającą bezpieczeństwo serwerów internetowych jest mechanizm chroot. Jego zastosowanie polega na wydzieleniu nowej struktury plików i katalogów systemu, w obrębie których działa uruchomiony serwer. W ten sposób atakujący ma ograniczone pole manewru. Włamanie utrudnia niejednokrotnie brak powłoki (w wydzielonej strukturze nie musi ona wcale istnieć), a gdy się to natomiast uda, cracker uzyskuje dostęp jedynie do plików wykonywalnych, ustawień i logów samego serwera.

Przygotowanie chroota rozpoczniemy już na etapie instalacji Apache’a. Wystarczy wówczas uruchomić skrypt configure ze zdefiniowanymi odpowiednio ścieżkami do plików konfiguracyjnych, wykonywalnych i bibliotek oraz logów. Drugi sposób zaprezentujemy poniżej: przeniesienie istniejącej instalacji serwera do przestrzeni chroot.

Na początek zatrzymujemy uruchomioną instancję Apache’a. Tworzymy nowego użytkownika (o ile nie zostało to wcześniej zrobione), a następnie przygotowujemy strukturę nowego serwera. W tym celu wydajemy kolejno polecenia:
mkdir -p /chroot/apache
# mkdir -p /chroot/apache/dev
# mkdir -p /chroot/apache/etc/apache2
# mkdir -p /chroot/apache/lib
# mkdir -p /chroot/apache/usr/sbin
# mkdir -p /chroot/apache/var/run
# mkdir -p /chroot/apache/var/lock
# mkdir -p /chroot/apache/var/log/apache
# mkdir -p /chroot/apache/var/www/

Możliwość zapisu i wykonywania do katalogu /chroot/apache/var/log/apache powinien mieć tylko administrator:
# chmod 750 /chroot/apache/var/log/apache

W następnym kroku sprawdzamy, z jakich bibliotek korzysta Apache:
ldd /usr/sbin/apache2

Teraz należy wykonać najbardziej pracochłonny etap „zamykania” Apache’a w chroot. W tym celu kopiujemy wszystkie pliki serwera, pliki konfiguracyjne, biblioteki oraz dowiązania symboliczne do nich. Należy przy tym zachować dokładne położenie wszystkich obiektów w strukturze katalogów – może się więc okazać, że musimy utworzyć kolejny podzbiór. Nie podamy tutaj konkretnych poleceń, gdyż położenie plików różni się w zależności od używanego oprogramowania i dystrybucji Linuksa. Bardzo ogólny przepis składa się z kilku kroków:
skopiowanie katalogu /etc/apache2 do /chroot/apache/etc/apache2,
skopiowanie stron domowych, skryptów CGI z /var/www do /chroot/apache/var/www,
skopiowanie plików wykonywalnych /usr/sbin/apache2 i /usr/sbin/apache2ctl do /chroot/apache/usr/sbin.

W kolejnym kroku przygotowujemy plik urządzenia /dev/null, nadając mu jednocześnie odpowiednie parametry i prawa:
# mknod /chroot/apache/dev/null c 1 3
# chmod 666 /chroot/apache/dev/null

Teraz musimy jeszcze skopiować pliki systemowe /etc/passwd, /etc/group oraz /etc/shadow oraz usunąć z nich wszystkie wiersze poza tym definiującym użytkownika apache:
apache:x:1001:1001::/dev/null:/bin/false

Nie zapomnijmy także o skopiowaniu zbiorów /etc/hosts i /etc/nsswitch.conf, a po wykonaniu tego możemy przystąpić do pierwszego uruchomienia serwera. W tym celu wydajemy polecenie:
/usr/sbin/chroot /chroot/apache /usr/sbin/apache2

Pierwszy człon wskazuje ścieżkę do polecenia chroot. Drugi stanowi katalog, w którym chcemy zamknąć Apache’a, czyli tu /chroot/apache, ostatni natomiast określa ścieżkę do pliku wykonywalnego serwera. Zauważmy, że każdy z nich oddzielony jest spacją!

Upewnijmy się jeszcze, czy Apache został „uwięziony” w chroocie. Poleceniem ps –A | grep apache2 listujemy wszystkie procesy serwera, po czym zapisujemy numer (PID) dowolnego z nich. Następnie za pomocą komendy ls /proc/numer_procesu/root sprawdzamy, w którym drzewie katalogów operuje serwer. Jeżeli lista katalogów i plików pokrywa się ze strukturą utworzoną na potrzeby serwera, to wszystko jest w porządku! Aby sprawdzić, czy wszystko działa, po prostu za pomocą przeglądarki WWW próbujemy połączyć się z naszym serwerem.

Oczywiście może się zdarzyć, że serwer nie zostanie prawidłowo uruchomiony. Wówczas należy sprawdzić komunikaty zapisane w pliku error.log. Z dużym prawdopodobieństwem będziemy wtedy musieli przekopiować dodatkowe pliki konfiguracyjne, np. /etc/mime.types, lub poprawić wybrane ścieżki w plikach konfiguracyjnych.

Na koniec pozostaje nam przepisanie skryptu odpowiedzialnego za uruchamianie Apache’a podczas startu systemu, by serwer wywoływany był w sposób, jak pokazaliśmy wcześniej. W niektórych specyficznych wypadkach będziemy musieli także poprawić konfigurację sysloga, logrotate i innych pochodnych programów współpracujących z Apache'em, np. Webalizera.

3 komentarze:

  1. Ten komentarz został usunięty przez autora.

    OdpowiedzUsuń
  2. Konfiguracja Apache to pierwsza rzecz którą musimy się zając tuż zaraz po jego instalacji i w całym procesie stawiania serwera. Chyba, że tworzymy aplikacje użytkowe dla klientów jak https://craftware.pl to wtedy na pewno już taki serwer musi być odpowiednio skonfigurowany. Dziś jest dostępnych wiele paczek które możemy zainstalować z poziomu konsoli dosłownie jednym wywołaniem polecenia.

    OdpowiedzUsuń
  3. Jestem pod wrażeniem. Bardzo fajny wpis.

    OdpowiedzUsuń