NFsec Logo

Apache – podstawowy poziom bezpieczeństwa – podsumowanie

02/03/2014 w Bezpieczeństwo Brak komentarzy.  (artykuł nr 437, ilość słów: 2004)

G

dybym miał na dzisiejszy dzień zapewnić podstawowy poziom bezpieczeństwa swojego serwera WWW – po standardowej instalacji z paczki zacząłbym od kilku rzeczy:

Pierwszą z nich na pewno jest zmiana ustawień nagłówka HTTP Server, aby nikt nie przeprowadzał sondy odnośnie wersji mojego serwera i załadowanych modułów za pomocą techniki banner grabbing np. przy pomocy prostego pluginu do Firefoksa jakim jest Firebug. Poruszając się dalej w strefie wycieku informacji – kolejnym krokiem była by eliminacja ETagów, ponieważ i tak przy większej liczbie serwerów nie spełniają one swojej roli.

Skoro mowa o spełnianiu roli to trudno nie zgodzić się z faktem, że metoda TRACE jest czymś, co obniża poziom bezpieczeństwa naszego serwera i zalecane jest jej wyłączenie. Przejdźmy teraz trochę do obszaru z zakresu wydajności. Podobnie jak w przypadku bezpieczeństwa systemów operacyjnych – nigdy nie należy instalować dodatkowego oprogramowania, którego nigdy się nie będzie używać, a które w swojej standardowej konfiguracji może powodować różnego rodzaju luki. Analogicznie możemy odnieść się do serwera Apache – czy te wszystkie moduły typu mod_negotiation, czy mod_autoindex są nam naprawdę potrzebne? Przecież nasza strona nie posiada innej wersji językowej niż polska i nigdy nie będziemy listować zawartości katalogów bez plików index.html. Dlatego podstawowym krokiem przed wystawieniem naszego serwera na okrutny świat Internetu jest refaktoryzacja ładowanych modułów. Nie tylko wpływają one na jego wydajność, ale także rozszerzają rodzaje i podatności na różne ataki. Tym bardziej, że w większości przypadków są pozostawiane bez użytku w standardowej, dostarczonej przez pakiet konfiguracji.

Kolejnym etapem jest zaplanowanie struktury naszych hostów wirtualnych i ich obsługi. W dzisiejszych czasach rzadko zdarza się, że serwer WWW nazywa się identycznie (posiada taką samą nazwę DNS), jak domena strony którą obsługuje – co stanowi dobrą praktykę. W ten sposób możemy zapewnić separację wielu adresów IP / interfejsów, czy żądań HTTP zwracanych i interpretowanych w nagłówku HOST – tym samym rozróżniając, które żądania są naprawdę przeznaczone do konkretnych domen i aplikacji, a które przez przypadek próbują uzyskać dostęp do zastrzeżonych zasobów. W serwerze Apache pierwszy zdefiniowany host wirtualny dla danego adresu IP (i portu) – obsługuje wszystkie żądania jakie kierowane są do serwera pod warunkiem, że nie znalazły one odwzorowania w definicjach innych vhostów. Dlatego pierwszym wirtualnym hostem powinien być wirtualny host typu catch all. Przykład: serwer gundam.x0x.pl (12.34.56.78) ma hostować stronę o adresie: x0x.pl.

Zanim zdefiniujemy nasz pierwszy vhost musimy zadbać o odpowiednie prawa do wybranych katalogów / podkatalogów, ponieważ każdy z nich mimo, że jest odwzorowany w systemie (z własnymi właścicielami i prawami dostępu) – w serwerze Apache może zostać osobno skonfigurowany do przestrzegania odpowiednich uprawnień i obsługi różnych funkcjonalności. Dlatego dla głównego i najwyższej postanowionego w hierarchii katalogu “/” powinniśmy przyjąć najbardziej restrykcyjne ustawienia. Jest to podobna polityka jak dla firewalli – blokujemy wszystko z założenia, aby później robić dziury zezwoleniami:

<Directory />
    Options None
    AllowOverride None
    Order deny,allow
    Deny from all
</Directory>

Wracając do hostów wirtualnych. Naszym pierwszym hostem będzie zarówno strona statyczna dla serwera gundam.x0x.pl, jak i “śmietnik” dla wszystkich innych żądań, które nie odwołują się do serwisu x0x.pl:

NameVirtualHost 12.34.56.78:80

<VirtualHost 12.34.56.78:80>
    ServerAdmin administrator@x0x.pl
    ServerName gundam.x0x.pl
    ServerAlias www.gundam.x0x.pl
    UseCanonicalName On
    DocumentRoot /var/www/html
    <Directory /var/www/html>
        Order allow,deny
        Allow from all
        <Limit GET HEAD>
            Order allow,deny
            Allow from all
        </Limit>
        <LimitExcept GET HEAD>
            Order deny,allow
            Deny from all
        </LimitExcept>
    </Directory>
    ErrorLog /var/log/httpd/error_log
    LogLevel warn
    CustomLog /var/log/httpd/access_log combined
</VirtualHost>

Dlaczego “śmietnik”? Ponieważ od teraz wszystkie żądania, które w nagłówku “Host:” będą miały ustawione nieprawidłowe lub spreparowane nazwy domen, a będą kierowane na nasz serwer (12.34.56.78) trafią do tego wirtualnego hosta. Co to oznacza w praktyce? Że wszystkie boty, skanery i inne plugastwa ustawione na automatyczne i bezmyślne przeszukiwanie podatności serwerów WWW będą odbijały się od np. pliku index.html umieszczonym w katalogu /var/www/html, a nasze logi zapełnią się wpisami typu:

... "GET /w00tw00t.at.ISC.SANS.DFind:) HTTP/1.1" 404 198 "-" "-"
... "GET /cgi-bin/php5 HTTP/1.1" 404 184 "-" "-"
... "GET /phpmyadmin/config/config.inc.php?p=phpinfo(); HTTP/1.1" 404 195 "-" "-"

W definicji w/w vhosta nie musimy ponownie definiować wpisów typu:

    Options None
    AllowOverride None

Ponieważ nie odejmujemy, ani dodajemy żadnych uprawnień i funkcji, a zgodnie z regułą łączenia definicji uprawnień w sekcjach dziedziczymy te już wcześniej zdefiniowane dla katalogu “/”. Ze względu na fakt, że będziemy wyświetlać prostą stronę HTML ograniczamy metody HTTP do dwóch podstawowych i zupełnie wystarczających GET oraz HEAD za pomocą dyrektywy Limit. Możemy przejść do kolejnego stadium, jakim jest definicja hosta wirtualnego dla aplikacji obsługiwanej przez adres x0x.pl:

<VirtualHost 12.34.56.78:80>
        ServerAdmin administrator@x0x.pl
        ServerName x0x.pl
        ServerAlias www.x0x.pl
        UseCanonicalName On
        DocumentRoot /data/x0x/www
        <Directory /data/x0x/www>
               	Options SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all

                RewriteEngine On
               	RewriteBase /
               	RewriteCond %{HTTP_HOST} ^www\.x0x\.pl$ [NC]
                RewriteRule ^(.*)$ http://x0x.pl/$1 [R=301,L]

               	<Limit GET POST HEAD>
                       	Order allow,deny
                        Allow from all
                </Limit>
                <LimitExcept GET POST HEAD>
                        Order deny,allow
                        Deny from all
                </LimitExcept>
                <FilesMatch "configuration.php">
                    Order allow,deny
                    Deny from all
                </FilesMatch>
        </Directory>
        ErrorLog /var/log/httpd/x0x_error_log
        LogLevel warn
        CustomLog /var/log/httpd/x0x_access_log combined
</VirtualHost>

W naszej aplikacji x0x umożliwiamy podążanie za linkami symbolicznymi w systemie plików, ale tylko jeśli właściciel linku symbolicznego i jego celu to ten sam użytkownik (SymLinksIfOwnerMatch). Skoro jesteśmy administratorami naszego serwera WWW nie ma sensu definicja umożliwiająca korzystanie z plików .htaccess (AllowOverride All), ponieważ wszystkie interesujące nas reguły przepisujące możemy zawrzeć w definicji samego hosta. Jeśli zmuszeni jesteśmy jednak do udostępnienia plików typu .htaccess znacznie lepiej jest przyznawać dostęp do konkretnych funkcji niż zezwolić na wszystko w standardzie:

AllowOverride None
AllowOverrideList RewriteEngine RewriteOptions RewriteBase RewriteCond RewriteRule

Poza tym nieprawidłowe wykorzystanie plików .htaccess może również wpłynąć negatywnie na wydajność serwera. Jak widzimy lista metod HTTP została rozszerzona o metodę POST umożliwiającą przesyłanie danych w formularzach i edytorach. Dodatkowo Apache będzie starał się chronić wrażliwy plik configuration.php zawierający dane autoryzujące dedykowanego użytkownika aplikacji do bazy danych. Jeśli mamy problem z określeniem, który wirtualny host jest pierwszy dla danego adresu IP i pełni rolę catch-all powinniśmy wykorzystać polecenie: httpd lub apache2 -S.

Serwer HTTPd powinien zawsze być uruchomiony z prawami zwykłego użytkownika (bez możliwości korzystania z powłoki systemowej!) w celu zapewnienia separacji uprawnień (w razie luki w zabezpieczeniach) dla innych daemonów uruchomionych na systemie. Zazwyczaj serwery Apache instalowane są za pomocą pakietów, które tworzą i uruchamiają go z prawami takich użytkowników – dla wielu dystrybucji jest to “apache” lub “www-data”:

[root@gundam conf]# ps -ef | grep http | grep -v grep
root     15570     1  0 Feb24 ?        00:00:07 /usr/sbin/httpd
apache   15606 15570  0 Feb24 ?        00:02:53 /usr/sbin/httpd
apache   15650 15570  0 Feb24 ?        00:02:45 /usr/sbin/httpd
apache   15674 15570  0 Feb24 ?        00:04:10 /usr/sbin/httpd
apache   15675 15570  0 Feb24 ?        00:02:45 /usr/sbin/httpd
apache   15676 15570  0 Feb24 ?        00:03:11 /usr/sbin/httpd

Powyżej widzimy procesy serwera Apache odpalonego w trybie prefork. Jeden proces niestety nadal jest uruchomiony z prawami root. Taka kolej rzeczy jest spowodowana koniecznością nasłuchu serwera na uprzywilejowanym porcie 80. Jedną z metod jest wykorzystanie POSIX capabilities, drugą natomiast ustawienie nasłuchu serwera np. na porcie 8080 i wykorzystanie loadbalancera lub serwera proxy do przekazywania połączeń z portu 80 na 8080. Możemy to także wykorzystać za pomocą iptables:

iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -A OUTPUT -p tcp -m tcp -d $IP --dport 80 -j REDIRECT --to-ports 8080

Gdzie $IP jest adresem IP, na którym nasłuchuje serwer. Niezależnie jakie rozwiązanie wybierzemy powinniśmy również zabezpieczyć pliki związane z serwerem httpd (tutaj przykład na podstawie dystrybucji CentOS):

chmod 750 /etc/httpd
chmod 750 /etc/httpd/conf /etc/httpd/conf.d /var/log/httpd
chmod 750 /usr/sbin/httpd
chmod 640 /etc/httpd/conf/*.conf /etc/httpd/conf.d/*.conf

Właścicielem tych plików powinien być użytkownik z prawami, którego zdecydowaliśmy się uruchamiać serwer httpd, a grupą ten sam użytkownik lub uniwersalnie: root. Na koniec warto przypomnieć, że jeśli nasza aplikacja jest pobierana za pomocą dowolnego repozytorium kodu należy pamiętać o zabezpieczeniu odpowiednich katalogów. Możemy również rozważyć restrykcyjne potraktowanie połączeń sieciowych generowanych przez nią samą. Oczywiście zupełną podstawą jest systematyczna aktualizacja oprogramowania.

Więcej informacji: Security Tips

Kategorie K a t e g o r i e : Bezpieczeństwo

Tagi T a g i : , , , , ,

Komentowanie tego wpisu jest zablokowane.