Asmo Slackware Page

8th September 2010

.::MENU::.

Wstęp
Mapa serwisu
Instalacja
Serwery
Artykuły
Tips&Tricks
Programowanie
ASP changelog
FORUM
FAQ
Linki
Ksiega gosci
O mnie

GG:
1710841


11.1 Internet "super-serwer" - Inetd

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".

Co to jest inetd?

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:

<adres>:<nazwa usługi> <rodzaj gniazda> <protokół> <opcje> <użytkownik.grupa> <program serwera> <argumenty>

Kolumny oznaczają odpowiednio:

Nazwa usługi

taka jak nazwa usługi w pliku /etc/services.

Adres

nieobowiązkowepole 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ądatak:

ftp stream tcp nowait root /usr/sbin/tcpd proftpd

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 ).

Wyłączanie domyślnie włączonych usług

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ę:

# grep -v '^#' /etc/inetd.conf

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ę:

# kill -HUP `cat /var/run/inetd.pid`

Ponieważ zakomentowaliśmy wszystkie usługi równie dobrze możemy wydać polecenie:

# kill -9 `cat /var/run/inetd.pid`

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).

11.2 Network File Systems

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:

# . /etc/rc.d/rc.portmap stop
# . /etc/rc.d/rc.nfsd stop

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.

11.3 TCPD - tcpwrappers demon - kontrola dostępu

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:

  1. Nadchodzi żądanie połączenia z portem powiedzmy 21 (FTP)
  2. inetd przejmuje nad nim kontrole i uruchamia tcpd
  3. tcpd sprawdza czy wykonujący połączenie ma prawo by się z nami łączyć
  4. 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:

hosts.allow
ALL: 127.0.0.1
ftp: 192.168.0.10, 192.168.1.
sshd: 192.168.0., czesiek.interia.pl
hosts.deny
ALL:ALL

Plik hosts.allow pozwala na:

  1. połączenia do wszystkich usług z adresu 127.0.0.1
  2. połączenia do serwera FTP z adresów 192.168.0.10 oraz z wszystkich adresów w sieci 192.168.1.0
  3. 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.

11.4 Konfiguracja opcji logowania

opcje logowania

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).

powitania i banery

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ę:

#echo "Welcome to Asmo Box it's \d \t and you are on \l" > /etc/issue

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:

# echo "$(/bin/uname -sr)." > /etc/motd

a następnie czyścimy plik /etc/motd:

# >/etc/motd

zabezpieczanie ssh

Gdy do zdalnego logowania używacie ssh (jeśli nie to powinniście) 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

#PermitRootLogin yes PermitRootLogin no
brak AllowUsers użytkownik1 użytkownik2
brak DenyUsers użytkownik1 użytkownik2
#LoginGraceTime 2m LoginGraceTime 30
#MaxStartups 10 MaxStartups 1/3 ilości użytkowników w systemie nie wicej niż 10

Takie ustawienia są o wiele bardziej restrykcyjne niż standardowe. Przede wszystkim nie pozwalamy na logowanie się jako użytkownik root. Zawsze powinniśmy logować się jako nieuprzywilejowany użytkownik a w momencie gdy potrzebujemy praw roota używać komendy su, np.:

$ su
Password:
# exit
$

Dyrektywy AllowUsers i DenyUsers w łatwy sposób pozwolą nam na ograniczanie dostępu do naszego serwera. Wiem, że jest to trochę niewygodne dodawać i usuwać użytkowników z tych list ale lepsze to niż wpadnięcie w kłopoty. W nazwach użytkowników w tych dyrektywach mogą wystąpić znaki ? oraz * pozwalające na bardziej ogólniejsze wskazanie użytkowników, np:

AllowUsers *ssh #Użytkownicy których loginy kończą się na ssh
AllowUsers ???r #Użytkownicy których login składa się z 4 liter i kończy się na r

Prócz tych dwóch dyrektyw mamy do dyspozycji także AllowGroup i DenyGroup.

Następnie tworzymy plik /etc/ssh/baner i dodajemy do niego np. taki tekst:

Welcome to Asmo Box. Your use of this server is logged and monitored. Unauthorized use of this server will be prosecuted.

Po czym restartujemy serwer sshd:

# . /etc/rc.d/rc.sshd restart

Oczywiście jeśli użytkownik będzie miał trochę wiedzy przeglądnie sobie plik /proc/version i dowie się jaki mamy system :).

zacieranie śladów

Kolejną wartą polecenia zmianą w domyślnej konfiguracji systemu jest stworzenie pliku ~/.bash_logout i dodanie do niego polecenia clear.

# echo clear >> ~/.bash_logout

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

# cp ~/.bash_logout /etc/skel

11.5 Zmiana domyślnej powłoki dla niektórych użytkowników

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:

nazwa konta:haslo:UID:GID:GECOS:katalog domowy:shell

nazwa konta

Unikatowa nazwa użytkownika w systemie. Nie powinna zawierać dużych liter

hasło

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.

UID

Numer identyfikacyjny użytkownika

GID

Numer identyfikacyjny grupy do jakiej należy użytkownik

GECOS

To pole jest opcjonalne i służy wyłącznie do przechowywania informacji na temat użytkownika (General Electric Comprehensive Operating System)

katalog domowy

każdy użytkownik posiada swój katalog domowy. Ścieżka do tego katalogu przechowywana jest w zmiennej środowiskowej $HOME.

shell

domyślna powłoka uruchamiana po zalogowaniu

Usuwamy użytkowników:

# userdel adm
# userdel lp
# userdel sync
# userdel shutdown
# userdel halt
# userdel news
# userdel uucp
# userdel operator
# userdel games
# userdel smmsp
# userdel ftp
# userdel rpc
# userdel pop
# userdel gdm

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

# echo /dev/null >> /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:

# groupdel adm
# groupdel lp
# groupdel news
# groupdel uucp
# groupdel games
# groupdel pop
# groupdel smmsp

11.6 Stawiamy firewall

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.

  1. Wchodzimy na stronę http://easyfwgen.morizot.net/gen/
  2. Wpisujemy nazwę interfejsu przez który mamy dostęp do Internetu
  3. Jeśli otrzymujemy od ISP adres za pośrednictwem DHCP zaznaczamy Dynamic Internet IP Address jeśli mamy statyczny to Static Internet IP Address
  4. Jeśli chcemy udostępniać Internet sieci wewnętrznej zaznaczamy Gateway/Firewall w przeciwnym wypadku zostawiamy ustawienie domyślne
  5. Zaznaczamy Allow Inbound Services
  6. Naciskamy Generate Firewall. Strona wyświetla się ponownie z dodatkowymi opcjami
  7. W części Single System or Private Network Gateway wypełniamy odpowiednio nazwę i adresy interfejsu do którego podłączona jest sieć lokalna.
  8. Zaznaczamy Advanced Network Options
  9. 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
  10. Naciskamy Generate Firewall. Strona wyświetla się ponownie z dodatkowymi opcjami
  11. W części Advanced Network Options zaznaczamy Internal DHCP Server, Mangle the Packet TTL
  12. Naciskamy Generate Firewall. Strona wyświetla się ponownie z dodatkowymi opcjami
  13. Wpisujemy 128 w dodatkowym polu - wiersz Mangle the Packet TTL
  14. 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:

IPT="/usr/sbin/iptables"
IPTS="/usr/sbin/iptables-save"
IPTR="/usr/sbin/iptables-restore"

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.255

Usł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.

[ Poprzednia ] [ Spis treści ] [ Następna ]
©Asmo , last modified: April 20 2008 23:28:35.