Bezpieczeństwo systemów komputerowych
na przykładzie systemu Linux.
Autorzy:
Bałos Dominik
Czapla Dariusz
Górkiewicz Jan
Bezpieczeństwo na poziomie sprzętu |
3 |
Bezpieczeństwo na poziomie systemu |
4 |
|
Instalacja |
4 |
|
Hasło |
4 |
|
Konto root oraz konta uprzywilejowane |
5 |
|
Startowanie i restartowanie systemu |
5 |
|
Komendy su oraz sudo |
7 |
|
Kopia plików z logami |
7 |
|
Ograniczenie rozmiaru dysku używanego przez użytkownika |
7 |
|
Używanie szyfrowanego systemu plików (CFS) |
9 |
Backup systemu |
10 |
|
Wstęp |
10 |
|
Program tar |
10 |
|
Archiwizacja przy pomocy programu tar |
11 |
|
Odzyskiwanie danych przy pomocy programu tar |
11 |
Bezpieczeństwo sieciowe |
12 |
|
Informacje o systemie |
12 |
|
Inetd i niebezpieczne serwisy sieciowe |
12 |
|
TCP_WRAPPERS |
12 |
|
Brak odpowiedzi na Ping (dystrybucja RedHat) |
13 |
SSH |
14 |
|
Wstęp |
14 |
|
Opis |
14 |
|
Zasady działania |
15 |
|
Pakiet OpenSSH |
16 |
|
Firewall (na przykładzie ipchains) |
17 |
|
Wstęp |
17 |
|
Aktywowanie filtrowania |
17 |
|
Ipchains |
18 |
|
Filtrowanie |
19 |
|
Opis podstawowych opcji programu ipchains |
22 |
|
Przykłady użycia programu ipchains oraz dodatkowe parametry |
22 |
|
Obsługa fragmentów pakietów |
24 |
|
Odnośniki do stron o bezpieczeństwie systemów |
25 |
Bezpieczeństwo na poziomie sprzętu.
Zabezpieczenie systemu na poziomie sprzętu polega na odcięciu możliwości zainicjalizowania pracy systemu z nośników pamięci zewnętrznej takich jak dyskietki lub płyty CD-ROM. System powinien być startowany tylko z partycji, na której został zainstalowany. Aby zabezpieczyć się przed startowaniem spoza tej partycji możemy:
usunąć fizycznie z serwera wszelkiego rodzaju urządzenia służące do odczytu zewnętrznych nośników danych
zabezpieczyć dostęp do BIOS'u serwera przy pomocy hasła, tak aby uniemożliwić włączenie opcji startowania systemu z urządzeń innych niż dysk z partycją startową naszego serwera
Bezpieczeństwo na poziomie systemu
Instalacja
Jeśli instalator pozwala nam wybrać w jaki sposób system będzie obsługiwał hasła wybieramy obsługę przez plik /etc/shadow.
Jeśli nasza dystrybucja pozwala na wybranie opcji bezpieczeństwa, z którą zostanie zainstalowany serwer, to wybieramy "paranoid". Przez wybranie tej opcji dalsze korzystanie z systemu może okazać się uciążliwe, jakkolwiek lepszą metodą jest odbezpieczanie pewnych usług z puli usług nieaktywnych niż dezaktywowanie usług aktywnych, które uważamy za niebezpieczne lub niepotrzebne.
Ważnym i początkowym punktem zabezpieczenia systemu jest wybranie właściwego hasła, przez które można otrzymać prawa administratora systemu (zasady wybierania dobrego hasła dotyczą także haseł dostępu na konta zwykłych użytkowników). Tworząc hasła należy kierować się następującymi zasadami:
hasło powinno składać się z minimum 6 znaków
hasło nie może być trywialne (np. imię, nazwisko itp.)
powinno składać się z kombinacji dużych i małych liter oraz cyfr
Przykład:
"I took the 2nd place in the 12 edition of Administrator's Conquest"
Hasło:
Itt2ndpit12eoAC
Do administratora systemu należy, aby użytkownik był zmuszony do zmiany swojego hasła po upływie określonego przedziału czasowego.
Konto root oraz konta uprzywilejowane
Należy pamiętać aby konta root używać tylko i wyłącznie w celach administracyjnych. Ponadto nie należy zostawiać otwartych sesji, na które zalogowaliśmy się jako użytkownik root. W celu zabezpieczenia się przed zostawianiem takich sesji otwartych, należy do pliku /etc/profile dodać wpis:
TMOUT=3600
Wpis ten instruuje system aby wylogowywał nas automatycznie po upływie 1 h. (3600 s.) nieaktywności w systemie.
Dobrą metodą zabezpieczenia jest także wykomentowanie wszystkich wpisów w pliku /etc/securetty z wyjątkiem "tty1", w celu zabronienia użytkownikowi root logowania się poprzez inne urządzenia TTY z wyjątkiem pierwszego.
Jeśli chodzi o uprzywilejowane konta należy pamiętać aby po zainstalowaniu systemu usunąć wszystkie konta i grupy nieużywane w naszym systemie, a które powstają przy instalacji (w niektórych dystrybucjach). Grupy te to np. adm, lp, uucp, news.
W celu zapobieżenia przypadkowego skasowania plików /etc/passwd, /etc/shadow, /etc/group oraz /etc/gshadow należy dla tych plików ustawić tzw. "immutable bit". Robimy to wywołując komendę:
chattr +i plik.
Startowanie i restartowanie systemu
Jeżeli używamy programu lilo należy pamiętać o właściwej jego konfiguracji (plik /etc/lilo.conf). Zaleca się aby do tego pliku dodać następujące wpisy:
timeout=00: od razu startujemy nasz system nie dając możliwości wystartowania innego
restricted oraz password=<password>: przy startowaniu będziemy pytani o hasło
Należy jeszcze ustawić prawa odczytu i zapisu tylko dla administratora (chmod 600 /etc/lilo.conf) ze względu na to, że plik ten zawiera niezakodowane hasło.
Bezpieczeństwo systemu możemy kontrolować także na poziomie montowania partycji w naszym systemie (plik /etc/fstab). Kontrolę tą uzyskujemy poprzez parametry montowania. Oto niektóre z nich:
defaults: zezwolenie na quota, read-write, suid na danej partycji
noqouta: nie ustawia ograniczeń rozmiaru dysku dla użytkowników na danej partycji
quota: zezwala na ustawienie ograniczeń rozmiaru dysku dla użytkowników na danej partycji
nosuid: nie ustawia dostępu SUID/GUID na danej partycji
suid: zezwala na dostęp SUID/GUID na danej partycji
ro: zezwala tylko na odczyt danych z danej partycji
rw: zezwala na odczyt i zapis danych z danej partycji
noexec: zabronienie wykonywania plików binarnych
Aby uniemożliwić restartowanie systemu przy użyciu kombinacji klawiszy Ctrl+Alt+Delete, w pliku /etc/inittab przy pomocy znaku # komentujemy linię zawierającą wpis:
ca:ctrlaltdel:/sbin/shutdown -t3 -r -now.
Normalny użytkownik systemu nie musi koniecznie wiedzieć co dzieje się w skryptach startowych systemu. Dlatego też wykonujemy komendę:
chmod -R 700 /etc/rc.d/init.d/*
Oznacza to, że tylko administrator systemu oraz demony systemowe mogą czytać, zapisywać i wykonywać pliki startowe.
Komendy su oraz sudo
Komenda su służy do uzyskania praw i środowisko innego użytkownika (w szczególności użytkownika root). Możemy zabronić normalnym użytkownikom wykonywania komendy su dla konta root.
Komenda sudo służy do wykonania programu jako inny użytkownik. Kontrolę nad tym kto jakie komendy może wykonywać za pomocą sudo mamy poprzez plik /etc/sudoers. Dobrą metodą zabezpieczenia jest zabronienie wszystkim użytkownikom wykonywanie jakichkolwiek programów za pomocą komendy sudo.
Kopia plików z logami
Jeśli nasze zabezpieczenia systemu nie okazały się wystarczające zostają nam już tylko pliki z logami. Pliki takie możemy wykorzystać do wykrycia słabego punktu naszego systemu. Dlatego ważne jest aby posiadać te pliki. Możemy np. sprawić aby każde ważne dla nas logi były automatycznie drukowane w momencie wystąpienia. Chodzi tutaj o kopię logów, której osoba włamująca się do systemu nie mogła zniszczyć.
Ograniczenie rozmiaru dysku używanego przez użytkownika
Quota jest to pakiet umożliwiający ograniczenie wielkości dysku twardego dostępnego dla konta (dla użytkownika, który na tym koncie zapisuje swoje dane). Dzięki ograniczeniu dostępnej dla użytkownika przestrzeni dyskowej możemy być pewni, że żaden użytkownik nie zapełni nam dysku twardego, a przez to nie stworzy niebezpieczeństwa błędnej pracy systemu.
Aby móc skorzystać z Quoty musimy mieć wkompilowaną w jądro jej obsługę. Aby wkompilować Quotę do jądra należy zazanczyć opcję Quota support w menu Filesystem. Oprócz kompilacji jądra należy także doinstalować odpowiednie oprogramowanie.
Aby nasza Quota działała musimy sprawić by pliki inicjujące system automatycznie sprawdzały i uruchamiały Quotę. Bardzo ważną zasadą jest, aby skrypt inicjujący Quotę znajdował się (wykonywał) po wykonaniu wszystkich poleceń montujących dyski i partycje! Jeśli nie zrobimy tego poprawnie Quota może nie działać prawidłowo. Oto przykład skryptu startującego tę usługę:
# Sprawdź quotę i włącz
ją
if [ -x /usr/sbin/quotacheck ]
then
echo "Checking
quotas. This may take some time."
/usr/sbin/quotacheck
-avug
echo " Done."
fi
if [ -x
/usr/sbin/quotaon ]
then
echo "Turning on
quota."
/usr/sbin/quotaon -avug
fi
Teraz trzeba dodać Quotę do systemów plików na naszym dysku. Zrobimy to edytując plik /etc/fstab. Po opcji default dopisz słowo usrquota by ustawić Quotę dla konkretnych użytkowników. U mnie wpis dla partycji głównej wygląda tak:
/dev/hda3 / ext2 defaults,usrquota 1 1
Jeśli chcemy ustawiać ograniczenia dla całej grupy użytkowników, zamiast userqouta musimy wpisać grpquota :
/dev/hda3 / ext2 defaults,grpquota 1 1
Możemy też ustawić ograniczenia przestrzeni dyskowej równocześnie dla użytkowników i grup :
/dev/hda3 / ext2 defaults,userquota,grpquota 1 1
Tworzymy teraz plik z informacjami dla Quoty. Musimy to zrobić z poziomu root`a, a plik ten musi należeć tylko i wyłącznie dla root`a. Utworzymy go w katalogu głównym partycji i będzie nosił nazwę quota.user.
Tworzymy teraz plik z informacjami dla Quoty. Musimy to zrobić z poziomu root`a, a plik ten musi należeć tylko i wyłącznie dla root`a. Utworzymy go w katalogu głównym partycji, której ograniczenia będą dotyczyć i będzie nosił nazwę quota.user.
Z konta root`a wpisujemy:
touch /quota.user
chmod
600 /quota.user
Analogicznie dla grupy:
touch /quota.group
chmod
600 /quota.group
Jeśli mamy katalogi umieszczone na osobnych partycjach np. /home, to musimy utworzyć quota.user i quota.group na tych partycjach. Dla przykładu:
touch
/home/quota.user
touch /home/quota.group
chmod 600
/home/quota.user
chmod 600 /home/quota.group
Limity
użytkownikom przypisuje się za pomocą polecenia edquota. Gdy
wpiszemy edqota artur (artur =
login naszego użytkownika) uruchomi się nam standardowy edytor
zapisany w zmiennej EDITOR.
Quotas for user
artur
/dev/hda3: blocks in use: 2594, limits (soft = 5120, hard =
6000)
inodes in use: 356, limits (soft = 1000, hard = 1500)
Dla objaśnienia blocks in use oznacza aktualną ilość miejsca zajmowaną przez naszego użytkownika, inodes in use to całkowita liczba plików, które użytkownik posiada.
Dla całych grup limity ustawiamy tak samo z wyjątkiem, że zamiast user podajemy group, no i wpisujemy oczywiście nazwę istniejącej grupy.
Wracając do limitów wartość soft oznacza maksymalną wartość jaką użytkownik ma przyznaną, ale istnieje jeszcze grace period, która razem z soft limit stanowi nieprzekraczalną ilość dostępnego miejsca - hard limit.
Używanie szyfrowanego systemu plików (CFS)
CFS umożliwia niezależne od aplikacji szyfrowanie/deszyfrowanie danych na powłoce struktury plików i nie wymaga modyfikacji kodu istniejącego już systemu plików, ani żadnych modyfikacji jądra systemu. Zabezpieczenie danych w ten sposób zabezpiecza nas przed skopiowaniem naszych danych w przypadku np. kradzieży dysku.
Backup systemu
Wstęp
Jedną z metod zabezpieczenia serwera jest regularne wykonywanie backup'u systemu. Błędy i zawieszenie ze skutkiem utraty ważnych danych mogą się zdarzyć od czasu do czasu. Najczęstszą przyczyną utraty danych są: ataki hackerów, błędy sprzętu, błędy użytkowników etc. Najbezpieczniejszą metodą robienia backup'u jest zapisywanie najważniejszych danych na nośnikach zewnętrznych (kaseta, CD, wymienny dysk) lub w lokalizacji sieciowej. Ewentualnie możemy zastosować system dysków RAID w standardzie obsługującym mirroring. Backup możemy przeprowadzać za pomocą takich programów jak: dump, tar lub cpio. Przy wyborze danych przeznaczonych do archiwizacji należy pamiętać aby nie przeprowadzać archiwizacji katalogów:
/proc gdyż znajdują się tutaj dane generowane przez jądro systemu
/mnt gdyż zazwyczaj w tym miejscu montujemy nośniki pamięci zewnętrznej (np. CD-ROM)
Musimy także wybrać strategię przeprowadzenia backup'u. Jedną z nich jest strategia polegająca na robieniu pełnego backup'u w pierwszy dzień tygodnia oraz backup'ów dopełniających w resztę dni tygodnia. Backup dopełniający jest to archiwizacja tylko tych danych, które zmieniły się od poprzedniego backup'u.
W przykładach użycia programów tar i dump zakładamy, że robimy backup katalogu /home na urządzeniu kasetowym widocznym jako urządzenie /dev/hdd0
Program tar
Program tar przeznaczony jest do zapisywania i odczytywania danych na i z pojedynczego pliku. Archiwum tworzone przez program tar może być zapisane zarówno na taśmie jaki i do pojedynczego pliku. W przypadku archiwizacji na taśmę, argumentem programu (po opcji 'f') nie jest nazwa tworzonego archiwum, tylko nazwa urządzenia (np. /dev/hdd0).
Archiwizacja przy pomocy programu tar
Aby przeprowadzić pełny backup katalogu /home używamy komendy:
tar cpf /dev/hdd0 --label "Full backup" --directory /home
Aby przeprowadzić backup dopełniający używamy komendy:
tar cpNf /dev/hdd0 --label "Incremental backup" --directory /home
Odzyskiwanie danych przy pomocy programu tar
Aby odtworzyć pliki zarchiwizowane w pliku (np. backup2001-05-04.tar) należy z katalogu / wykonać komendę:
tar xpf /dev/hdd0/backup2001-05-04.tar
Bezpieczeństwo sieciowe
Informacje o systemie
Pierwszą i w miarę prostą rzeczą jest sprawdzenie jak wiele informacji o naszym systemie otrzymuje użytkownik logujący się na niego. Informacje takie udostępniane są użytkownikowi poprzez pliki /etc/issue oraz /etc/issue.net. Ważne jest aby użytkownik otrzymał jak najmniej informacji o naszym systemie podczas logowania się na niego.
Inetd, nazywany również "super server", ładuje programy sieciowe bazując na rodzaju żądania, które przychodzi z sieci. W pliku /etc/inetd.conft znajdują się wpisy, mówiące demonowi inetd jakie serwisy może on startować i z jakim portem są one związane. W celu zabezpieczenia naszego systemu wyłączamy wszystkie niebezpieczne serwisy (np. telnet, ftp etc.) oraz kasujemy je w systemie. Dodatkowym zabezpieczeniem jest wykonanie komend:
chmod 600 /etc/inetd.conf
chattr +i /etc/inetd.conf
TCP_WRAPPERS to najprostszy i najmniej problemowy sposób zabezpieczenia naszego systemu przed dostępem z zewnątrz. Do kontroli dostępu do naszego systemu z zewnątrz służą dwa pliki /etc/hosts.deny oraz /etc/hosts.allow. Aby zabronić dostępu do systemu z jakiegokolwiek serwera zewnętrznego w pliku /etc/hosts.deny umieszczamy wpis (tylko ten wpis powinien znajdować się w tym pliku): ALL: ALL@ALL DENY, PARANOID. Aby jednak zupełnie nie odciąć naszego systemu od świata zewnętrznego możemy przy pomocy pliku /etc/hosts.allow wylistować hosty, z których dozwolone będzie dostanie się na serwer poprzez konkretne serwisy (np. ssh). Więcej informacji na temat plików /etc/hosts.deny oraz /etc/hosts.allow możemy znaleźć w manualu do systemu (man hosts.deny, man hosts.allow). Znajdziemy tam min. składnię tych plików.
Aby nasz serwer nie mógł być wykryty z zewnątrz przy użyciu programu ping należy wykonać komendę:
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
Komendę tą możemy dodać do skryptu startowego, tak aby po każdym starcie systemu aktywować odmowę na sygnały programu ping.
SSH
Wstęp
Pakiet SSH (ang. Secure Shell) oferuje nam możliwość połączenia się z komputerami podłączonymi do sieci komputerowej, wykonania na nich zdalnie poleceń i kopiowania plików pomiędzy nimi. Co najważniejsze pakiet oferuje silną autoryzację komputerów i użytkowników dokonujących powyższych działań oraz zapewnia bezpieczną komunikację w sieci INTERNET.
Dodatkowo pakiet oferuje bezpieczne połączenia oparte na protokole X-Windows. Pakietem możemy zastąpić standardowe polecenia systemu operacyjnego: rlogin, rsh i rcp (poprzez polecenia ssh i scp).
Protokół SSH zapewnia mechanizm kodowania danych w warstwie transportowej protokołu sieciowego. Protokół zapewnia także autoryzację pomiędzy dwoma komputerami w sieci, autoryzację pomiędzy użytkownikami, wraz z ochroną prywatności i integralności ich danych.
Program SSH Server pod zapewnia bezpieczny proces logowania, transfer plików, pracę pod X11, połączenia w protokole TCP/IP poprzez niepewne sieci. Serwer czuwa nad autentycznością danych, automatycznie dokonuje kodowania sesji i integruje ochronę dla wszystkich przesyłanych danych. Do tego celu wykorzystuje się protokół RSA, służący do wymiany kluczy i sprawdzania autentyczności oraz symetryczne algorytmy, Blowfish lub 3DES do kodowania transferu danych.
Program SSH client zapewnia bezpieczny proces logowania w niepewnej sieci. Program ssh w pełni zastępuje protokół TELNET dodatkowo realizując sprawdzanie autentyczności, automatyczne kodowanie sesji i integrację metod ochrony zdefiniowanych w protokole SSH.
SSH client również dostarcza technologię " TCP/IP port forwarding technology" przekierowywania niechronionych połączeń poprzez chroniony kanał. Jest to realizowane poprzez utworzenie zastępczego serwera dla źródłowego portu pracującego pod protokołem TCP/IP. Serwer ten, utworzony na lokalnej maszynie, czeka na połączenie programu użytkownika do portu źródłowego. Następnie SSH przesyła żądanie i dane przez chroniony kanał do zdalnego systemu. SSH server na zdalnym systemie dokonuje finalnego połączenia do własciwego hosta i portu. Wiele zdalnych usług, które wykorzystują protokół TCP/IP może być chronionych, między innymi: aplikacje użytkowników client-server, systemy baz danych, i usługi takie jak HTTP, TELNET, POP, SMTP. SSH zapewnia automatyczne przesyłanie danych w X11 Windowing System, głównie używanych na maszynach unix'owych.
Każdy z komputerów na których jest zainstalowany pakiet SSH posiada parę kluczy - klucz prywatny, możliwy do odczytania jedynie przez administratora danego komputera oraz przez demona sshd, obsługującego usługę SSH i klucz publiczny dostępny dla wszystkich użytkowników sieci. Połączenie jest realizowane po stronie klienta przez program ssh (SSH client) , a po stronie serwera przez demona sshd (SSH server). Kiedy klient łączy się z demonem (serwerem) jako pierwsze dane otrzymuje klucz publiczny serwera. Klient porównuje ten klucz z zachowanym w wewnętrznej bazie danych, z poprzednich połączeń (o ile wcześniej łączył się z tym serwerem, jeżeli nie to go tylko zapamiętuje w bazie danych). W przypadku stwierdzenia niezgodności kluczy połączenie jest zamykane. W przeciwnym przypadku klient generuje losową liczbę 256 bitową. Liczbę tę szyfruje przy pomocy swojego klucza prywatnego oraz klucz publicznego serwera i tak zakodowaną przesyła do serwera. Serwer przy pomocy swojego klucza prywatnego i klucz publicznego klienta rozkodowuje przesyłkę, czyli wygenerowaną przez klienta losowo liczbę. Liczba ta stanowi klucz używany do kodowania podczas dalszej komunikacji.
Po dokonaniu autoryzacji komputerów następuje autoryzacja użytkownika. Najpierw sprawdza się istnienie klucza publicznego klienta w globalnej bazie danych kluczy publicznych innych serwerów (plik /etc/ssh_known_hosts) lub w indywidualnej bazie danego użytkownika (plik ~/.ssh/known_hosts). W przypadku znalezienia tego klucza, demon zezwala na dokonanie autoryzacji na podstawie plików /etc/hosts.equiv, /etc/shosts.equiv, ~/.rhosts lub ~/.shosts. Pliki /etc/shosts.equiv i ~/.shosts stanowią odpowiedniki plików /etc/hosts.equiv oraz ~/.rhosts ale wyłącznie dla usługi ssh, a więc stanowią znacznie lepszą metodę autoryzacji. W przypadku niepowodzenia autoryzacji, sprawdzana jest obecność pliku ~/.ssh/authorized_keys zawierającego klucze publiczne danego użytkownika wygenerowane na innych stacjach. Plik ten może sobie stworzyć każdy użytkownik indywidualnie przy pomocy polecenia ssh-keygen na stacji klienta i poprzez przesłanie go na serwer. Następnie serwer próbuje dokonać autoryzacji użytkownika w sposób analogiczny do przeprowadzonej wcześniej autoryzacji komputerów, tzn. wymiany z klientem zakodowanej informacji przy pomocy pary kluczy: klucz publiczny użytkownika, klucz prywatny serwera i klucz prywatny użytkownika, klucz publiczny serwera. W przypadku niepowodzenia tej metody, demon pyta się użytkownika o jego hasło. Ponieważ transmisja jest kodowana, nie ma obawy o podsłuchanie go przez niepowołaną osobę.
Pakiet OpenSSH
Pakiet OpenSSH realizuje szyfrowane połączenie pomiędzy dwoma komputerami, zapewniając bezpieczeństwo przesyłania danych, autoryzację połączeń i autentykacje. Jest napisany na następujące systemy operacyjne:
Linux,
Solaris,
AIX,
HPUX,
NetBSD,
Irix
OpenSSH jest rozwijany w oparciu o ostatnią nielicencjonowaną wersję SSH Tatu Ylonen'a. Wszystkie opatentowane algorytmy zawarte w pakiecie, zostały przeniesione do zewnętrznych bibliotek, wszystkie znane dziury w bezpieczeństwie zostały naprawione, rozbudowano pakiet o nowe cechy i dokonano wielu usprawnień oprogramowania.
OpenSSH zawiera w sobie między innymi następujące programy:
ssh - zastępuje rsh, rlogin i telnet, umożliwia zdalne kopiowanie plików - scp, które zastępuje rcp i ftp,
sshd - serwer usługi ssh (port 22),
ssh-add, dodaje informacje identyfikacyjne dla ssh-agent,
ssh-agent, służy do trzymania prywatnych kluczy autentykacyjnych,
ssh-keygen, generuje i zarządza kluczami autentykacyjnymi programu ssh.
Firewall (na przykładzie ipchains)
Wstęp
Wszystkie informacje krążące w sieci przyjmują formę pakietów. Pakiet najogólniej dzieli się na nagłówek i ciało. Ciało zawiera informacje zrozumiałe dla aplikacji przeznaczonej do otrzymania danego pakietu. Z informacji zawartych w nagłówku interesujące dla nas, w aspekcie tego tematu, są informacje o źródle i miejscu docelowym pakietu. Możemy przyjąć, że informacje te dostępne są dla nas w formie ipsrc:portsrc oraz ipdest:portdest gdzie:
ipsrc - adres IP nadawcy pakietu
portsrc - port nadawcy pakietu
ipdest - adres IP odbiorcy pakietu
portdest - port odbiorcy pakietu
Filtr pakietów to oprogramowanie, które na podstawie informacji zawartych w nagłówku pakietu decyduje o tym co się z nim stanie. Wynikiem działania takiego oprogramowania może być:
zabronienie otrzymania pakietu: pakiet nie dostaje się do odbiorcy, do którego został skierowany
akceptacja otrzymania pakietu: pakiet dostaje się do odbiorcy, do którego został skierowany
odrzucenie pakietu: pakiet nie dostaje się do odbiorcy, do którego został skierowany a strona wysyłająca zostaje o tym fakcie poinformowana
Aktywowanie filtrowania
Aby móc kontrolować pakiety "przepływające" przez nasz interfejs sieciowy, musimy sprawdzić czy nasze jądro wspiera filtrowanie pakietów. Jeśli w katalogu /proc/net istnieje plik ip_fwchains oznacza to że tak. Jeśli natomiast plik ten nie istnieje musimy ustawić odpowiednie parametry jądra. Dla jądra w wersji 2.1 i 2.2 są to: CONFIG_FIREWALL oraz CONFIG_IP_FIREWALL. Obydwa parametry ustawiamy na "y".
Ipchains
Ipchains jest narzędziem, które umożliwia nam min. kontrolowanie parametrów filtrowania pakietów. Ustawia i kasuje reguły filtrowania pakietów, które to reguły używane są przez jądro systemu. Program ipchains jest nowszym odpowiednikiem programu ipfwadm. Zmiany dokonane przez program ipchains zostają utracone w momencie restartowania systemu, dlatego zaleca się aby raz utworzoną konfigurację zapisać jako jeden ze skryptów startowych systemu. Zakładając, że reguły filtrowania mamy zapisane w pliku /etc/ipchains.rules możemy napisać następujący skrypt startowy (/etc/init.d/packetfilter):
#! /bin/sh
# Skrypt do kontrolowania filtrowania pakietów.
# Jeśli nie zdefiniowano reguł, nie rób nic.
[ -f /etc/ipchains.rules ] || exit 0
case "$1" in
start)
echo -n "Włączam fitrowanie pakietów:"
/sbin/ipchains-restore < /etc/ipchains.rules || exit 1
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "."
;;
stop)
echo -n "Wyłączam filtrowanie pakietów:"
echo 0 > /proc/sys/net/ipv4/ip_forward
/sbin/ipchains -F
/sbin/ipchains -X
/sbin/ipchains -P input ACCEPT
/sbin/ipchains -P output ACCEPT
/sbin/ipchains -P forward ACCEPT
echo "."
;;
*)
echo "Użycie: /etc/init.d/packetfilter {start|stop}"
exit 1
;;
esac
exit 0
Filtrowanie
W trakcie filtrowania pakietów jądro systemu posługuje się jedną z trzech list reguł zwanych "firewall chains". Nazwy tych list to: input, output oraz forward. Kiedy pakiet przychodzi z zewnątrz (np. poprzez interfejs Ethernet) jądro używa reguł zapisanych w liście input aby zdecydować o tym co stanie się z pakietem. Jeśli pakiet "przeżył" ten krok, jądro sprawdza jego adres docelowy. Jeśli adresem docelowym jest adres innej maszyny, wtedy pakiet jest testowany pod kątem reguł zawartych w liście forward. Lista output służy do testowania pakietów tuż przed opuszczeniem systemu filtrującego (także tych, które były testowane przy pomocy reguł zawartych w liście forward). Oprócz tych trzech podstawowych list istnieje możliwość definiowania własnych.
Reguły składające się na listę przyjmują postać: "jeśli nagłówek pakietu wygląda tak, to zrób z nim to". Jeśli jakaś reguła nie odnosi się do testowanego pakietu, następna z kolei zostaje zastosowana. Jeśli żadna z reguł nie została zastosowana do pakietu, wtedy jest on traktowany zgodnie z generalną regułą bezpieczeństwa systemu. Generalna reguła bezpieczeństwa systemu może przyjmować jedną z postaci:
"wszystko co nie jest zabronione jest dozwolone"
"wszystko co nie jest dozwolone jest zabronione"
Poniższy diagram prezentuje drogę jaką przebywa pakiet przechodzący przez system z filtracją pakietów:

Opis poszczególnych stanów na powyższym diagramie:
checksum: Test sprawdzający czy otrzymany pakiet nie jest uszkodzony. Jeśli tak, jego dalsze przejście jest zabronione.
sanity: Ostatni test pakietu przed "wpuszczeniem" go do "input chain". Odrzucane są wszystkie pakiety, które mogły by "zmylić" reguły sprawdzające w następnych krokach filtracji.
input chain: Jest to pierwsza lista reguł, pod kątem których pakiet jest testowany. Jeśli wynik jest inny niż zabronienie lub odrzucenie, pakiet przechodzi dalej.
demasquerade: Stan ten zachodzi jeśli rozpatrywany pakiet jest odpowiedzią na wcześniej wysłany pakiet (request -> response) i jeśli w naszej sieci używamy "IP Masquerade".
routing decision: W tym stanie sprawdzane jest pole określające odbiorcę. W zależności czy jest to IP naszej maszyny czy innej, system podejmuje odpowiednie kroki (zobacz diagram).
local process: Proces uruchomiony na naszej maszynie, którego jednym z działań jest wymiana informacji w sieci (odbiorca i nadawca pakietów).
lo interface: Kiedy pakiety wysyłane przez lokalny proces przeznaczone są również dla procesu lokalnego w polach nagłówka odpowiadających za adres źródła i adres docelowy mają wpisany interfejs lo (loopback interface).
forward chain: Lista reguł, pod kątem której testuje się każdy pakiet przeznaczony dla maszyny innej niż nasza.
output chain: Lista reguł, pod kątem której testuje się każdy pakiet mający opuścić system.
Opis podstawowych opcji programu ipchains
Opcje dotyczące operacji na całych listach:
tworzenie nowej listy (-N)
kasowanie pustej listy (-X)
zmienienie generalnej reguły bezpieczeństwa dla wbudowanej listy (-P)
wypisanie wszystkich reguł w liście (-L)
wyrzucenie wszystkich reguł z listy (-F)
wyzerowania liczników pakietów i bajtów we wszystkich regułach (-Z)
Opcje dotyczące poszczególnych reguł w listach:
dodanie nowej reguły do końca listy (-A)
dodanie nowej reguły na określonej pozycji w liście (-I)
zamienienie reguły na określonej pozycji w liście (-R)
skasowanie reguły na określonej pozycji w liście (-D)
Przykłady użycia programu ipchains oraz dodatkowe parametry
Zabronienie odpowiadania na pakiety programu ping wysłanych z interfejsu lo (127.0.0.1):
ipchains -A input -s 127.0.0.1 -p icmp -j DENY
gdzie:
-s: adres źródła
-p: protokół (np. icmp, tcp, udp)
-j: ACCEPT|DENY|REJECT|MASQ|REDIRECT|RETURN
Usuwanie powyższej reguły z listy input:
ipchains -D input 1
lub
ipchains -D input -s 127.0.0.1 -p icmp -j DENY
Zabronienie odpowiadania na pakiety programu ping wysłanych przez jakikolwiek host:
ipchains -A input -s 0/0 -p icmp -j DENY
Adres sieciowy w opcjach -s (source) oraz -d (destination) może być podany na cztery sposoby:
przez nazwę np. localhost lub ernie.icslab.agh.edu.pl
przez IP np. 127.0.0.1 lub 206.32.128.5
przez zakres adresów IP:
199.95.207.0/32 - wszystkie od 199.95.207.0 do 199.95.207.255
199.95.207.0/255.255.255.255 - tak samo
Dozwolone jest także użycie znaku "!" (NOT) przed adresem hosta. Oznacza to, że chcemy aby rozpatrywane były wszystkie adresy nie należące do podanych np.
ipchains -A input -s ! localhost -p icmp -j DENY
Zabroń odpowiadania na pakiety ICMP wysłane przez wszystkie hosty oprócz localhost.
Jeśli wartością argumentu -p jest TCP lub UDP, mamy możliwość oprócz adresu wyspecyfikować także interesujące nas porty. Jeśli chcemy, żeby był to zakres portów używamy znaku ':'. I tak oznaczenie 6000:6010 oznacza, że odnosimy się do 11 portów od 6000 do 6010 włącznie. Jeśli pominiemy dolny zakres program domyślnie użyje 0, jeśli natomiast pominiemy górny domyślną wartością będzie 65535. Tak więc aby wyspecyfikować, że chodzi nam o wszystkie połączenia TCP przychodzące z portów poniżej 1024 użyjemy następujących argumentów: "-p TCP -s 0.0.0.0/0 :1023". Numer portu możemy także podać poprzez nazwę np. www. Dozwolone jest także używanie znaku '!' oznaczającego negację. Należy jednak uważać na miejsce, w którym znak ten występuje. Następujące dwa wpisy wyjaśniają tę różnicę:
-p TCP -d ! 192.168.1.1 www
oraz
-p TCP -d 192.168.1.1 ! www
Wpis pierwszy oznacza, że chodzi nam o port 81 na każdej maszynie oprócz 192.168.1.1, natomiast wpis drugi oznacza, że chodzi nam o wszystkie porty na maszynie 192.168.1.1 oprócz portu 81.
Za pomocą opcji "-i" możemy wyspecyfikować, do którego interfejsu sieciowego odwołuje się dana komenda (oczywiście jeśli posiadamy więcej niż jeden interfejs sieciowy). Aby sprawdzić ile interfejsów sieciowych posiada system używamy komendy ifconfig.
Aby wymazać wszystkie reguły z danej listy używamy opcji -F:
ipchains -F input
Aby wylistować wszystkie reguły z danej listy używamy opcji -L:
ipchains -L input
Bardzo użyteczną opcją jest opcja -C. Za jej pomocą możemy sprawdzić co stanie się z danym pakietem np. wchodzącym skierowanym na konkretny adres i port.
ipchains -C input -p TCP -s 192.168.1.1 6000 -d 192.168.1.2 www
odpowiedź programu może wyglądać np. tak:
packet accepted
Obsługa fragmentów pakietów
Czasami w sieci dochodzi do sytuacji kiedy jeden pakiet musi zostać podzielony na mniejsze fragmenty (ze względu np. na przepustowość). Kiedy sytuacja taka nastąpi strona odbierająca zbiera te fragmenty aby ponownie sformować z nich cały pakiet.
Problem z fragmentami polega na tym, że ważne dla nas informacje będą zawarte tylko w pierwszym fragmencie (odpowiadającym nagłówkowi). Jednym z wyjść jest skompilowanie jądra systemu z włączoną opcją "IP: always defragment". Oznacza to, że system zanim podejmie jakiekolwiek decyzje odnośnie pakietu odtworzy go w całości z nadchodzących fragmentów. Drugim rozwiązaniem jest odpowiednie sformułowanie reguł tak aby odnosiły się one także do fragmentów. Ważne jest, aby pamiętać iż w normalnym przypadku tylko pierwszy fragment (zawierający informację z nagłówka) zostanie potraktowany jak pakiet, reszta nie. Aby dana reguła traktowała tak samo wszystkie fragmenty składające się na pakiet należy przy jej specyfikowaniu użyć opcji '-f'.
Odnośniki do stron o bezpieczeństwie systemów
http://www.openna.com
http://www.ssh.org
http://www.openssh.com
http://www.jtz.org.pl
http://www.openwall.com/linux/