Jeśli zainstalowałeś system zgodnie z opisem zamieszczonym w tym serwisie to powinieneś mieć uruchomione takie usługi:
# netstat -a Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 *:time *:* LISTEN tcp 0 0 *:sunrpc *:* LISTEN tcp 0 0 *:auth *:* LISTEN tcp 0 0 *:ssh *:* LISTEN udp 0 0 *:biff *:* udp 0 0 *:time *:* udp 0 0 *:bootpc *:* udp 0 0 *:sunrpc *:*
Jak widać jest ich dość dużo. Wszystkie programy, które są w stanie LISTEN to serwery oczekujące nadejścia połączenia. Większość z ich kontrolowana jest przez program inetd - internet "super-server".
Zadaniem inetd jest nasłuchiwanie na określonych w pliku konfiguracyjnym /etc/inetd.conf portach, w imieniu innych programów. Gdy nadejdzie połączenie na któryś z tych portów inetd uruchamia właściwy program do jego obsługi. Dzięki inetd zmniejszamy obciążenie systemu, ponieważ w pamięci uruchomiony jest tylko jeden program obsługujący nadchodzące połączenia a nie kilka. Zasada działania inetd jest bardzo prosta. Np. jeśli nadejdzie żądanie połączenia na port 21 (FTP) inetd uruchamia program serwera FTP. Gdy połączenie zostanie zakończone program serwera zostaje wyłączony.
Gniazda, na których ma nasłuchiwać inetd oraz jakie programy uruchamiać do ich obsługi definiujemy w pliku /etc/inetd.conf. Dla każdej usługi znajduje się w nim wpis w następującym formacie:
Kolumny oznaczają odpowiednio:
Nazwa usługi
taka jak nazwa usługi w pliku /etc/services.
Adres
nieobowiązkowe pole z adresem na jakim ma nasłuchiwać serwer. Adres musi być jednym z adresów IP lub nazwą hosta.
Rodzaj gniazda
jak sama nazwa wskazuje jest to rodzaj gniazda. Mamy następujące możliwości: stream, dgram, raw, rdm, seqpacket.
Protokół
protokół z jakim pracuje serwer ( /etc/protocols ). Przykładem mogą być: tcp lub udp.
Opcje
w tym polu może znajdować się jedna z opcji - wait lub nowait. Opcje te informują inetd czy czekać na zakończenie pracy serwera czy nadal przyjmować nowe połączenia i uruchamiać kolejne serwery do ich obsługi. Gdybyśmy ustawili wait w wierszu odpowiadającej konfiguracji serwera ftp; z serwerem mógłby się połączyć tylko jeden użytkownik. Kolejny użytkownik zostałby obsłużony po rozłączeniu się pierwszego.
Użytkownik[.grupa] lub użytkownik[:grupa]
serwer zostanie uruchomiony jako proces użytkownika i grupy zdefiniowanej w tej opcji. Podawanie grupy nie jest konieczne.
Program serwera
ścieżka do pliku uruchomieniowego serwera
Argumenty
argumenty jakie chcemy przekazać serwerowi
Dla serwera FTP wiersz konfiguracyjny wygląda tak:
Dowiadujemy się z niej że jest to serwer ftp ( w pliku /etc/services widzimy że operuje on na porcie 21 ), jako protokuół mamy tcp, który jest protokołem strumieniowym, dla każdego łączącego się użytkownika będzie tworzony nowy serwer - nowait, serwer startuje jako root i wykorzystuje tcpwrapers ( patrz poniżej rozdział 11.3 ).
Jak widzieliśmy wcześniej w nowo zainstalowanym systemie program inetd nasłuchuje na wielu portach. Aby wyłączyć nasłuchiwanie wystarczy zakomentować wiersz z nazwą usługi w pliku konfiguracyjnym /etc/inetd.conf.
Aby zobaczyć jakie usługi są obecnie uruchamiane przez inetd wydajemy komendę:
U mnie po instalacji miałem domyślnie włączone takie usługi:
time stream tcp nowait root internal time dgram udp wait root internal comsat dgram udp wait root /usr/sbin/tcpd in.comsat auth stream tcp wait nobody /usr/sbin/in.identd in.identd -P/dev/null
Wszystkie powyższe usługi możemy spokojnie wyłączyć. W tym celu otwieramy plik /etc/inetd.conf i komentujemy wiersze odpowiadające usługom, które chcemy wyłączyć. Następnie zapisujemy plik i restartujemy inetd wydając komendę:
Ponieważ zakomentowaliśmy wszystkie usługi równie dobrze możemy wydać polecenie:
Aby inetd nie był uruchamiany przy starce systemu należy usunąć atrybut wykonywalny pliku /etc/rc.d/rc.inetd.
# chmod 660 /etc/rc.d/rc.inetd
Sprawdźmy czy rzeczywiście inetd przestał nasłuchiwać:
# netstat -a Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 *:sunrpc *:* LISTEN tcp 0 0 *:ssh *:* LISTEN udp 0 0 *:bootpc *:* udp 0 0 *:sunrpc *:*
Widzimy, że w tej chwili system nasłuchuje już tylko na kilku portach. Ponieważ całkiem wyłączyliśmy inetd programy nasłuchujące na wyświetlonych portach nie są pod jego kontrolą. Czyli zostały uruchomione przez system jako samodzielne (ang. standalone).
Jeśli nie będziemy montować katalogów za pośrednictwem NFS, możemy wyłączyć również pierwszą i ostatnią usługę z powyższej listy. Usługi te uruchamiane są w pliku /etc/rc.d/rc.inet2 poleceniem /sbin/rpc.portmap. Aby nie uruchamiać tej usługi usuwamy atrybut wykonywalny pliku /etc/rc.d/rc.portmap.
# chmod 660 /etc/rc.d/rc.portmap
# chmod 660 /etc/rc.d/rc.nfsd
Teraz jeszcze usuniemy uruchomione programy rpc.portmap i nfsd:
Sprawdźmy jakie usługi zostały:
# netstat -a Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 *:ssh *:* LISTEN udp 0 0 *:bootpc *:*
OK. Usunęliśmy już prawie wszystko. To co zostało to serwer ssh oraz klient DHCP. Obie usługi zostawiamy. Pierwsza z nich to nasłuchujący serwer ssh, który pozwoli nam na zdalne łączenie się z naszym serwerem. Druga to klient DHCP który konfiguruje jeden z naszych interfejsów sieciowych.
Jeśli inetd nasłuchuje na jakimś porcie i na ten port nadejdzie żądanie połączenia to zanim inetd uruchomi program odpowiadający za obsługę tego połączenia uruchamiany jest tcpd - access control facility for internet services - czyli urządzenie kontroli dostępu do usług internetowych.
Algorytm działania jest taki:
- Nadchodzi żądanie połączenia z portem powiedzmy 21 (FTP)
- inetd przejmuje nad nim kontrole i uruchamia tcpd
- tcpd sprawdza czy wykonujący połączenie ma prawo by się z nami łączyć
- Jeśli ma prawo to uruchamiany jest odpowiedni program, który obsługuje to połączenie w tym przypadku serwer FTP. Jeśli nie ma prawa to połączenie jest odrzucane
| Tip: |
| Powyższy algorytm działa tylko wtedy gdy program startowany jest za pośrednictwem inetd oraz został napisany/skompilowany z wykorzystaniem biblioteki libwrap. W przykładzie pliku konfiguracyjnego inetd pokazałem wiersz odpowiadający konfiguracji serwera FTP. Zwróćcie uwagę, że program serwera wywoływany jest przez tcpd - ostatnie dwie kolumny. |
To kto ma dostęp do danej usługi, lub nie, definiujemy w plikach /etc/hosts.allow i /etc/hosts.deny. Tcpd sprawdza najpierw plik hosts.allow i jeśli jest tam regułka, która pasuje do nawiązującego połączenie to połączenie jest przyjmowane. Jeśli w pliku nie ma regułki, która pasowałaby do nawiązującego połączenie tcpd sprawdza plik hosts.deny. Jeśli nawiązujący połączenie pasuje do którejś z regułek połączenie jest odrzucane. Jeśli nawiązujący połączenie nie jest wymieniony ani w pliku hosts.deny ani hosts.allow to połączenie jest przyjmowane.
Filozofia konfiguracji plików jest taka, że w pliku hosts.deny zabraniamy dostępu do wszystkich usług - wszystkim. Natomiast w pliku hosts.allow przydzielamy dostęp tylko tym, którym chcemy go przydzielić.
Składnia tych plików jest dość prosta:
hosts.allow
<usługa/nazwa procesu serwera >:<kto ma dostęp>hosts.deny
<usługa/nazwa procesu serwera>:<kto nie ma dostępu>
Przykłady:
Plik hosts.allow pozwala na:
- połączenia do wszystkich usług z adresu 127.0.0.1
- połączenia do serwera FTP z adresów 192.168.0.10 oraz z wszystkich adresów w sieci 192.168.1.0
- połączenia z ssh z sieci 192.168.0.0 i od czesiek.interia.pl
Plik hosts.deny zabrania wszystkim na połączenia ze wszystkimi usługami.
Po przeprowadzeniu wszystkich opisanych tu kroków nasz system jest lepiej zabezpieczony. Nie znaczy to, że jest całkiem bezpieczny. Artykuł opisuje jedynie jeden z poziomów zabezpieczeń. Kolejnym będzie skonfigurowanie dobrego firewalla.
Należy również pamiętać aby wszystkie programy, które uruchamiamy w naszym systemie były na bieżąco uaktualniane. Utrudni to potencjalnemu włamywaczowi wykorzystanie znanych dziur w starym oprogramowaniu.
| Tip: |
| Zabezpieczenie serwera przy pomocy tcpwrapers nie jest polecaną metodą. O wiele lepszą metodą jest napisanie dobrego firewalla wykorzystując iptables. |
W pliku /etc/login.defs możemy skonfigurować wiele opcji dotyczących logowania do systemu. Każda z nich jest dość dobrze wyjaśniona. My zmienimy tylko kilka z nich:
FAIL_DELAY 10
LOG_UNKFAIL_ENAB yes
LOG_OK_LOGINS yes
SULOG_FILE /var/log/sulog
UMASK 027
PASS_MAX_DAYS 30
PASS_MIN_DAYS 15
PASS_MIN_LEN 6
PASS_WARN_AGE 7
LOGIN_RETRIES 3
DEFAULT_HOME no
Opcje PASS_MAX_DAYS, PASS_MIN_DAYS, PASS_WARN_AGE można ustawić również przy pomocy polecenia passwd. Odpowiadają nim przełączniki, kolejno -x, -n, -w.
Jeśli chodzi o opcje UMASK to takiej samej zmiany powinniśmy dokonać w pliku /etc/profile (wiersz 61).
Dobrym pomysłem jest również nie podawanie informacji o naszym systemie każdemu logującemu się (lub próbującemu) użytkownikowi. Jak pewnie zauważyłeś każdemu logowaniu towarzyszy wiersz informujący nas, że logujemy się do systemu Linux o jądrze 2.4.26 oraz jednej z konsol tty. Ta informacja może posłużyć potencjalnemu włamywaczowi, ponieważ rozpoznanie systemu to jedna trzecia sukcesu.
Aby zapobiec wyświetlaniu wspomnianego powitania wydajemy poniższą komendę:
Oczywiście zamiast "Asmo Box" wpisujecie cokolwiek wam się podoba.
Zmieniamy również plik /etc/rc.d/rc.S. Wpisujemy "#" na początku wiersza 268:
a następnie czyścimy plik /etc/motd:
Gdy do zdalnego logowania używacie ssh to zauważyliście, że po zalogowaniu wyświetlany jest komunikat o systemie i obecnie zainstalowanym jądrze. Aby to zmienić edytujemy plik /etc/ssh/sshd_config. Wyszukujemy wiersz "PrintMod yes" i zmieniamy na "PrintMod no".
Ponieważ mamy już otwarty plik zmieńmy również wiersze:
Oryginalnie |
Zmieniamy na |
|
|---|---|---|
| Protocol 1,2 | Protocol 2 | |
| #RSAAuthentication yes |
RSAAuthentication no |
|
| #Banner /some/path | Banner /etc/ssh/baner |
Następnie tworzymy plik /etc/ssh/baner i dodajemy do niego np. taki tekst:
Po czym restartujemy serwer sshd:
Oczywiście jeśli użytkownik będzie miał trochę wiedzy przeglądnie sobie plik /proc/version i dowie się jaki mamy system :).
Kolejną wartą polecenia zmianą w domyślnej konfiguracji systemu jest stworzenie pliku ~/.bash_logout i dodanie do niego polecenia clear.
Spowoduje to automatyczne czyszczenie ekranu po wydaniu polecenia logout lub naciśnięciu klawiszy [ctrl]+[d].
Powyższe polecenie doda oczywiście plik .bash_logout tylko to katalogu /root. Aby plik ten tworzony był automatycznie przy dodawaniu kont użytkowników umieszczamy go w katalogu /etc/skel
Gdy przyjrzymy się plikowi /etc/passwd zaraz po zainstalowaniu systemu okaże się ze jest w nim wiele wpisów. W większości są to domyślne wpisy wymagane przez niektóre programy. W celu podniesienia bezpieczeństwa dokonamy edycji niektórych wartości a parę z nich usuniemy całkowicie.
Zanim przejdziemy do edycji pliku /etc/passwd zapoznamy się z jego budową.
Jak wcześniej wspomniałem każdy wiersz odpowiada jednemu użytkownikowi a jej format to:
Unikatowa nazwa użytkownika w systemie. Nie powinna zawierać dużych liter
Hasło do systemu. W większości przypadków jest to "x" świadczący że system używa tzw. shadow. Ze względu na bezpieczeństwo zaszyfrowane hasła umieszczane są pliku /etc/shadow, z prawami do czytania tylko dla administratora systemu. Plik /etc/passwd może czytać każdy użytkownik systemu.
Numer identyfikacyjny użytkownika
Numer identyfikacyjny grupy do jakiej należy użytkownik
To pole jest opcjonalne i służy wyłącznie do przechowywania informacji na temat użytkownika (General Electric Comprehensive Operating System)
każdy użytkownik posiada swój katalog domowy. Ścieżka do tego katalogu przechowywana jest w zmiennej środowiskowej $HOME.
domyślna powłoka uruchamiana po zalogowaniu
Usuwamy użytkowników:
Dodajemy /dev/null jako shell dla pozostałych prócz root i kont stworzonych przez nas samych.
Aby wszystko działało poprawnie dodajemy wiersz /dev/null do pliku /etc/shells
| Tip: |
| Na wielu stronach znajdziecie przykłady z dodawaniem /bin/false jako domyślnego shell'a. Ten sposób jest jednak bezpieczniejszy. |
Usuwamy grupy:
Firewall to jeden z lepszych sposobów zabezpieczania systemów przed różnego rodzaju zdalnymi atakami. Idea stojąca za każdym firewallem polega na dopuszczaniu do serwera tylko pożądanego ruchu a odrzucaniu ruchu podejrzanego. Obecnie najlepszym narzędziem do konfiguracji firewalla jest iptables. Pełny opis tego narzędzia znajdziesz pod adresem http://iptables-tutorial.frozentux.net/iptables-tutorial.html. Jest to moim zdaniem najlepsze dostępne na Internecie opracowanie tego tematu.
Ponieważ temat konfiguracji firewall'a można ciągnąć w nieskończoność postanowiłem pójść na skróty. Opisze jak przy pomocy jednego z wielu dostępnych na Internecie narzędzi wygenerować firewall.
- Wchodzimy na stronę http://easyfwgen.morizot.net/gen/
- Wpisujemy nazwę interfejsu przez który mamy dostęp do Internetu
- Jeśli otrzymujemy od ISP adres za pośrednictwem DHCP zaznaczamy Dynamic Internet IP Address jeśli mamy statyczny to Static Internet IP Address
- Jeśli chcemy udostępniać Internet sieci wewnętrznej zaznaczamy Gateway/Firewall w przeciwnym wypadku zostawiamy ustawienie domyślne
- Zaznaczamy Allow Inbound Services
- Naciskamy Generate Firewall. Strona wyświetla się ponownie z dodatkowymi opcjami
- W części Single System or Private Network Gateway wypełniamy odpowiednio nazwę i adresy interfejsu do którego podłączona jest sieć lokalna.
- Zaznaczamy Advanced Network Options
- W części Allow Inbound Services zaznaczmy SSH oraz inne usługi które mamy uruchomione na naszym serwerze. Jeśli instalowałeś serwer zgodnie z moim opisem to powinieneś mieć tylko SSH
- Naciskamy Generate Firewall. Strona wyświetla się ponownie z dodatkowymi opcjami
- W części Advanced Network Options zaznaczamy Internal DHCP Server, Mangle the Packet TTL
- Naciskamy Generate Firewall. Strona wyświetla się ponownie z dodatkowymi opcjami
- Wpisujemy 128 w dodatkowym polu - wiersz Mangle the Packet TTL
- Naciskamy Generate Firewall. I mamy nasz firewall
Teraz wystarczy skopiować wygenerowany firewall i zapisać w katalogu /etc/rc.d w pliku o nazwie rc.firewall. Pamiętaj, że jeśli zapisujesz plik pod Windows to powinieneś użyć programu, który zapisze plik tekstowy w wersji dla systemu Linux. Ja w takich przypadkach używam EmEditor.
Nie zapomnij o zmianie praw pliku na wykonywalny: chmod 0700 /etc/rc.d/rc.firewall
Na koniec musimy jeszcze znienić wewnątrz pliku firewalla wartość zmiennych IPT, IPTS, IPTR jak poniżej:
Polecam przejrzeć strukturę wygenerowanego powyżej firewall'a i postarać się zrozumieć jego działanie. Pomoże nam w tym strona podana na początku. Naprawdę warto poświecić kilka godzin na zrozumienie działania iptables. Pomoże nam to rozwiązać wiele problemów w dalszej pracy i zabezpieczaniu Slackware.
| Tip: |
| Pamiętaj również, że jeśli masz jednocześnie skonfigurowane tcpwrappers i firewall to działają one jednocześnie. Jeśli jakieś połączenie zostanie dopuszczone przez firewall to niekoniecznie zostanie dopuszczone przez tcpwrappers. |
Na koniec przygotowałem przykładowy firewall wygenerowany przy pomocy powyższej strony dla następującej konfiguracji:
Interfejs internetowy - eth0 - konfigurowany przez DHCP naszego dostawcy.
Interfejs sieci wewnętrznej - eth1:
IP: 192.168.0.1
Sumask: 255.255.255.0
Broadcast: 192.168.0.255Usługi udostępniane na serwerze:
SSH na (eth0 i eth1)
Serwer DHCP (eth1)Inne:
Ustawienie TTL dla wszystkich wychodzących pakietów na 128
Firewall:
Do ściągnięcia tutaj.
| Tip: |
| Uwaga: Jeśli zamierzasz używać tego firewalla to niepotrzebne są już wpisy które opisałem w rozdziale 9. Konfiguracja Sieci do pliku /etc/rc.d/rc.local. |
Powyższy firewall nie jest zbyt skomplikowany i nie zapewni całkowitej ochrony. Nie broni nas między innym przed atakami DoS ( Denial of Service ) lub odmianami takimi jak DDoS ( Distributed Denial of Service). Napisanie dobrego firewalla to naprawdę ciężka i długa praca. Każdy z firewalli przystosowany jest do wymagań konkretnej sieci więc trudno mówić ogólnie.