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:
- 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:
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:
- 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. |
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 |
| brak |
DenyUsers |
| #LoginGraceTime 2m |
LoginGraceTime 30 |
| #MaxStartups 10 |
MaxStartups |
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
AllowUsers ???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.
- 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:
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: |
|
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 ]