|
wersja 0.4 |
|
Spis treści |
Po kiego ... ? 1. Od czegoś trzeba zacząć 2. Nowy system plików 3. Biblioteki - prawdziwe wyzwanie 4. Pierdoły Posłowie |
| Po kiego ... ? |
Już w przedszkolu uczą, że najlepszym (a przy okazji najbardziej popularnym) serwerem www na świecie jest Apache. Oczywiście ostatnią wersję (1.3.x) wspomnianego softu masz już na dysku. Aby zwiększyć bezpieczeństwo naszego serwera www, możemy umieścić go w pierdlu. Tak jest, jeśli nawet ktoś się do nas włamie - wyląduje tam gdzie jego miejsce. W praktyce polga to na tym, że Apacz zostaje uruchomiony w "zamkniętym" systemie plików. Są tam tylko niezbędne do jego działania pliki, nic więcej. Brak katalogów domowych użytkowników, SUIDów, plików z hasłami itd. Mechanizm chroot (znany także jako jail) uważany jest za rozwiązanie podnoszące w znaczący sposób bezpieczeństwo systemu. Zapowiada się ciekawie... No i może na koniec wspomnę tylko, że niniejszy dokument nie opisuje szczegółów pliku konfiguracyjnego Apacza - tych w Sieci nie brakuje. |
| 1. Od czegoś trzeba zacząć |
A więc zaczynam. Na początek informacje praktyczno - techniczne. Opisuję tutaj instalację z kodu źródłowego. Różnego rodzaju instalatory - ułatwiacze rozmieszczają pliki Apacza po całym dysku i nikt nie wie gdzie czego szukać. Nie wiadomo nawet co się jak nazywa ;). Po drugie: konfiguracja i działanie zostały przetestowane pod Slackiem 9.0. Po trzecie: instaluję wersję 1.3.27. Po czwarte i chyba najważniejsze: nie cuduj. Jeśli nie jesteś w temacie chroota, rób krok po kroku to, co opisuję. Gdy już szczaisz o co chodzi, będziesz mógł to robić po swojemu (ścieżki, prawa itp.). Na początek musisz wybrać sobie użytkownika, z prawami którego będzie chodził nasz serwerek. Domyślnie jest to nobody. Wykorzystuje go pewnie jeszcze parę usług, więc powinieneś stworzyć sobie nowego, dedykowanego usera. I stworzyć nową grupę. Mój wybór padł na użytkownika www, którego podstawową grupą będzie www. Ciekawe dlaczego... Dobra jest, teraz musimy utworzyć go z minimalną liczbą przywilejów. Zaczniemy od grupy: groupadd www useradd -c "serwer www" -d /dev/null -g www -s /bin/false www Tak więc utworzyliśmy najpierw grupę www. Będzie należał do niej tylko użytkownik www. W drugiej linii dodaliśmy tego użytkownika. Jego katalogiem domowym jest /dev/null, należy on do grupy www, jego shellem jest /bin/false a opisem "serwer www". Nasz nowy użytkownik to prawdziwy looser, nie ma nic. Gdyby wszyscy tacy byli... ----------------------------- dla Apache + PHP --------------------------- W przypadku instalacji Apacza z PHP należy na początku postępować standardowo: cd apache-1.3.27 ./configure cd ../php-4.3.2 ./configure --with-apache=../apache-1.3.27 --without-mysql make make install -------------------------------------------------------------------------- -------------------------- dla Apache + mod_ssl -------------------------- Sednem sprawy jest wygenerowanie sobie certyfikatu, klucza itp. Szczegółowy opis umieściłem w dokumencie na mojej stronie. W dalszym ciągu niniejszej pracy zakładam, że postąpiłeś zgodnie ze wskazówkami tam zawartymi (do tej pory punkt 1: OpenSSL). Po wejściu do katalogu mod_ssl-2.8.14-1.3.27 robisz tyle: ./configure --with-apache=../apache_1.3.27 --with-crt=/etc/ssl/server.crt --with-key=/etc/ssl/server.key -------------------------------------------------------------------------- Czas skonfigurować Apacza. Oto opcje, które proponuję na początek: ./configure --prefix=/usr/apache --server-gid=www --server-uid=www --------------------------- dla Apache + PHP --------------------------- Jeśli chcemy dorzucić obsługę PHP (jako moduł statyczny), należy do powyższych opcji dorzucić: --activate-module=src/modules/php4/libphp4.a --------------------------------------------------------------------------- ------------------------- dla Apache + mod_ssl -------------------------- Aby dołączyć nasz moduł, do wyżej wymienionych opcji musimy dopisać: --enable-module=ssl Przed wydaniem polecenia ./configure ... powinniśmy także ustawić zmienną SSL_BASE tak, aby wskazywała katalog ze źródłem openssl'a Całe polecenie konfiguracyjne Apacza może więc wyglądać tak: SSL_BASE=../openssl-0.9.7b ./configure [tutaj wyżej opisane opcje] --------------------------------------------------------------------------- Teraz standardowo: make make install Tymczasowo proponuję umieścić Apacza właśnie w /usr/apache. Gdy wszystko przeniesie się do wydzielonego systemu plików, będzie o wiele prościej. W każdym razie chodzi o jak najkrótszą ścieżkę i minimalną liczbę porozrzucanych katalogów (logi, pliki konfiguracyjne, plik .pid itp). W tym przypadku wszystko to zamyka się w /usr/apache. ------------------------------ dla Apache + PHP -------------------------- Instalacja PHP przebiega cały czas normalnie: cd php-4.3.2 cp php.ini-dist /usr/local/lib/php.ini Pozostało jeszcze wyedytować plik httpd.conf i dorzucić do niego wpis: AddType application/x-httpd-php .php -------------------------------------------------------------------------- Teraz nadszedł czas, abyś spróbował uruchomić Apacza i zobaczyć czy "normalnie" zainstalowany działa jak należy. W konfigu (/usr/apache/conf/httpd.conf) powinieneś zmienić opcję "Port" na "80" i sprawdzić czy "User" i "Group" wskazują na www. ------------------------------ dla Apache + PHP -------------------------- Powinieneś sprawdzić działanie i Apacza i PHP, wykorzystując np. funkcję phpinfo() -------------------------------------------------------------------------- -------------------------- dla Apache + mod_ssl -------------------------- Sprawdź, czy połączenie przez SSL działa prawidłowo. W razie potrzeby sięgnij do dokumentu na mojej stronie. -------------------------------------------------------------------------- Jeśli działa - jest dobrze. Wyłącz Apacza, zaczynamy zabawę. |
| 2. Nowy system plików |
Należy teraz wybrać katalog, który stanie się / (rootem) dla naszego serwerka www. Apacz nie będzie widział nic, co jest wcześniej. Linuxową tradycją, przekazywaną z ojca na syna, stał się katalog /chroot jako podstawa dla wszyskich więzionych programów. Tak więc robimy, co następuje: mkdir /chroot mkdir /chroot/apache Jak już pewnie się domyśliłeś, rootem dla naszego Indiańca będzie /chroot/apache. Teraz wyobraź sobie, że jesteś programem, który działa z prawami jakiegoś użytkownika. Na początek przydałby się tobie shell (a jest nim /bin/false). mkdir /chroot/apache/bin cp /bin/false /chroot/apache/bin Jak wspomniałem wcześniej, /chroot/apache staje się /. Tak się składa, że jest w nim bin, który zawiera shella. Inną ważną sprawą jest katalog domowy (tutaj: /dev/null). Najpier sprawdź jakie ma prawa i do kogo należy wyżej wymieniony (ls -l /dev/null). Prawa i właściciela należy odwzorować w nowym roocie. /dev/null jest urządzeniem znakowym, którego nie można tak po prostu skopiować. Należy je utworzyć: mkdir /chroot/apache/dev cd /chroot/apache/dev mknod null c 1 3 chmod 666 null chown root:sys null Teraz ls -l /chroot/apache/dev/null powinien wyglądać jak ls -l /dev/null (nie licząc daty utworzenia :). Na razie jest dobrze, w więzieniu mamy /dev oraz /bin. Jeszcze var/run na różne dziwne rzeczy :) mkdir /chroot/apache/var mkdir /chroot/apache/var/run Gdybym chciał przycynić, powyższe dwie linijki zastąpiłbym jedną: mkdir -p /chroot/apache/var/run Jedziemy dalej - czas przerzucić Apacza: mkdir /chroot/apache/usr cp -r /usr/apache /chroot/apache/usr Dobra, mamy kolejny element układanki. Teraz czas na /etc/ i kilka plików, które tam siedzą: mkdir /chroot/apache/etc cd /chroot/apache/etc cp /etc/hosts . cp /etc/resolv.conf . cp /etc/nsswitch.conf . cp /etc/host.conf . cp /etc/localtime . cp /etc/group . cp /etc/passwd . Spokojnie! Teraz wrzuć do jakiegoś edytora plik group i usuń z niego wszystkie linijki, za wyjątkiej tej z definicją grupy www. Zapisz zmiany. Plik /chroot/apache/etc/group jest teraz plikiem mającym jedną linijkę. To samo zrób z passwd - pozostaw tylko linię z definicją użytkownika www. Pozostałych wyrzuć. Zapisz zmiany, plik /chroot/apache/etc/passwd ma także jedną linijkę. ---------------------------- dla Apache + PHP ---------------------------- Nasz Apacz potrzebuje pliku php.ini. Nie pozostało nam nic innego jak wykonać poniższe: mkdir /chroot/apache/usr/local mkdir /chroot/apache/usr/local/lib cp /usr/local/lib/php.ini /chroot/apache/usr/local/lib Dla bardziej złożonych aplikacji, będziesz prawdopodobnie potrzebował jeszcze tego: mkdir /chroot/apache/tmp chmod 1777 /chroot/apache/tmp -------------------------------------------------------------------------- ------------------------- dla Apache + mod_ssl ------------------------- Zaczynamy od urządzenia /dev/urandom. Jeśli go nie masz, wykorzystaj /dev/random postępując analogicznie: Sprawdź jego prawa - musisz je odwzorować w chroocie. cd /chroot/apache/dev mknod urandom c 1 9 Prawa dostępu i właściciela powinny pokrywać się z prawami /dev/urandom. Jeśli masz tylko /dev/random, utwór z go zamiast urandom. Jak zauważa Paweł P. (thx): dla RedHata 7.2 "trzeba było dodatkowo stworzyć mknod /dev/tty c 5 0 - bez tego wyskakiwał komunikat o braku klucza prywatnego". Jeszcze pozostał katalog tmp, który w przypadku PHP nie był wymagany. Jeśli go nie masz - już czas go utworzyć: mkdir /chroot/apache/tmp chmod 1777 /chroot/apache/tmp -------------------------------------------------------------------------- Teraz zauważ, że wszystkie pliki, które znajduą się w /chroot/apache, są "nieszkodliwe". Nie ma ich wiele i nie zdradzają żadnych istotnych informacji o systemie, jego konfiguracji, użytkownikach itp. |
| 3. Biblioteki - prawdziwe wyzwanie |
Tutaj zaczyna się sedno sprawy - część najtrudniejsza. Apacz bowiem potrzebuje do prawidłowego działania pewnych bibliotek. Jakich ? Zależy od systemu, jego wersji, kompilatora itp. Poniższy opis pasuje do Slacka 9. Postaram się wyjaśnić, jak rozpoznać co gdzie wrzucić, dlatego poniższe polecenia należy odpowiednio zmodyfikować. Demonem odpowiadającym za działanie naszego programu jest httpd. Znajduje się on w katalogu /chroot/apache/usr/apache/bin/. Aby dowiedzieć się, które biblioteki są wymagane do jego działania, należy posłużyć się poleceniem ldd. Jego argumentem jest binarka. ldd /chroot/apache/usr/apache/bin/httpd Dla Slacka 9 wynik działania polecenia przedstawia się następująco: libm.so.6 => /lib/libm.so.6 (...) libcrypt.so.1 => /lib/libcrypt.so.1 (...) libexpat.so.0 => /usr/lib/libexpat.so.0 (...) libc.so.6 => /lib/libc.so.6 (...) /lib/ld-linux.so.2 => /lib/ld-linux.so.2(...) ---------------------------- dla Apache + PHP ---------------------------- W tym przypadku powinno pojawić się trochę więcej bibliotek. U mnie były to dodatkowo: libresolv.so.2 => /lib/libresolv.so.2 (...) libdl.so.2 => /lib/libdl.so.2 (...) libnsl.so.1 => /lib/libnsl.so.1 (...) -------------------------------------------------------------------------- U Ciebie powyższe może wyglądać trochę inaczej, dlatego teraz uważaj... Bierzemy pod uwagę prawą stronę. Pliki tam wymienione należy skopiować do odpowiednich katalogów w /chroot/apache. Oto odpowiednie polecenia (u siebie zmień je analogicznie) dla wyżej otrzymanego wyniku. mkdir /chroot/apache/lib cd /chroot/apache/lib cp /lib/libm.so.6 . cp /lib/libcrypt.so.1 . cp /lib/libc.so.6 . cp /lib/ld-linux.so.2 . mkdir /chroot/apache/usr/lib cd /chroot/apache/usr/lib cp /usr/lib/libexpat.so.0 . ----------------------------- dla Apache + PHP ------------------------ Jak łatwo się domyślić, należy dodatkowo zrobić to: cd /chroot/apache/lib cp /lib/libresolv.so.2 . cp /lib/libdl.so.2 . cp /lib/libnsl.so.1 . --------------------------------------------------------------------------- --------------------------- dla Apache + mod_ssl ------------------------ mod_ssl nie wymaga dodatkowych bibliotek. Przynajmniej u mnie :) (to z cyklu "niewiarygodne ale prawdziwe"). --------------------------------------------------------------------------- Powinieneś już wiedzieć o co chodzi. Chciałbym w tym momencie napisać, że to już wszystko... Już pewnie się domyśliłeś że tak nie jest. Lecimy dalej. Aby uruchomić jakiś program w chroocie używa się następującej składni: chroot nowy_root_programu względna_ścieżka_programu. W naszym przypadku wygląda to tak: chroot /chroot/apache /usr/apache/bin/httpd Objaśnienie: chroot to program, który zamknie w /chroot/apache program /usr/apache/bin/httpd. Ścieżka do samego programu (ostatni parametr) jest podana względem /chroot/apache. Czyli chroot zamyka nas w /chroot/apache (od tej porty jest on / rootem) i uruchamia /usr/apache/bin/httpd. Program, który zostaje uruchomiony to /chroot/apache/usr/apache/bin/httpd. Mam nadzieję, że rozumiesz :) Uwaga: uruchom apacza demonem httpd, a nie apachectl czy jakimś skryptem w stylu rc.X. Żadnych skryptów, robimy ręcznie to co one. Powinieneś otrzymać błąd :). W Slacku 9 jest to: "httpd: bad user name www". Niezłe, co ? Czegoś jeszcze brakuje. I tu dochodzimy do sedna. Ta część pracy nazywa się "w poszukiwaniu zaginionych bibliotek". Wykorzystamy tutaj fajny programik o nazwie strace. Pozwala on śledzić działanie programu - a co za tym idzie jego odwołania do (pozostałych) bibliotek, plików itp. strace uruchamia się z poleceniem, którego działanie należy śledzić. No to lecimy: strace chroot /chroot/apache /usr/apache/bin/httpd Okej, przez ekran przewinęło nam się multum informacji. Wystarczy teraz uważnie czytać (często cofając ekran "do tyłu :)" ) i szukać nazw plików, do których httpd się odwołuje. W powyższym przypadku wyczaiłem gdzieś linię: open("/lib/libnss_compact.so.2", O_RDONLY) = -1 ENOENT (No such file ...) Mam cię ! Następuje tutaj odwołanie do biblioteki, której nie skopiowałem do mojego chroota (/chroot/apache). Wykonuję więc następujący krok: cp /lib/libnss_compact.so.2 /chroot/apache/lib/ Próbujemy znowu uruchomić Apacza: chroot /chroot/apache /usr/apache/bin/httpd Albo otrzymamy znowu błąd (często ten sam), albo Apacz się uruchomi. Powinniśmy wałkować to wszystko tak długo, dopóki Apacz nie uruchomi się bez żadnego pierdnięcia. Jeśli widzimy jakikolwiek błąd, uruchamiamy znowu strace szukając odwołania do czegoś, czego nie skopiowaliśmy do naszego chroota. Nie musi to być biblioteka, może to być jakiś plik w /etc/. Jeszcze jedno: po kilku takich próbach Apacz może wystartować, nawet jeśli zrobi to z błędem. Nie chcemy błędów. Dlatego po próbie uruchomienia Apacza w chroocie, przed kolejnym uruchomieniem strace dobrze jest wydać polecenie killall httpd. To koniec części "w poszukiwaniu zaginionych bibliotek". Poniżej przedstawiam listę plików (dokładnie: poleceń) które musiałem wykonać aby Apacz w końcu bezbłędnie wystartował w chroocie na Slacku 9. cp /lib/libnss_compact.so.2 /chroot/apache/lib cp /lib/libnsl.so.1 /chroot/apache/lib cp /lib/libnss_dns.so.2 /chroot/apache/lib cp /lib/libnss_files.so.2 /chroot/apache/lib ------------------------------ dla Apache + PHP --------------------------- Plik libnsl.so.1 przerzuciliśmy już wcześniej. --------------------------------------------------------------------------- Dobra, po wydaniu polecenia: chroot /chroot/apache /usr/apache/bin/httpd bez żadnych błędów serwerek wystartował. Można to sprawdzić przy pomocy polecenia ps waux |grep httpd. Okej - jest. Widzimy. Ale skąd mamy mieć pewność, że to ten Apacz chodzi co trzeba, skoro ścieżka do niego jest inna ? Najlepiej się o tym przekonać usuwając oryginalnie zainstalowanego przez make install Apacza: rm -rf /usr/apache Teraz zatrzymujemy naszego (killall httpd) i jeszcze raz go uruchamiamy w chroocie. Chodzi ? To dobrze. Ciągle nie jesteś pewien ? Wykonaj polecenie ps x|grep httpd i zapamiętaj PID procesu httpd. Teraz wykonaj polecenie ls /proc/PID/root (PID to liczba) - powinieneś ujrzeć zawartość katalogu /chroot/apache/. Wygląda na to, że działa :). ----------------------------- dla Apache + PHP ------------------------- Wygląda na to, że działa :)). -------------------------------------------------------------------------- ---------------------------- dla Apache + mod_ssl --------------------- Dla mod_ssl dopisujemy parametr -DSSL : chroot /chroot/apache /usr/apache/bin/httpd -DSSL Wygląda na to, że działa :))) ------------------------------------------------------------------------- I jeszcze ważna uwaga dotycząca funkcji system PHP. Zacytuje tutaj mejla którego otrzymałem od Marcina R. (THX!): Po pierwsze znalazłem w sieci informacje, że funkcja "system" wymaga pliku /bin/sh (więc wrzuciłem go do /chroot/apache/bin/sh). Jednak to nie rozwiązało problemu. Polecenie dalej nie działało, mimo, że: "chroot /chroot/apache/ /usr/apache/bin/ls -l" wykonywane było poprawnie. Zrobiłem tak: uruchomiłem sh w chroocie i z tamtego (uwięzionego shella) wywołałem polecenie ls. Co się okazało? Brakuje mu bibliotek (mimo, że sprawdzałem wcześniej "ldd /chroot/apache/bin/ls" i nic nie wspominał o nich). Przekopiowałem brakujące pliki i jest ok. |
| 4. Pierdoły |
Po pierwsze: start i stop Start Apacza: chroot /chroot/apache /usr/apache/bin/httpd Stop Apacza: killall httpd Po drugie: konfigi Jestem przyzwyczajony do trzymania wszystkich plików konfiguracyjnych w katalogu /etc/. Dlatego też wykonuje polecenie: ln -s /chroot/apache/usr/apache/conf /etc/apache Po trzecie: logi Jestem przyzwyczajony do trzymania logów w /var/log/. Dlatego też wykonuje następujące polecenie: ln -s /chroot/apache/usr/apache/logs /var/log/apache Po czwarte: zacznij mieszać po swojemu. Pamiętaj, że ścieżki bezwzględne w pliku konfiguracyjnym Apacza rozpoczynają się tak naprawdę w /chroot/apache. Jeśli modyfikujesz coś w httpd.conf, musisz odpowiednio to uwzględnić. Po piąte: skrypty dostarczone razem z Apaczem (np. apachectl) raczej nie będą działały. Odnoszą się one do takich poleceń jak echo, kill itp., które znajdują się np. w katalogu /bin/. U nas ich nie ma. Masz dwa wyjścia - albo zrezygnować z ww. skryptów, albo przerzucać odpowiednie binarki i/lub modyfikować skrypty. Wybór należy do Ciebie. Po szóste: jeśli coś zamieszałeś i przestało działać, pamiętaj o poleceniu strace. Jest kwestią czasu, kiedy zaczniesz myśleć jak chroot. Nie pytaj mnie o pliki startowe, "zrób to sam". |
| Posłowie |
Jest to pierwsza wersja tego dokumentu i zawiera pewnie jakieś błędy/niedoróbki/potknięcia itp. Będę bardzo wdzięczny za wszelkie uwagi, komentarze, poprawki, wyrazy wdzięczności. Z góry przepraszam za powyższe i mam nadzieję, że będziecie mnie informować w których miejscach coś nie gra. Jako (częściowe) wytłumaczenie przedstawiam fakt, że większość tej pracy powstawała w późnych godzinach nocnych. Ostatnia wersja tego dokumentu znajduje się pod niżej wymienionym adresem. Kontakt ze mną: linio@terramail.pl Wesprzyj finansowo autora - kliknij tutaj |
|
=============================== Henryk Liniowski, Poznań 2003 http://linio.terramail.pl =============================== |