poniedziałek, 26 października 2009

Rsync

rsync -avz /root/backup / backup

rsync.exe -qartuz --force --delete 10.173.231.201::backup/* /cygdrive/c/backup/

rsyncd.conf


log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock

[backup]
path = /backup/
comment = backup
read only = yes
use chroot = no
charset = utf-8
uid = root
gid = root
hosts allow = 10.173.231.0/24

piątek, 23 października 2009

Jak zmienić hasło użytkownika w MySQL-u?

Jeśli korzystamy z konta administratora (root) i nigdy nie zmienialiśmy jego hasła, należy to zrobić komendą:
mysqladmin -u root password NOWE_HASLO

Jeżeli chcemy zmienić hasło użytkownika, który ma już jakieś ustanowione, należy to zrobić komendą:
mysqladmin -u NAZWA_UZYTKOWNIKA
 -p STARE_HASLO NOWE_HASLO

Zmiana już ustanowionego hasła administratora jest oczywiście możliwa przez:
mysqladmin -u root -p STARE_HASLO NOWE_HASLO

Jak przekierować porty za pomocą SSH?

Przekierowania mogą być realizowane przez zaszyfrowane tunele i dlatego są uważane za dobry sposób zabezpieczenia zawartości ruchu sieciowego. Jest to połączenie routingu i przepisania pakietów – dlatego, że aby dostarczyć pakiety danych do docelowej usługi sieciowej, trzeba zmienić ich docelowy IP, docelowy port lub jedno i drugie. Przepisanie takie musi być z punktu widzenia użytkownika przezroczyste, tak by gdy sądzi on, że łączy się z portem 23, a faktycznie połączenie następuje na porcie 2323, nie było różnicy w funkcjonowaniu usługi.

Przekierowanie można uzyskać za pomocą ustawienia reguł dla zapory sieciowej albo też za pomocą oprogramowania takiego jak SSH. Zaletą wykorzystania SSH jest to, że możemy to zrobić bez konieczności zmiany konfiguracji usług systemowych (do czego możemy też nie mieć uprawnień), a w dodatku nasze połączenia będą zaszyfrowane.

Załóżmy, że chcemy przekierować połączenia z portu 2323 naszego komputera na port 23 w maszynie zdalny.host.net:
ssh -L 2323:localhost:23 zdalny.host.net. -o "KeepAlive yes"


Flaga -L mówi klientowi SSH, by uruchomić lokalny tunel pomiędzy podanymi portami i maszynami, flaga -o zaś, by podtrzymać połączenie, nawet jeśli nie ma na nim żadnego ruchu sieciowego.

Po uruchomieniu połączenia zostajemy poproszeni o zalogowanie się do zdalnego systemu. Po zalogowaniu pomiędzy maszynami localhost i zdalny.host.net zostaje uruchomiony szyfrowany tunel. Teraz by np. uzyskać dostęp do usługi telnet na maszynie zdalny.host.net (normalnie niedostępnej), wystarczy wydać polecenie:
telnet localhost 2323


UWAGA: Przekierowanie portów wymaga praw administratora tylko wtedy, gdy otwieramy tunel do portów uprzywilejowanych, o numerze od 0 do 1023. Podany w przykładzie port 2323 może być oczywiście wykorzystany przez każdego użytkownika.

Zamiast usługi telnet możemy w ten sposób przekierować np. połączenia FTP czy SCP.

HTTPS: jak uruchomić SSL w serwerze Apache?

Potrzebna nam będzie działająca instalacja serwera Apache oraz pakiet OpenSSL. Apache powinien dysponować modułem mod_ssl. Może on być albo wkompilowany w serwer, albo ładowany oddzielnie. O tym, że mod_ssl został wkompilowany w serwer, możemy się przekonać, wydając polecenie apache2 -l (lub httpd -l – w zależności od systemu, na jakim pracujemy). Jeśli zaś mod_ssl jest niezależnym modułem, to w katalogu z modułami Apache'a powinien znaleźć się plik mod_ssl.so. Jeżeli jednak mod_ssl nie występuje w żadnym z tych miejsc, musimy albo zrekompilować serwer, albo poszukać pakietu zawierającego ten moduł.
Generowanie klucza

Na początku należy stworzyć klucz i certyfikat, za pomocą którego dane będą szyfrowane i deszyfrowane z serwera WWW. Najlepiej wykorzystać w tym celu generator (pseudo)losowych znaków. Jeden z najlepszych generatorów liczb pseudolosowych można znaleźć w Sieci – to serwis www.random.org. Możemy w nim wygenerować łańcuchy dowolnej długości, składające się z cyfr oraz małych i dużych liter. Wygenerowany łańcuch zapisujemy do pliku, którym następnie „nakarmimy” generator liczb losowych OpenSSL-a.

Robimy to za pomocą komendy:
openssl genrsa -des3 -rand plik.txt -out serwer.klucz 1024

OpenSSL zapyta o hasło – może być ono dowolne. Problem tylko z tym, że przy każdym restarcie Apache'a będziemy musieli je podawać. Jeśli nie chcemy uwierzytelniać klucza serwera przy każdym jego uruchomieniu, można usunąć hasło za pomocą komendy:

openssl rsa -in serwer.klucz -out serwer.bezszyfru

Po podaniu klucza podanego w poprzednim kroku openssl generuje nam plik serwer.bez zawierający niezaszyfrowany klucz serwera.

Teraz, mimo że sami będziemy sobie podpisywali certyfikat, należy wygenerować żądanie podpisu certyfikatu. Robimy to komendą:

openssl req -new -key serwer.bezszyfru -out serwer.cert

OpenSSL zapyta nas o rozmaite informacje, takie jak kod ISO kraju (np. PL), miasto, nazwę organizacji lub firmy czy też nasze nazwisko. Jeżeli nie chcemy się zbytnio nad tym wszystkim rozwodzić, to możemy pozostawić wszystkie pola puste.

Kolejny krok polega na podpisaniu certyfikatu. Robi się to za pomocą komendy:

openssl x509 -req -in serwer.cert -signkey serwer.bezszyfru -out serwer.cert

Oczywiście, nie ma się co łudzić, że ktoś będzie honorował nasz podpis. Ostatecznie nie jesteśmy VeriSignem czy Thawte i przeglądarki będą wyświetlały ostrzeżenie, że nasz certyfikat jest nieważny.

Stworzone w ten sposób pliki należy skopiować do katalogu konfiguracyjnego Apache'a i tak ustawić ich prawa dostępu, aby były one odczytywalne tylko dla roota. Można to zrobić następująco:

find /etc/apache2/serwer* -type f |xargs chmod 400

Jest to szczególnie ważne, jeżeli zdecydowaliśmy się nie szyfrować naszego klucza.

Konfigurowanie serwera

Pierwszą czynnością jest tu sprawdzenie w głównym pliku konfiguracyjnym Apache'a apache2.conf (lub httpd.conf), czy moduł mod_ssl jest ładowany (jeśli nie jest wkompilowany w serwer). Jeżeli jej nie ma, musimy dodać dyrektywę Load Module, której argumentami są ssl_module i ścieżka do pliku mod_ssl.so. Należy też usunąć znak # przed dyrektywą Include httpd-ssl.conf.

Następnie trzeba wprowadzić zmiany w pliku httpd-ssl.conf. W sekcji VirtualHost należy sprawdzić, czy dyrektywa DocumentRoot jest ustawiona na miejsce, w którym chcemy hostować bezpieczne strony. Domyślnie jest to zwykły katalog WWW – najczęściej htdocs, lepiej jednak stworzyć dla nich osobne miejsce – np. /var/www/htdocs-ssl.
Linia, która zaczyna się od frazy SSLCipherSuite, jest listą dozwolonych i zabronionych standardów szyfrowania. Kolejność, w jakiej się one znajdują, wyznacza ich priorytet podczas wyboru. To, co tutaj wybierzemy, zależy już od naszej polityki bezpieczeństwa. Im większe wymagania, tym więcej użytkowników ze starymi przeglądarkami pozostawiamy „na lodzie”. Blog InfiniteSecond zaleca zastosowanie następującej polityki:

SSLCipherSuite DHE-RSA-AES256-SHA:EDH-RSA-DES-CBC3-SHA:DHE-RSA-AES128-SHA: AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA

Z innymi, słabszymi wersjami można się zapoznać na stronie infinitesecond.blogspot.com/2008/03/recommended-sslciphersuite.html.

Teraz należy przejść do linii zaczynających się od SSLCertificateFile i SSLCertificateKeyFile, jako ich argumenty podając nazwy wygenerowanych wcześniej plików (odpowiednio serwer.cert i serwer.bezszyfru).

Ostatnią czynnością jest stworzenie zestawu reguł dla katalogu zawierającego bezpieczne strony – może to być coś takiego, choć oczywiście nie jest to zbyt restrykcyjne ustawienie:


Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all


Teraz po restarcie serwera Apache (/etc/init.d/apache2 restart), jeżeli wejdziemy na naszą stronę, korzystając z protokołu https:// (a nie http://), przeglądarka poinformuje nas, że korzystamy z bezpiecznego połączenia, wyświetlając w Pasku statusu małą kłódeczkę.

Jak zablokować dostęp do strony WWW dla poszczególnych krajów? [.htaccess]

Czasem zdarza się, że chcemy, aby nasza strona internetowa była np. dostępna tylko dla internautów z Polski. Mogliśmy na przykład podpisać umowę z dostawcami treści, którzy zakazują nam udostępniania ich materiałów poza Rzeczpospolitą. Jak rozwiązać taki problem?

Dla osób korzystających z serwera Apache, pomocą okaże się odpowiednie przygotowanie pliku .htaccess. Ręcznie tego raczej jednak nie zrobimy: przygotowanie odpowiedniego ciągu zablokowanych adresów IP to niezwykle nużące zadanie. Dlatego możemy skorzystać z API geolokalizacji IP, dostarczanego przez serwis blogama.org oraz specjalnego skryptu, który wygeneruje nam plik dostępowy.

Wpierw jednak należy zrozumieć, jak działają reguły w pliku .htaccess. Jeśli ustawimy własność allow dla krajów "PL, DE" (Polska i Niemcy), dopuszczony będzie tylko ruch przychodzący z Polski i Niemiec. Jeśli ustawimy własność deny dla "US, CA", zablokowany będzie tylko ruch przychodzący ze Stanów Zjednoczonych i Kanady.

Wygenerowanie pliku .htaccess za pomocą API geolokalizacji IP jest bardzo proste – usługa dostępna jest pod adresem iplocationtools.com. Przykładowo wygenerowany plik .htaccess może wyglądać następująco:

iplocationtools.com/country_query.php?country=PL&output=htaccess_allow

gdzie parametr country określa listę kodów krajów, oddzielonych od siebie przecinkami, zaś output to typ blokowania.

W rezultacie otrzymamy plik wyglądający następująco:

#COUNTRY_BLOCK_START



order deny,allow
allow from 57.66.162.0/24
allow from 57.66.195.0/26
allow from 57.66.195.64/27
allow from 57.66.195.96/28

[…]

deny from all



#COUNTRY_BLOCK_END



Jednak bloki IP często przechodzą z rąk do rąk. Generowanie za każdym razem pliku .htaccess mogłoby się okazać niewygodne. Pomóc może nam skrypt, stworzony przez autorów mechanizmu geolokalizacji z blogama.org.

Zanim go uruchomimy, należy w katalogu roboczym z którego korzystamy stworzyć plik htaccessfile.txt, do którego wprowadzamy wszystkie ścieżki dostępowe do plików .htacces, które chcemy zmieniać. Na przykład:

/var/www/mojblog.pl/.htaccess
/var/www/mojafirma.pl/.htaccess

W samym skrypcie na początku można znaleźć parametry konfiguracyjne:

WORKDIR="/var/www/" – katalog z prawami zapisu, w którym umieszczony jest skrypt,
HTACCESSFILE="htaccessfile.txt" – plik ze ścieżkami dostępu do plików .htaccess,
HTACCESSBLOCK="htaccess-blocklist.txt" – plik roboczy,
TEMPFILE="htaccess.temp" – plik roboczy,
COUNTRIES="PL" – lista krajów,
TYPE="allow" – typ dostępu: ekskluzywny (allow) lub inkluzywny (deny).

Następnie należy nadać skryptowi prawa wykonawcze:
chmod +x nazwaskryptu.sh


i dodać go do crontabu

* * * * * /ścieżka/nazwaskryptu.sh >/dev/null 2>&1



Dzięki temu będziemy mogli regularnie aktualizować bazę zablokowanych (bądź dopuszczonych) adresów.

A oto wspomiany skrypt:
#!/bin/bash
###BLOGAMA.ORG###
###MODIFY THIS SECTION###
WORKDIR="/var/www/"
HTACCESSFILE="htaccessfile.txt"
HTACCESSBLOCK="htaccess-blocklist.txt"
TEMPFILE="htaccess.temp"
COUNTRIES="PL"
TYPE="allow"
#########################
#####DO NOT MAKE MODIFICATIONS BELOW#####
cd $WORKDIR
#Get the file from blogama.org API
wget -c --output-document=$HTACCESSBLOCK "http://blogama.org/country_query.php?country=$COUNTRIES&output=htaccess_$TYPE"
for i in $( cat $WORKDIR$HTACCESSFILE ); do
if [ -f $i ]; then
cat $i 2>&1 | grep "COUNTRY_BLOCK_START"
if [ "$?" -ne "1" ]; then #ALREADY IN HTACCESS
sed '/#COUNTRY_BLOCK_START/,/#COUNTRY_BLOCK_END/d' $i > $WORKDIR$TEMPFILE
cat $WORKDIR$HTACCESSBLOCK >> $WORKDIR$TEMPFILE
mv $WORKDIR$TEMPFILE $i
else #NOT IN HTACCESS
cat $WORKDIR$HTACCESSBLOCK >> $i
fi
fi
done
rm -f $WORKDIR$HTACCESSBLOCK

Jak sprawdzić bezpieczeństwo sieci bezprzewodowej?

narzędzi, działających w środowisku Windows, ale ich możliwości są nieco ograniczone, ze względu na ograniczenia sterowników WiFi dla systemu z Redmond). Możemy wykorzystać zarówno popularne Ubuntu, Fedorę czy OpenSUSE, jak i specjalizowane dystrybucje do audytów bezpieczeństwa, takie jak Backtrack (który ma m.in. tę zaletę, że można go uruchomić z pendrive'a, bez konieczności instalowania na dysku twardym komputera). BackTrack zawiera od razu gotowe wszystkie potrzebne narzędzia bezpieczeństwa. Jego najnowszą wersję 4 Prerelease można pobrać ze strony www.remote-exploit.org/backtrack_download.html.

Do testów wykorzystamy zaś zestaw skryptów aircrack-ng, który pozwala zarówno na monitoring ruchu sieciowego, jak i wstrzykiwanie do niego odpowiednio spreparowanych pakietów. Aircrack-ng jest dostępny zarówno na stronie projektu, jak i w repozytoriach popularnych dystrybucji. Jego instalacja sprowadza się do wydania polecenia sudo apt-get install aircrack-ng (Debian, Ubuntu) czy yum install aircrack-ng (Fedora).

Potrzebujemy też w komputerze karty sieciowej, która będzie kompatybilna z aircrackiem. Z listą obsługiwanych układów można zapoznać się na stronie www.aircrack-ng.org/doku.php?id=compatibility_drivers.

Najwygodniej jest wykorzystywać taki program terminala, który pozwala nam używać wielu sesji powłoki w kartach – będziemy bowiem jednocześnie używać wielu skryptów z pakietu aircrack-ng. Może to być np. Konsola środowiska KDE czy Terminal środowiska GNOME.
Monitoring

Pierwszym krokiem jest rozpoczęcie monitorowania ruchu sieciowego do punktu dostępowego, który będziemy testować, tak aby nie nawiązywać z nim połączenia. Zakładając, że nasza karta sieciowa nosi w systemie nazwę wlan0 (można to sprawdzić, wydając polecenie iwconfig, przedstawiające listę aktywnych interfejsów sieciowych z rozszerzeniem WiFi), uzyskujemy uprawnienia roota poleceniem su - (lub używamy sudo)a następnie wpisujemy w powłoce polecenie:

airmon-ng start wlan0

jeśli wszystko pójdzie dobrze, powinniśmy otrzymać komunikat podobny do tego, jak na poniższym zrzucie ekranu.

Teraz polecenie iwconfig powinno pokazać nam, że dysponujemy specjalnym interfejsem sieciowym mon0. Za jego pomocą będziemy monitorować ruch sieciowy. Wydajemy więc polecenie (jako root):

airodump-ng mon0

W efektcie uzyskujemy listę wszystkich punktów dostępowych w otoczeniu: ich adres MAC (BSSID), dane o sile sygnału, generowanym ruchu, przesyłanych danych, kanale na którym odbywa się transmisja, rodzaju szyfrowania i uwierzytelnienia oraz nazwie punktu (ESSID).

Poniżej wyświetlana jest lista klientów łączących się z danymi sieciami bezprzewodowymi. Gdy znajdziemy już na liście sieć, którą chcemy przetestować, zapiszmy do pliku tekstowego informacje o kanale, na którym działa oraz jej adres MAC (BSSID). Zapiszmy też informacje o wszystkich klientach (STATION) powiązanych z danym BSSID sieci. Teraz możemy przerwać już działanie airodump, wciskając kombinację klawiszy Ctrl-C.

Przechwytywanie

Teraz uruchomimy ponownie airodump-ng, tak aby zbierać pakiety dla danej sieci bezprzewodowej i zapisywać je do pliku. Jeśli nasz punkt dostępowy działa np. na kanale 11, jego BSSID to 00:00:0A:FF:01:DD, monitorujący interfejs sieciowy nazywa się mon0, a plik, do którego będziemy zapisywać pakiety to wifi_zrzut, wydajemy polecenie:

airodump-ng --channel 11 --bssid 00:00:0A:FF:01:DD --write wifi_zrzut mon0

Teraz pozostaje czekać – powinniśmy zgromadzić około 40 tysięcy pakietów, aby dostać się do klucza WEP. Może to w wypadku niezbyt aktywnych punktów dostępowych zająć wiele godzin, dlatego zmusimy router WiFi, aby wygenerował nam dodatkowe pakiety dzięki narzędziu aireplay-ng.
Wstrzykiwanie

Uruchamiamy drugą sesję terminala (w pierwszej działa airodump-ng). Listę ataków można zobaczyć po wpisaniu polecenia aireplay-ng. Standardowo wykorzystywany jest atak wykorzystujący pakiety ARP. Jeśli mamy spisany BSSID klienta, korzystającego z punktu dostępowego, tym lepiej. W przeciwnym razie możliwe, że nasze połączenie zostanie odrzucone. Ograniczymy się też do wysyłania 30 pakietów na sekundę.

Za pomocą polecenia

aireplay-ng -3 -b 00:00:0A:FF:01:DD -h FF:FF:FF:FF:FF:FF -x 30 mon0

rozpoczynamy wstrzykiwanie pakietów. Jak widać, parametr b określa adres MAC punktu dostępowego, parametr h określa MAC klienta, x odpowiada za liczbę pakietów wysyłanych na sekundę, a wlan0 to nazwa naszego interfejsu sieciowego.
Crackowanie

Po zebraniu pewnej liczby pakietów, możemy przystąpić do crackowania. W nowym terminalu spróbujemy uzyskać klucz WEP za pomocą polecenia (zakładając, że pakiety zapisujemy do pliku wifi_zrzut):

aircrack-ng wifi_zrzut*.cap

To rozpoczyna proces łamania hasła – jeśli zebraliśmy wystarczającą liczbę pakietów, powinniśmy uzyskać komunikat KEY FOUND! z komentarzem „Decrypted correctly: 100%”. Otrzymany klucz jest podany w postaci heksadecymalnej (np. 40:88:FF:A0:12) i może być wpisany jako hasło połączeniowe po usunięciu dwukropków.

Uwagi

Jeśli mamy problemy ze wstrzykiwaniem pakietów, warto sprawdzić nasz interfejs sieciowy, czy w ogóle daje taką możliwość, za pomocą polecenia aireplay-ng -9 wlan 0.

Jeśli potrzebujemy zmienić adres MAC naszego interfejsu sieciowego na np. 11:22:33:44:55:66 (ponieważ punkt dostępowy wykorzystuje filtrowanie po adresach MAC), wykorzystujemy polecenia ifconfig wlan0 down && ifconfig wlan0 hw ether 11:22:33:44:55:66 && ifconfig wlan0 up.


WPA-PSK

Atak na klucz WPA-PSK jest atakiem słownikowym, dlatego im lepszy mamy słownik, tym większe nasze szanse na pokonanie tego zabezpieczenia. Dobre słowniki znajdziecie w naszym dziale download . Pamiętajcie też, że atak jest możliwy tylko wtedy, gdy z AP połączony jest przynajmniej jeden klient.
1. Otwieramy pierwszy terminal i wpisujemy:
#ifconfig ath0 up



#airmon.sh start ath0






Karta działa teraz w trybie monitoringu.

2. Teraz zobaczymy co słychać w eterze:
#airodump ath0 x 0 1






3. Na kanale ... widzimy sieć zabezpieczoną kluczem WEP. Przyjrzyjmy się jej bliżej:
#airodump ath0 x ... 1






4. Otwieramy drugi terminal
Stosujemy atak 0 (deauthentication) na jednym z klientów połączonych z AP. Spowoduje to jego rozłączenie i ponowne połączenie z 4 etapowym procesem wymiany klucza WPA_PSK (tzw. WPA handshake - uścisk dłoni), który przechwyci airodump.
#aireplay -0 15 -a 3e:00:20:xx:xx:xx -c 10:00:1e:yy:yy:yy ath0






5. Otwieramy trzeci terminal i włączamy aircracka w celu sprawdzenia, czy airodump przechwycil WPA-handshake.
#aircrack -w /katalog_ze_slownikiem/slownik.txt







Jeżeli przy danej sieci zobaczymy przechwycony WPA-handshake, wtedy wybieramy ją i rozpoczyna się proces łamania klucza WPA-PSK.



Możemy wtedy zamkąć pierwszy i drugi terminal. Jeżeli klucz WPA był w słowniku, to po pewnym czasie nasz atak zakończy się sukcesem:


UWAGA!: PAKIET AIRCRACK DZIAŁA W PEŁNI TYLKO Z ODPOWIEDNIMI KARTAMI WLAN, JAKĄ KARTĘ KUPIĆ DOWIESZ SIĘ W DZIALE SPRZĘT!


To już wszystko, co chciałem Wam przekazać na temat AIRCRACKA, mam nadzieję, że zdobyte wiadomości wykorzystacie jedynie w celu rozwinięcia swojej wiedzy, nie łamiąc przy tym prawa!


Jak przyśpieszyć zapytania do bazy MySQL?

Oto garść porad, których zastosowanie powinno przyśpieszyć działanie twoich skryptów i odciążyć serwer baz danych. Większość z nich znajdzie zastosowanie ogólnie przy relacyjnych bazach danych, nie tylko przy MySQL-u.

Korzystaj z typu CHAR gdy tylko to jest możliwe (zamiast VARCHAR, BLOB czy TEXT). Wiele kolumn na pewno będzie zawierało pola o stałej długości – np. polski numer IBAN to zawsze 26 znaków. Dane z kolumn typu CHAR mogą być znacznie szybciej przeszukane, niż z kolumn innych typów.

Zaoszczędź na pamięci wykorzystywanej na każdą kolumnę, deklarując jej rozmiar na tyle tylko, aby wystarczyło na zachowanie przechowywanych wartości.

Jeśli kolumna nie jest pusta, zadeklaruj to za pomocą NOT NULL. To przyśpieszy przeszukiwanie tabeli.

Nie dziel tabeli, jeśli wydaje ci się, że masz zbyt wiele kolumn. Podczas uzyskiwania dostępu do wiersza, najwięcej czasu zajmuje wyszukanie pierwszego bajtu w wierszu.

Jeśli przeszukujesz wiersze w tej samej kolejności (np. wyr1, wyr2, wyr3, …), zoptymalizuj tabelę za pomocą polecenia ALTER TABLE … ORDER BY wyr1, wyr2, wyr3.

Nie używaj pętli PHP aby pobrać z bazy dany wiersze jeden po drugim. Zamiast tego lepiej skorzystać z dyrektywy IN, np. tak: SELECT * FROM 'tabela' WHERE 'id' IN (1,3,5,9,11);

Nie trzymaj w bazie plików binarnych (np. obrazków) – najlepiej by były one zachowane na dysku jako pliki, a w bazie znajdowały się tylko odnośniki do nich.

Jeśli musisz w bazie trzymać pliki tekstowe o dużych rozmiarach, sprawdź, czy nie lepiej zadeklarować typu kolumny jako BLOB, wprowadzać dane po ich skompresowaniu gzipem, a następnie dekompresować już w aplikacji.

Jeśli ładujesz tabelę z pliku tekstowego, wykorzystaj polecenie LOAD DATA INFILE. Jest bardzo szybkie.

Dane o sesji użytkownika, jak i wszelkie inne niekrytyczne dane, warto trzymać w tabeli MEMORY. Jest o wiele szybsza niż inne. Tabelę taką zakłada się poleceniem CREATE TABLE test ENGINE=MEMORY;.

Porzuć REPLACE. REPLACE to złożenie DELETE i INSERT. Lepiej jest użyć INSERT … ON DUPLICATE KEY UPDATE (czyli INSERT oraz UPDATE, jeśli doszło do konfliktu).

Unikaj stosowania klauzuli HAVING. Jest dość powolna.

Grupuj podobne INSERT-y w jeden długi INSERT z wieloma wartościami, tak aby wstawić wiele wierszy jednocześnie. Każde połączenie, przesłanie i parsowanie kwerendy zajmuje kilkukrotnie dłużej niż samo wstawienie danych. Jeśli takie zgrupowanie jest niemożliwe, to jeśli korzystasz z engine'u InnoDB, wypróbuj START TRANSACTION oraz COMMIT. Jeśli jest to MyISAM, zastosuj LOCK TABLES – wówczas bufor indeksu będzie napełniany tylko raz, po wszystkich INSERT-ach. (Pamiętaj jednak, żeby co kilkaset wierszy otwierać (unlock) tabele, aby inne wątki miały do nich dostęp).

Korzystaj z funkcji BENCHMARK, aby przetestować poszególne wyrażenia.


Wyłączenie konta root

Takie ustawienie jest akurat domyślne w Ubuntu. Użytkownicy innych dystrybucji powinni sprawdzić, czy mają dostęp do sudo za pomocą komendy visudo. Służy ona bezpiecznej edycji pliku sudoers. Następnie należy dodać do niej linijkę nazwauzytkownika ALL=(ALL) ALL.

Następnie można zablokować konto roota za pomocą komendy sudo passwd -l root.
Zablokowanie dostępu do SSH

Należy to zrobić blokując logowanie dla roota, wyłączając uwierzytelnianie przez hasła i ustawiając odpowiednie wpisy w pliku denyhost.

Aby wyłączyć logowanie roota, należy w pliku /etc/ssh/ssd_config znaleźć linię PermitRootLogin yes i zmienić ją na PermitRootLogin no.

Aby wyłączyć uwierzytelnianie przez hasło (stosowane wówczas będą tylko klucze publiczne), należy we wspomnianym wyżej pliku zmienić linię #PasswordAuthentication yes na PasswordAuthentication no.

Denyhosts wymaga dodatkowej instalacji – najprościej zrobić to za pomocą komendy sudo apt-get install denyhosts. Ustawienia aplikacji można znaleźć w /etc/denyhosts.conf.
Aktualizacja systemu: cron-apt

Pamiętanie o samodzielnej, regularnej aktualizacji systemu może być problematyczne. Jeśli lista naszych repozytoriów wskazuje tylko na te, które związane są z poprawkami bezpieczeństwa, warto zautomatyzować ten proces. W Debianie i Ubuntu można w tym celu wykorzystać cron-apt. Instaluje się go poleceniem sudo apt-get install cron-apt. Potem należy tylko ustawić swój adres e-mailowy w pliku /etc/cron-apt/config, pole MAILTO=. Według standardowych ustawień cron-apt będzie aktualizował system codziennie, o 4 nad ranem. Można to zmienić w pliku /etc/cron.d/cron-apt.
Restrykcyjna konfiguracja zapory sieciowej (firewalla)

Zestawiając reguły zapory sieciowej, pozwól tylko na takie połączenia, jakie naprawdę są potrzebne. IPtables to potężne narzędzie, a w Sieci dostępnych jest wiele gotowych, dobrze działających konfiguracji. Przykładowo reguły dla maszyny, która działać ma tylko jako serwer WWW, zarządzany przez SSH, mogłyby wyglądać następująco
iptables -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport 22 --sport 1024:65535 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport 80 --sport 1024:65535 -m state --state NEW -j ACCEPT



Zakładając oczywiście, że eth0 to nasz interfejs sieciowy, a połączenia HTTP i SSH odbywają się odpowiednio na portach 80 i 22.

Samodzielne pisanie reguł dla IPtables nie jest proste, ale pomóc w tym może wiele wygodnych do tego narzędzi. Spośród nich warto polecić takie aplikacje jak shorewall i firewall builder.
Zabezpieczenie PHP za pomocą Suhosin

Suhosin to system ochronny dla PHP, który pozwala na zabezpieczenie serwerów i użytkowników przed konsekwencjami znanych i nieznanych błędów w rdzeniu PHP. Prowadzi on czasem do problemów z kompatybilnością źle napisanych skryptów. Najprościej zainstalować go pisząc sudo apt-get install php5-suhosin. Następnie należy w pliku /etc/php5/conf.d/suhosin.ini wpisać linię extension=suhosin.so.
Zabezpieczenie bazy danych MySQL

Niezłym pomysłem na zabezpieczenie serwera baz danych przed włamaniem jest zablokowanie logowania jako root z LAMP-owego serwera, tak aby np. można było to zrobić tylko z poziomu laptopa administratora. Polecenie mysql update user set host = 'x.x.x.x' where user="root" (gdzie x.x.x.x oznacza adres IP komputera, z którego można się będzie logować), uniemożliwi osobom, które miałyby konto z prawami roota, zalogowanie się do bazy danych.

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.

Co to jest .htaccess

Wielu osobom skrót .htaccess kojarzy się przede wszystkim z możliwością kontrolowania dostępu do strony internetowej za pomocą hasła. I choć jest to rzeczywiście jedno z bardziej popularnych zastosowań tego pliku, to jego rola jest znacznie szersza. Mechanizm .htaccess został zaprojektowany jako narzędzie do zmiany konfiguracji Apache’a w odniesieniu do pojedynczych katalogów na serwerze. W ten sposób nawet zwykły użytkownik może zmodyfikować ustawienia Apache’a, aktywując funkcje obsługi skryptów CGI i przetwarzania dyrektyw SSI czy ograniczając dostęp osób do strony z konkretnego adresu IP. Pliki .htaccess są także wykorzystywane do przygotowywania własnych stron błędów generowanych przez serwer. I to wszystko jest możliwe na poziomie pojedynczego katalogu w serwisie internetowym. Dla wszystkich naraz lub każdego z osobna.

Warto jednak wiedzieć, że ustawienia wprowadzane do konfiguracji przez .htaccess mogą być równie dobrze definiowane na poziomie głównego pliku ustawień Apache’a. Jakby tego było mało, dokumentacja serwera wprost odradza stosowanie .htaccess, jeżeli nie mamy ku temu wyraźnych przesłanek. Kiedy zatem nie powinniśmy używać tego mechanizmu? Podstawowa odpowiedź na to pytanie brzmi: wtedy, gdy mamy dostęp do plików konfiguracyjnych serwera. Reguły zapisane w .htaccess możemy z powodzeniem zawrzeć w ramach dyrektywy w głównym pliku ustawień Apache’a. Podejście to ma dwie kluczowe przesłanki. Pierwsza z nich związana jest ze zwiększonym obciążeniem serwera. Komputer, który musi przetwarzać dodatkowe reguły zapisane w kilku-kilkudziesięciu plikach konfiguracyjnych, potrzebuje więcej zasobów. Druga dotyczy bezpieczeństwa: jeżeli udostępniamy możliwość zmiany konfiguracji Apache’a, to w pewnym zakresie tracimy nad nim kontrolę. Użytkownicy mogą modyfikować jego ustawienia, co potencjalnie może prowadzić do naruszenia zasad bezpieczeństwa.

Mimo tych zastrzeżeń mechanizm .htaccess jest bardzo przydatnym narzędziem. Jeśli korzystamy z usług dostawcy hostingu, to dostęp do .htaccess umożliwi nam uruchomienie serwera WWW zgodnie z naszymi oczekiwaniami. Z drugiej strony, jeżeli jesteśmy właścicielami serwera i mamy do niego dostęp z uprawnieniami administratora, powinniśmy rozważyć konfigurację Apache’a na poziomie głównych plików konfiguracyjnych.

Admin musi pozwolić

Włączenie mechanizmu .htaccess odbywa się w głównych plikach konfiguracyjnych Apache’a. To właśnie tu decydujemy, czy możliwe będzie użycie plików .htaccess, a jeżeli tak, to w jakim zakresie. Służy do tego dyrektywa AllowOverride definiowana w sekcji dla głównego katalogu serwera lub jego podkatalogów. Dyrektywa ta może przyjmować wartość None, All, AuthConfig, FileInfo, Indexes, Limit oraz Options. Jak łatwo się domyślić, ustawienie tej opcji na
AllowOverride None

wyłącza użycie plików .htaccess. Serwer nie uwzględni wówczas konfiguracji w nich zapisanej, nawet jeżeli istnieją one w odpowiednich katalogach. Z kolei zastąpienie słowa None wpisem All zezwoli na użycie .htaccess w pełnym zakresie. Administrator może również przyznać uprawnienia tylko do zmiany niektórych jego ustawień. Służą do tego dyrektywy grup:
AuthConfig – włączenie mechanizmów autoryzacji odwiedzających stronę,
FileInfo – zmiana typu dokumentów (MIME, strony błędów),
Indexes – modyfikacja ustawień związanych z obsługą katalogów (strona główna, listowanie katalogów),
Limit – limitowanie dostępu do strony za pomocą mechanizmu zezwól/odmów (allow/deny),
Options – kontrolowanie opcji specyficznych dla katalogów (np. włączanie CGI, SSI itd.).

Opcje te można ze sobą łączyć, a zatem, aby zezwolić użytkownikom na zmianę konfiguracji serwera w zakresie autoryzacji i limitowania dostępu do serwera w ustawieniach Apache’a dla wybranego katalogu (sekcja Directory), wprowadzamy zapis:
AllowOverride AuthConfig Limit

Szczegółowe informacje na ten temat zostały zawarte w dokumentacji Apache’a [1]. Warto ją przeczytać, jeżeli chcemy dokładnie poznać znaczenie dyrektywy AllowOverride.

Choć poniższą poradę należy traktować raczej jako ciekawostkę, to niektórzy zechcą zrobić z niej użytek. Warto wiedzieć, że plik .htaccess może mieć dowolną inną nazwę, o ile wskażemy to w konfiguracji Apache’a. Służy do tego dyrektywa AccessFileName definiowana w ustawieniach serwera. Ma ona następującą składnię:
AccessFileName .configuration

gdzie .configuration oznacza nową nazwę pliku, który będzie odczytywany w poszukiwaniu lokalnej konfiguracji serwera.

Tworzenie .htaccess

Plik .htaccess jest zwykłym plikiem tekstowym ASCII. Jest on czytelny dla człowieka i może zostać utworzony za pomocą dowolnego edytora, np. Notatnika w Windows czy Vim lub Emacs w Linuksie. Zachowując zmiany, warto zwrócić uwagę na dość nietypową, szczególnie w środowisku Windows, jego nazwę. Rozpoczyna się ona kropką, po której następuje coś na kształt rozszerzenia. I choć jest to plik tekstowy, nie ma on przyrostka .txt. Tak przygotowany zbiór przenosimy na serwer np. za pomocą protokołu FTP. Trzeba pamiętać, aby skopiować go w trybie transmisji ASCII, a nie binarnym.

Zbiór .htaccess „działa” w obrębie katalogu, w którym został umieszczony, oraz wszystkich jego podfolderach. Jeżeli zatem zapiszemy .htaccess w katalogu głównym serwera, zmiany w nim wprowadzone obejmą swoim zasięgiem cały serwis WWW. Nic nie stoi na przeszkodzie, aby w każdym z podkatalogów zdefiniować osobny plik .htaccess. Ale uwaga: parametry ustawień zawarte w .htaccess zapisanych w danym katalogu zastępują te ustalone na poziomie głównego pliku konfiguracyjnego serwera i wszystkich plików umieszczonych wyżej w strukturze drzewa katalogów.

Dostęp na hasło

Użycie haseł to najprostsza metoda na ograniczenie dostępu do naszej strony lub wybranego jej katalogu. Zanim odwiedzający obejrzy zawartość serwisu, będzie musiał wprowadzić nazwę użytkownika i hasło. Choć mechanizm ten możemy zaimplementować, korzystając z języków programowania (PHP, JavaScript itd.), znacznie szybciej podobny efekt uzyskamy, gdy zastosujemy zbiory .htaccess.

Na początek przygotowujemy plik zawierający hasła dostępu wraz ze skojarzonymi z nimi osobami (nazwami użytkownika). Jest to zbiór tekstowy .htpasswd, w którym hasła są zaszyfrowane za pomocą algorytmu MD5. Z tego też względu do wykonania tego zadania posłużymy się programem htpasswd dostarczanym wraz z Apache’em. Jest on zazwyczaj dostępny w domyślnej ścieżce przeszukiwania serwera, a jego uruchomienie powinno mieć następującą postać:
htpasswd -c /home/apache/hasla/.htpasswd janek

gdzie /home/apache/hasla/ jest ścieżką do katalogu, w którym będziemy przechowywali hasła, .htpasswd nazwą pliku je przechowującym, a janek to użytkownik, dla którego definiujemy dostęp. Na koniec pozostaje nam dwukrotnie wprowadzić hasło i pamiętać, że pliki te powinny być przechowywane poza miejscem, w którym udostępniamy stronę WWW. Inaczej mówiąc, hasła zapisujemy w katalogu, do którego ma dostęp serwer Apache, ale który nie jest osiągalny z poziomu przeglądarki internetowej. Aby dopisać dodatkowych użytkowników do pliku z hasłami w kolejnym wywołaniu htpasswd, pomijamy parametr -c.

Gdy pierwszy krok mamy za sobą, w pliku .htaccess definiujemy reguły autoryzacji użytkowników. Przykładowe wpisy mogą mieć następującą postać:
AuthType Basic
AuthName "Galeria zdjec"
AuthUserFile /home/apache/hasla/.htpasswd
Require user janek franek iza

gdzie parametr AuthUserFile określa ścieżkę do pliku .htpasswd, janek, franek oraz iza są natomiast osobami uprawnionymi do przeglądania danego zasobu. Zamiast wymieniać użytkownika z osobna, możemy posłużyć się parametrem valid-user:
require valid-user

Wówczas wszyscy użytkownicy mający odpowiednie wpisy w .htpasswd będą mogli logować się do serwisu. Pole AuthName zawiera informację, którą możemy przekazać użytkownikom, a która identyfikuje nasz serwis. Pojawi się ona w okienku logowania do strefy chronionej hasłem. Z kolei AuthType wskazuje typ autoryzacji HTTP. W tym przypadku jest to Basic.

Nasze reguły możemy wzbogacić o funkcję ograniczającą dostęp do strony tylko z wybranego adresu IP, puli adresów lub domeny, np.:
Access allow 40.53.218.11
Access allow serwer.pl

Wróćmy jednak do pliku .htpasswd. Przykładowa jego zawartość może mieć postać:
janek:Epowp5bTSabac
franek:IqOcGapAdnEmI

Choć hasła to zwykły ciąg znaków, już na pierwszy rzut oka widać, że są one zaszyfrowane przez program htpasswd. Jego użycie jest możliwe tylko wówczas, gdy mamy dostęp do linii komend serwera. Dostawcy hostingu niechętnie jednak oferują taką usługę. W takim przypadku musimy poradzić sobie w inny sposób. Pierwszy polega na wykorzystaniu mechanizmów w panelu administracyjnym serwera WWW. Operator umożliwia wówczas automatyczne wygenerowanie użytkowników i skojarzonych z nim haseł z poziomu zwykłej przeglądarki internetowej. Drugie rozwiązanie opiera się na programach działających online. Potrafią one wygenerować zaszyfrowane hasła, które następnie kopiujemy do pliku .htpasswd i przenosimy na serwer. Przykładowe generatory znajdziemy na stronach .htpasswd Content Generator [2] oraz .htpasswd generator [3].

Strony błędów

„404 File Not Found” – takim standardowym komunikatem serwer poinformuje nas, że strona, której zażądaliśmy, nie została odnaleziona. To jeden z najczęściej spotykanych błędów występujących podczas przeglądania Internetu. Predefiniowanych kodów zwracanych przez serwer jest znacznie więcej i dotyczą one m.in. wewnętrznych błędów serwera czy nieautoryzowanego dostępu do serwisu. Kody statusu nie muszą jednak wcale oznaczać błędu. Przykładowo: komunikat 200 OK. wysłany do przeglądarki informuje o odnalezieniu strony na serwerze. Obszerną listę kodów znajdziemy na stronach Wikipedii [4] oraz organizacji W3C [5].

Administrator strony internetowej może samodzielnie zadecydować, jaką akcje ma podjąć Apache w przypadku wystąpienia błędu. W praktyce najczęściej stosuje się mechanizm wyświetlania własnej strony (dokumentu) błędu zawierającej zrozumiały dla przeciętnego użytkownika przekaz o zaistniałej sytuacji zamiast surowego, technicznego komunikatu od serwera. Strony błędów mogą zostać zdefiniowane w pliku .htaccess. Jego konstrukcja jest bardzo prosta:
ErrorDocument 404 /komunikaty/nieznaleziono.html
ErrorDocument 403 "Nie masz dostępu do tej strony."
ErrorDocument 500 "/cgi-bin/obsluga_bledow.pl"
ErrorDocument 403 http://www.serwer.pl

Po słowie kluczowym ErrorDocument należy podać kod statusu oraz podejmowaną przez serwer akcję. Może to być załadowanie innej strony WWW (pierwszy wiersz przykładu), wyświetlenie komunikatu tekstowego (drugi wiersz), wywołanie skryptu (trzeci wiersz) czy po prostu przekierowanie do innego serwisu, także z innej domeny (czwarty wiersz). W przypadku gdy definiujemy własne strony błędów, np. w postaci pliku HTML, należy je odpowiednio wcześniej przygotować, przenieść na serwer i wskazać ścieżkę dostępu.

Zmiana strony startowej

Gdy wpiszemy w przeglądarce adres strony WWW obsługiwanej przez Apache’a, to przy standardowej jego konfiguracji automatycznie wyświetlana jest predefiniowana strona startowa. Jest to najczęściej plik index.html lub index.php umieszczony w głównym katalogu serwera. To powszechnie przyjęte nazewnictwo ma swoje odzwierciedlenie w konfiguracji Apache’a. Nazwa pliku startowego definiowana jest bowiem za pomocą parametru DirectoryIndex i najczęściej przyjmuje postać:
DirectoryIndex index.html index.htm index.php index.cgi

Kolejność wpisów ma tutaj znaczenie. I tak Apache najpierw będzie szukał pliku index.html, później index.htm, a na końcu index.cgi. Jeżeli z jakichś względów chcemy to domyślne zachowanie serwera zmienić, możemy użyć pliku .htaccess. Wystarczy, że umieścimy w nim wpis:
DirectoryIndex startowa.html

który nadpisze wartość tego parametru z głównego pliku konfiguracyjnego Apache’a. Od tego momentu domyślną stroną startową będzie plik startowa.html.

Blokowanie dostępu do strony

O ile .htpasswd umożliwia limitowanie dostępu do serwisu na poziomie użytkownika, tak mechanizm allow/deny pozwoli nam zablokować lub zezwolić na wyświetlanie strony osobom łączącym się ze wskazanego adresu IP, puli adresów czy domeny. Przykładowa konstrukcja wpisu w .htpasswd może wyglądać następująco:
order allow,deny
deny from serwer.pl
deny from 40.53.218.11
deny from 40.53.217.
allow from all

Parametr order pozwala ustalić kolejność przetwarzania dyrektyw allow i deny. W przypadku wpisu order allow,deny najpierw nakładane są warunki zezwalające na dostęp, a dopiero później te, które go zabraniają.

Na liście wpisów zamieszczamy tych, którym chcemy zablokować dostęp (w przykładzie tych z domeny serwer.pl oraz adresu 40.53.218.11 i całej puli adresów 40.53.217.), a następnie zezwalamy pozostałym (from all) na przeglądanie zasobów serwera.

CGI i SSI

Za pomocą .htaccess ustalimy także wiele innych parametrów pracy Apache’a. Nie sposób ich wszystkich wymienić, więc przytoczymy te najpopularniejsze. Aby możliwe było ich zaaplikowanie, dyrektywa AllowOverride musi być ustawiona na All lub w węższym zakresie na Options. Jeśli wybrany katalog serwera służy do przechowywania i wykonywania skryptów CGI, tworzymy dyrektywę:
Options +ExecCGI

I analogicznie, aby odebrać te prawa, jako parametr Options wpisujemy -ExecCGI. W podobny sposób włączymy obsługę mechanizmu SSI (Server Side Includes). Pozwala on na dynamiczne osadzanie wielu stron w jednym dokumencie. Jeżeli chcemy aktywować SSI dla wybranego katalogu, w .htaccess zamieszczamy wpis:
Options +Includes

Dodatkowo sprawdźmy, czy w głównym pliku konfiguracyjnym Apache’a zdefiniowano sposób obsługi CGI i SSI. Służą do tego dyrektywy:
AddHandler cgi-script .cgi
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml

Wpisy te możemy równie dobrze zamieścić w pliku .htaccess, o ile administrator przyznał dodatkowo możliwość modyfikacji ustawień z grupy FileInfo.

Listowanie katalogów

Na koniec chyba najprzyjemniejsza i najprostsza do zrozumienia dyrektywa Indexes. W niektórych domyślnych konfiguracjach serwera jest ona włączona. Jej działanie polega na wyświetlaniu zawartości katalogu, jeśli nie została wprowadzona pełna nazwa pliku oraz gdy nie istnieje plik startowy definiowany dyrektywą DirectoryIndex. Funkcja ta jest natomiast niezbyt chętnie udostępniana przez administratorów. Nie powinniśmy bowiem pozwalać odwiedzającym naszą stronę na przeglądanie zawartości katalogu, o ile oczywiście nie ma ku temu wyraźnych przesłanek. Aby zablokować listowanie wybranego katalogu, w pliku .htaccess umieszczamy wpis:
Options -Indexes

Analogicznie jak w poprzednich przypadkach, aby włączyć domyślnie nieaktywną funkcję listowania, znak minusa zastępujemy plusem. Warto zwrócić uwagę także na dyrektywę IndexIgnore. Pozwala ona na selektywne ograniczenie listowanych plików. Warto sprawdzić, czy nie jest ona już zdefiniowana w głównym pliku konfiguracyjnym. W wersji 2 serwera w dystrybucji znajduje się następujący wpis:
IndexIgnore .??* *~ *# RCS CVS *,v *,t

Ogranicza on listowanie m.in. plików rozpoczynających się od kropki, czyli choćby omawianego zbioru .htaccess. Zastosowano tutaj symbole wieloznaczne, np. * zastępującą dowolny ciąg znaków. W razie potrzeb możemy tę listę rozszerzyć o własne wpisy. Jeżeli nie chcemy, aby podczas wyświetlania zawartości katalogów były widoczne pliki graficzne (GIF, JPEG i PNG), możemy tę dyrektywę rozszerzyć o dodatkowe parametry:
IndexIgnore .??* *~ *# RCS CVS *,v *,t *.gif *jpg *jpeg *.png

Przedstawione zagadnienia nie wyczerpują możliwości, jakie daje użycie pliku .htaccsess. Żeby zachęcić do lepszego ich poznania, powiedzmy tylko tyle, że możliwe jest blokowanie botów czy bezpośrednich linków do plików na naszym serwerze.



Warto odwiedzić

[1] AllowOverride

http://httpd.apache.org/docs/2.2/mod/core.html#allowoverride

[2] .htpasswd Content Generator

http://home.flash.net/cgi-bin/pw.pl

[3] .htpasswd generator

http://www.htaccesstools.com/htpasswd-generator/

[4] Kody statusu protokołu HTTP

http://pl.wikipedia.org/wiki/Kod_odpowiedzi_HTTP

[5] Kody statusu protokołu HTTP (język angielski)

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

czwartek, 22 października 2009

Backup wszystkich baz danych mysql do pliku

#!/bin/sh
mysqldump --host=localhost --user=root --password=haslo --all-databases > all_databases.$(date +%F)
tar -zcf /home/mysql/all_databases.$(date +%F).tar.gz /home/mysql/all_databases.$(date +%F)
rm /home/mysql/all_databases.$(date +%F)
rm $(perl -e 'use POSIX qw(strftime); print strftime "all_databases.%F*",localtime(time-3600*24*7);')


A tak się importuje:

cat all_databases.2008-04-11 mysql -u root -p

Jak wyłączyć Śledzika z NK

Jak wyłączyć Śledzika?

Generalnie nie ma oficjalnej opcji 'wylacz' ale mozna go ukryc na stale poprzez modyfikacje w wyswietlaniu strony. Nie bedzie on wylaczony a jedynie bedzie niewidoczny ale efekt jest niemalze identyczny.

Internet Explorel

Wyłączenie śledzia dla Internet Explorel 7 i 8 Otwieramy notatnik i wpisujemy: #sledzik_box{display:none;} Zapisujemy plik np. na Pulpicie, o dowolnej nazwie ale z rozszerzeniem .css (np. 'sledzikssie.css')
W Internet Explorel wybieramy: Narzędzia -> Opcje internetowe -> Dostępność Zaznaczamy "Formatuj dokumenty używając mojego arkusza stylów" Przeglądaj i wybieramy nasz stworzony plik z np. Pulpitu sledzikssie.css

Firefox

1) pobieramy plugin: https://addons.mozilla.org/en-US/firefox/addon/2108

2) instalujemy

3) w Firefoxie wybieramy 'Narzędzia' -> 'Dodatki' i zaznaczamy zakladke 'Style'

4) klikamy na 'Stworz nowy styl' w prawym dolnym rogu

5) nadajemy mu nazwe i etykiete wedle wlasnego widzimisie

6) w duzym polu tekstowym wpisujemy:
#sledzik_box{display:none;}

7) wciskamy 'zapisz' i gotowe



Opera

1) Otwieramy notatnik i wpisujemy:
#sledzik_box{display:none;}

2) Zapisujemy plik w dowolnej lokalizacji, o dowolnej nazwie ale z rozszerzeniem .css (np. 'sledzikssie.css')

3) otwieramy opere i wybieramy 'Narzedzia' -> 'Preferencje'

4) wybieramy zakladke 'Zaawansowane'

5) wybieramy opcje 'Zawartosc'

6) wciskamy przycisk 'Opcje stylow'

7) na dole nowego okienka wciskamy 'wybierz' i szukamy naszego pliku stworzonego w punkcie 2

8) wybieramy nasz plik, klikamy ok i voila



Safari

1) Otwieramy notatnik i wpisujemy:
#sledzik_box{display:none;}

2) Zapisujemy plik w dowolnej lokalizacji, o dowolnej nazwie ale z rozszerzeniem .css (np. 'sledzikssie.css')

3) otwieramy safari, klikamy na kolo zebate w prawym gornym rogu i wybieramy 'Preferences' ( skrot ctrl+, )

4) Wybieramy zakladke advanced (zaawansowane)

5) Klikamy na opcje Style Sheet: 'None selected' i zaznaczamy 'Other...'

6) Otworzy nam sie okno wyboru pliku wiec szukamy naszego pliku stworzonego w punkcie 2

7) Zaznaczamy nasz plik, klikamy 'Open' i voila



Chrome

chyba nie ma opcji zmiany stylow przegladarki dla Chrome, na szybko nie znalazlem



Jezeli dodatkowo chcemy wylaczyc blog

W miejscu gdzie wpisujemy:
#sledzik_box{display:none;}

mozemy dodac nowa linijke i dopisac:
#promo_entry{display:none;}

i to zalatwi sprawe

Atak SQL Injection

SQL Injection - jeżeli masz do czynienia z bazami danych, zapewne to hasło nie jest Ci obce. Jeżeli jednak Twoja wiedza ogranicza się tylko do kilku mętnych faktów, bądź co gorsza nie wiesz co to w ogóle jest, czas najwyższy uzupełnić wiedzę! Osoby zaznajomione z kwestiami bezpieczeństwa (nie tylko komputerowego) wiedzą że zabezpieczenia są tak skuteczne jak najsłabszy element całego systemu zabezpieczeń. Nie pozwól aby Twoja Strona WWW lub program był tym najsłabszym ogniwem!
Przykłady ataków SQL Injection

Atak SQL Injection wykorzystuje fakt że dane wpisane do formularza na stronie WWW (lub w inny sposób wysłane do serwera) nie są w żaden sposób walidowane pod kątem ich poprawności. Do tego dochodzi fakt że w zapytaniach SQL stringi należy zamknąć pomiędzy znakami apostrofu. Zatem jeżeli ktoś wpisze do formularza ciąg znaków zawierający m.in. apostrof, różne rzeczy mogą się przytrafić - od zwykłego błędu wykonania zapytania SQL, aż po wykasowanie wszystkich danych z bazy danych czy dysku serwera, albo włamania do innych maszyn w sieci!

Najprostszy atak SQL Injection może wyglądać następująco: załóżmy że na stronie znajduje się następujący formularz:

Login:

Hasło:





Po stronie serwera, w kodzie PHP tworzone i wykonywane jest następujące zapytanie:
SELECT USER_ID FROM USERS WHERE (LOGIN='$login') AND (PASS='$pass')

Zmienne $login i $pass zawierają odpowiednio login i hasło wpisane w formularzu. Załóżmy że do systemu loguje się admin, posługując się swym bezpiecznym hasłem "jh*8!aaC4". Zapytanie które zostanie wykonane wygląda następująco:
SELECT USER_ID FROM USERS WHERE (LOGIN='admin') AND (PASS='jh*8!aaC4')

Jak na razie wszystko wygląda w porządku. Załóżmy jednak że nasz Czarny Kapelusz (Black Hat) próbuje się włamać, i wpisał jako hasło:
' OR '1'='1

Wynikowe zapytanie które zostanie wykonane będzie następujące:
SELECT USER_ID FROM USERS WHERE (LOGIN='admin') AND (PASS='' OR '1'='1')

Jak widać, w zapytaniu zmienił się warunek który sprawdza hasło - obecnie składa się on z sumy logicznej dwóch warunków: pierwszego który jest fałszywy (no chyba że admin nie ma założonego hasła, co jest mało prawdopodobne), i drugiego który jest zawsze prawdziwy. Wynik: napastnik zalogował się na konto admina bez znajomości (!) jego hasła.

Powyższy przykład ataku można zmodyfikować, wpisując następujący ciąg znaków jako nazwę użytkownika, i dowolne hasło (np. "a"):
admin') --

Wynikowe zapytanie które zostanie wykonane będzie następujące:
SELECT USER_ID FROM USERS WHERE (LOGIN='admin') --') AND (PASS='a')

W języku SQL dwa myślniki umieszczone obok siebie oznaczają początek komentarza, zatem w rezultacie wykona się tylko pierwsza część warunku WHERE (sprawdzenie nazwy użytkownika).

Napastnikowi może także nie zależeć na uzyskaniu nieautoryzowanego dostępu do serwera, ale na wyrządzeniu jak największych szkód. Może on tu skorzystać z faktu, że baza danych może wykonać kilka zapytań podanych po kolei (i ew. rozdzielonych średnikiem). Przykładowo może on wpisać coś takiego jako nazwę użytkownika:
') DELETE FROM USERS --

Wynik jest mało przyjemny - skasowana zostanie zawartość tabeli USERS. Napastnik może posunąć się jeszcze dalej, wpisując coś takiego:
') DROP DATABASE SKLEP --

Po wykonaniu tej komendy cała nasza baza danych przestaje istnieć! Jeżeli baza danych pozwala na wykonywanie poleceń systemowych, napastnik może także wykasować zawartość twardego dysku. Np. źle skonfigurowana baza danych MS SQL Server na Windows może pozwolić na wykonanie takiego ataku:
'); exec master..xp_cmdshell 'iisreset /stop' --

Wpisane powyższego ciągu znaków jako nazwy użytkownika spowoduje zatrzymanie serwera IIS (Internet Infomation Server, czyli serwer WWW Microsoftu). Jakie to może mieć skutki np. dla sklepu internetowego chyba nie muszę tłumaczyć. Poza tym w systemie istnieje cały szereg innych komend które napastnik może wykorzystać do złych celów.

Celem napastnika może nie być sianie zniszczenia, ale chęć kradzieży poufnych danych. Załóżmy że sklep internetowy pozwala na wyświetlenie listy produktów które zamówiło się w ostatnim czasie, za pomocą zapytania:
SELECT PRODUKT_ID, NAZWA, OPIS, KWOTA
FROM PRODUKTY, ZAMOWIENIA
WHERE (PRODUKTY.PRODUKT_ID=ZAMOWIENIA.PRODUKT.ID)
AND (KLIENT_ID=$id)
ORDER BY NAZWA

W tym przykładzie identyfikator klienta jest przekazywany z zewnątrz. W normalnej sytuacji jest to liczba; jeżeli jednak napastnik wpisze coś takiego:
0 OR 1=1

wtedy ostatnia linia warunku WHERE przybierze następującą postać:
AND (KLIENT_ID=0 OR 1=1)

Wynik: cała historia zamówień dokonanych przez wszystkich klientów sklepu wyświetli się na stronie.

Napastnik może także dostać się do innych tabel, korzystając z instrukcji UNION. W tym celu może wpisać np. coś takiego jako id:
-1) UNION SELECT KLIENT_ID, LOGIN, HASLO, 0 FROM KLIENCI --

Ostatnia linia warunku będzie wyglądać następująco:
AND (KLIENT_ID=-1) UNION SELECT KLIENT_ID, LOGIN, HASLO, 0 FROM KLIENCI --)

Zero w drugim zapytaniu SELECT po UNION jest konieczne aby liczba kolumn i ich typy się zgadzały. Całe zapytanie po wykonaniu zwróci napastnikowi listę loginów i haseł wszystkich klientów sklepu (być może także personelu, a przy odrobinie szczęścia nawet i hasło admina). Stąd już prosta droga do kradzieży np. danych osobowych.

Na tym możliwości ataków się nie kończą - korzystając z SQL Injection oraz faktu że strona ASP nie sprawdza potencjalnych błędów bazy danych można szukać innych tabel w bazie danych, oraz próbować określić typy ich kolumn - więcej na ten temat jest w materiałach do których linki są podane na końcu.
Zabezpieczenie przed atakiem SQL Injection

Aby zapobiec tego typu atakom, należy traktować wszystkie dane otrzymane z zewnątrz jako niezaufane, i sprawdzać ich poprawność. W przypadku liczb doskonale nadają się do tego np. wyrażenia regularne - w powyższym przykładzie parametr id można sprawdzić używając poniższego warunku (sprawdza on czy string składa się tylko z cyfr):
if (!ereg('^\d+$', $id))
{
// obsługa niepoprawnych danych
}

W przypadku danych tekstowych (jak np. login czy hasło) należy odpowiednio zakodować wszystkie pojedyncze apostrofy (zazwyczaj zamienić je na parę apostrofów), przez co ewentualny atak zostanie unieszkodliwiony. Dla każdej obsługiwanej bazy danych PHP dostarcza odpowiednią funkcję dedykowaną do tego celu, np. dla bazy MySQL jest to funkcja mysql_escape_string(). Można ją użyć następująco:
$login = mysql_escape_string($login);

W przypadku stringów można także rozważyć czy znak apostrofu może wystąpić w "legalnych" danych wejściowych - jeżeli nie, można dodać warunek który będzie odrzucał takie dane. W każdym przypadku warto także określić maksymalną długość danych wejściowych, i ją też kontrolować.

Jeżeli dane tekstowe są przeznaczone do późniejszego wyświetlenia na stronie WWW (a tak jest w większości przypadków), należy pamiętać aby przed ich wyświetleniem zamienić wszystkie znaki specjalne HTML na ich zakodowane odpowiedniki (np. za pomocą funkcji htmlspecialchars), aby zapobiec wyświetleniu fragmentu kodu HTML (lub gorzej, skryptu JavaScript, co może być atakiem XSS - Cross Site Scripting). "Legalne" dane też mogą niekiedy powodować podobne problemy. Dane można zakodować już przed zapisem ich do bazy danych. Warto wybrać jedną z tych dwóch metod (kodowanie przed wyświetleniem, lub zapisem do bazy danych), i konsekwentnie się jej trzymać.

Jeżeli używany interfejs dostępu do bazy danych obsługuje mechanizm parametrów, warto z niego skorzystać. Przedtem jednak należy się upewnić że on jest bezpieczny (tzn. parametry nie są wstawiane bezpośrednio do tekstu zapytania).
mod_rewrite jako dodatkowe zabezpieczenie przed SQL Injection

Dodatkowym metodą zabezpieczenia utrudniającą włamanie przez SQL Injection jest zastosowanie modułu Apache'a o nazwie mod_rewrite. Moduł ten pozwala m.in. na wykonanie przekierowania przychodzącego żądania pod zupełnie inny adres na serwerze. Sztuczka polega tutaj na tym że jest to wykonywane "wewnątrz" serwera, zatem nie jest to widoczne z zewnątrz. Z tego powodu moduł ten jest często stosowany jako jeden z elementów optymalizacji strony pod kątem wyszukiwarek internetowych. Nam jednak bardziej przyda się fakt że poprzez modyfikację adresu URL strony można ukryć oryginalną nazwę skryptu i wykorzystywane parametry przed wzrokiem ciekawskich. Przykład: strona wyświetlająca dane o produktach ma następujący adres:
http://www.serwer.pl/produkty.php?kategoria=3&produkt=235

Aby to zmienić, należy dodać odpowiednie komendy do pliku .htaccess, np. takie:
RewriteEngine On
RewriteBase /
RewriteRule ^produkty,([0-9]+),([0-9]+)\.html$ produkty.php?kategoria=$1&produkt=$2 [L]

Dzięki umieszczeniu powyższych reguł w pliki .htaccess do strony z produktami będzie się można odwołać na dwa sposoby: używając adresu podanego wcześniej, lub też nowego wykorzystującego reguły dla mod_rewrite:
http://www.serwer.pl/produkty,3,235.html

Taki adres ma tą zaletę z punktu widzenia bezpieczeństwa że ukryte są nazwa skryptu i jego parametry. Dodatkowo zastosowane wyrażenie regularne dokładnie określa zakres dopuszczalnych znaków będących identyfikatorami kategorii i produktu (mają to być liczby), więc próby wpisywania czegokolwiek innego gdzieś w środku adresu lub na jego końcu będą skutkować błędem 404 (nie znaleziono strony).

Oczywiście przedstawione tutaj zabezpieczenie przed SQL Injection wykorzystujące mod_rewrite nie jest idealnym zabezpieczeniem przed SQL Injection - ciągle można się odwołać do skryptu używając jego oryginalnej nazwy i parametrów, zatem skrypt ten musi być również odporny na atak SQL Injection. Warto go jednak zastosować jako dodatkowe zabezpieczenie, chociażby z tego względu, że powstrzyma większość dzieciaków które przeczytały sobie w Internecie coś na temat hakingu i potem chcą zaszpanować przed znajomymi jaki to on czy ona jest wielki "H4k3R".
Wielofazowy atak SQL Injection

We wszystkich wcześniejszych przykładach atakujący korzystał z faktu że dane wejściowe nie były walidowane, przez co miał możliwość modyfikacji wykonywanego zapytania. Jeżeli jednak witryna stosuje zabezpieczenia podane powyżej, atakujący może poszukiwać drogi ataku wielofazowego. Polega on na tym, że w pierwszej fazie dane podane przez napastnika są zapisywane do bazy danych, z uwzględnieniem powyższych zaleceń - mogą to być np. kryteria wyszukiwania do raportów które użytkownik może wygenerować, czy sposób sortowania wyników. Użytkownik może wybrać sobie jedno z tak zapisanych np. kryteriów wyszukiwania poprzez wybór jego nazwy - wydaje się to bezpieczne, gdyż do serwera jest przesyłany wyłącznie identyfikator, który podlega sprawdzeniu czy jest poprawny. Następnie tworzone jest dynamicznie zapytanie, którego częścią jest to co zostało wcześniej zapisane w bazie danych. W tym momencie twórcy witryny WWW mogą popełnić błąd zakładając że dane pochodzące z bazy danych są "bezpieczne". Jest to błąd, gdyż apostrofy które zostały zamienione na pary apostrofów podczas zapisu do bazy, przy odczycie ich z bazy są zwracane ponownie jako pojedyncze apostrofy

Aby się zabezpieczyć przed takimi niespodziankami, należy uważać w sytuacji gdy dane tekstowe pochodzące z bazy danych mają zostać użyte do konstrukcji kolejnych zapytań, i odpowiednio je zakodować. Alternatywnie można także rozważyć zamianę wszystkich apostrofów na cztery apostrofy podczas pierwszego zapisu do bazy (podczas odczytu zostanie tylko para apostrofów, czyli nadal to będzie bezpieczne) - jeżeli to rozwiązanie będzie stosowane konsekwentnie, powinno być także bezpieczne. Należy jednak w takim wypadku pilnować aby nie dopuścić do możliwości przeprowadzenia ataku 3- lub więcej fazowego.

Osobom zainteresowanym tym tematem polecam także przejrzenie następujących materiałów:
SQL Injection: Modes of Attack, Defence, and Why It Matters - opis sposobu ustalenia danych o kolumnach używanych w zapytaniu;
Advanced SQL Injection - zaawansowane techniki ataków SQL Injection na SQL Server;
Advanced SQL Injection - do zrozumienia tej prezentacji co prawda wymagana jest pewna wiedza, ale i tak czytając nagłówki można się zorientować jakie zagrożenia niosą ze sobą ataki SQL Injection. Znajduje się tam porównanie różnych baz danych pod kątem podatności na ataki SQL Injection, oraz szereg różnych metod ataków.