wtorek, 11 grudnia 2012

Bezpieczeństwo w systemie GNU/Linux cz.1

Jednak jak nie najważniejsza rzecz w środowisku administracyjnym, co zrobić aby się nie "narobić" po wizycie niechcianych gości? Oczywiście najłatwiej wybudować bunkier, zaminować i nie wchodzić licząc że infrastruktura będzie działać, jednak nie jest to takie proste. Oczywiście ważną kwestią jest ograniczenie do minimum fizycznego dostępu do maszyn, dla osób które muszą do nich mieć dostęp. Oczywiście na wypadek pożaru dobrze mieć instalacje gaśnicze, robić trzeba również kopie zapasowe i przechowywać w innej bezpiecznej lokalizacji. To wszystko jest ważne, jednak nie można zapomnieć o tym że do systemu można dostać się będąc na innym kontynencie, mając do dyspozycji komputer, internet i putty:).
 Dlatego warto wykonać kilka prostych zabiegów, które podniosą bezpieczeństwo naszego systemu. Nie ma i prawdopodobnie w najbliższej przyszłości nie będzie systemów zabezpieczonych całkowicie, no chyba że ktoś odłączy serwer od sieci i będzie na niego patrzył przez pancerną szybę:)


Na początek, jeśli mamy dostęp do serwera poprzez SSH należy pozmieniać kilka ustawień w pliku         nano /etc/ssh/sshd_config:

1) Port 22 (domyślnie), polecam zmienić na wyższy numer np. 5555 lub podobny.

2) Ustawienie jednego adresu do nasłuchiwania żądań w czasie próby podłączenia, ListenAddress 192.168.56.101, oczywiście adres jest przykładowy, oczywiście jeżeli serwer jest widoczny na zewnątrz musi mieć stałe IP, przy zmiennym wiadomo nie ma sensu ustawiać takiego adresu. Ewentualnie w sieci wewnętrznej można coś takie zrobić aby ktoś z użytkowników nie próbował nam wejść do systemu.

3) LoginGraceTime 10 czas potrzebny na wprowadzenie hasła przez nas hasła, wyrażony w sekundach,

4) Dobre trudne hasła w którym będą zarówno duże, małe litery jak i cyfry oraz znaki specjalne. Najlepiej gdy ciąg takich znaków jest przypadkowy.!!!

5) MaxAuthTries 2 liczba reprezentuje ile razy możemy się pomylić przy logowaniu.

6) PermitRootLogin no najlepiej poprzez SSH logować się na zwykłego usera, a na roota przelogować się poprzez su .

7) PermitEmptyPassword no oczywiście głupotą jest zezwolenie na logowanie się bez podawania jakiegokolwiek hasła.

8) Ograniczyć można również użytkowników, którzy mogą się logować poprzez SSH AllowUsers login

Następnie /etc/init.d/ssh restart

Skoro mamy już ustawione sensowne zabezpieczenia dostępu z zewnątrz, zajmijmy się zabezpieczeniem systemu na który loguje się kilku user'ów, czy to wprost do konsoli czy też poprzez serwer plików.

tutaj wchodzimy w zakres praw dostępu do plików oraz katalogów.

Przyznane prawa dla pliku czy katalogu możemy sprawdzić wydając polecenie ls -l nazwa_pliku.


Pojawi się ciąg dziwnych krzaczków, np.-rw-r--r--. Rozszyfrujmy je:

I tak pierwszy znak(w naszym przypadku) "-"(myślnik) wzkazuje, że nasz plik jest zwykłym plikiem, ale mogą tutaj znaleźć się również inne znaki:
# b - plik blokowy
# c - plik znakowy
# d - katalog 
# l - 'małe ly', dowiązanie symboliczne(pozwala skrócić polecenia i nazwać lepsze nazwy)
# p - potok
# s - (socket) gniazdo

Ciąg reprezentujący prawa dostępu można podzielić na grupy 3-y znakowe(pomijając oczywiście znak pierwszy) i tak:


# Pierwsza trójka daje prawa dla użytkownika,

# Druga dla grupy użytkowników,
# Trzecia dla pozostałych użytkowników ,

Każdy zestaw praw składa się z 3 znaczników i tak:


# r - pozwala na odczyt danych(przeszukiwanie zawartości),

# w- pozwala na zapis(prawo do zmiany zawartości)
# x - na wykonanie(np. skryptu lub wejście do katalogu)

Jeżeli natomiast tak jak w naszym przypadku mamy dla usera  rw- (będziemy mieli zapis odczyt na wykonanie brak prawa).


Nadając prawa stosujemy polecenie chmod u+x | g+x | o+x nazwa_pliku/katalogu.  Możemy również zmienić grupę do której należymy za pomocą chgrp :grupa nazwa_pliku


Powyższy przykład dodaje wykonanie dla usera, grupy oraz dla pozostałych. Możemy również jakieś prawo komuś zabrać poprzez zastąpienie znaku"+" znakiem "-", oraz zastąpić prawo poprzez jego skasowanie i nadanie nowego poprzez "+". 


Warto dodać o "t", które jeżeli się pojawi w zbiorze praw pozwala na to, żeby usunąć katalog może jedynie właściciel.


Był to pierwszy sposób, możemy również prawa zmieniać stosować system ósemkowy, czyli taki w którym najwyższym prawem jest "7". Wykorzystujemy również polecenie chmod 777 nazwwa_pliku/katalogu, w przypadku katalogu można dodać przełącznik -R do chmod, aby zmiany były widoczne też dla podkatalogów. 


Teraz pytanie skąd wziąć te wartości? Otóż zastosowanie ma tutaj dodawanie:) I tak:


---  0  prawa nieprzyznane

--x  1  tylko wykonanie
-w- 2  tylko zapis
-wx 3  zapis+wykonanie
r--   4  tylko odczyt
r-x   5  odczyt+wykonanie
rw-  6  informacje na temat komendy
rwx  7  zapis, odczyt, wykonanie

Znając wartości liczbowe pojedynczych praw dodajemy je do siebie uzyskując interesujące nas prawa. Aby dodać dodatkowo lepki bit należy dodać "1", czyli chmod 1777 katalog.


Dobrze mamy zrobione już prawa dla konkretnych plików oraz katalogów należy teraz jeszcze poprawić nieco kontrolę nad kontem root'a. Wystawiając usługi na zewnątrz narażamy się na złapanie czegoś z sieci, co niekoniecznie jest dobre. Dostanie się do systemu robaka który jest w stanie przejąć kontrolę nad kontem głównego administratora praktycznie system robi klops i zaczyna, np. rozsyłać spam z naszej domeny. 


Dlatego dobrym rozwiązaniem jest w codziennej pracy używanie konta roota, ale nie root'a:) Chodzi o to, aby konto na którym pracujemy miało duże prawa, ale nie specjalnie rzucało się w oczy intruzowi. Do tego nie zaszkodzi bezczelnie wyłączyć konta root'a, a jego prawa przenieść.


Utwórzmy nowe konto do systemu, np.:


adduser superja (oczwiście wraz z dobrym trudnym hasłem)

Po dodaniu nowego root'a musimy nieco pozmieniać wpisy w jednym z ważniejszych plików systemowych, czyli /etc/passwd


Wydajemy polecenie 


nano /etc/passwd


Musimy odszukać wpis w gąszczu linijek naszego user'a superja, zmieniamy linijkę reprezentującą na naszą zmodyfikowaną:


superja:x:0:0:,,,:/home/superja:/bin/bash


Tym sposobem nasz superja jest kontem z pełnymi prawami root'a, pozostałe dane wskazują na katalog domowy(dobrze, żeby był może taki który wskazuje na domyślnego user'a utworzonego podczas instalacji) oraz domyślną powłokę.


Najważniejsze zabezpieczenie konta, czyli hasło jest na pierwszy rzut oka jakimś bałaganem, ale tylko na pozór, wszystko to znajduje się w pliku:

nano /etc/shadow

Musimy podrasować hasło, które jest zaszyfrowane. Możemy dodać jakiś ciąg znaków, który zmodyfikuje hasło i wyłączy możliwość logowania. Jeżeli będzie potrzeba zalogowania się ponownie wystarczy usunąć dodatkowe znaki.


Teraz mamy możliwość zalogowania się na nowego naszego root'a


su superja


następnie można sprawdzić parametry naszego user'a:


whoami


I teraz powinniśmy zobaczyć root'a w opisie:)


Jeżeli chcemy udostępnić nieco miejsca dla innych użytkowników warto ograniczyć im dostęp do minimum, czyli jeżeli ma być to FTP, niech wszystko inne będzie niedostępne a czarne okienko w szczególność. Ponieważ przy tworzeniu konta domyślnie system zezwala na logowanie na konto przez SSH. Aby wyłączyć dostęp do konsoli musimy zmienić ustawienia w 2 plikach:


nano /etc/adduser.conf  

nano /etc/default/useradd

Na początku pliku mamy(w Debianie)


SHELL= /bin/bash lub /bin/sh

Zmieniając wpis na:


SHELL= /bin/false


Oczywiście możemy to zmienić w pliku /etc/passwd na końcu linijki z loginem naszego znajomego:)


Ostatnią z podstawowych zabezpieczeń powinno być zadbanie o to, aby nasza maszyna się nie zawiesiła w momencie, gdy ktoś będzie próbował sklonować proces co doprowadzi do problemów w działaniu całego systemu.

Chodzi tutaj o wywołanie tzw. fork-bomb'y. Kod tego problemu jest tak prosty że aż trudno uwierzyć, że może zrobić takie spustoszenie w systemie.

Poniżej kilka przykładów naszego szkodnika:

C:


#include 
 
int main(void)
{
   while(1)
   {
      fork();
   }
   return 0
}

Bash:

:(){ :|:& };: ( jakaś paranoja, wygląda jak emotikon hight level:)

Wyjaśnienie: zdefiniowana jest tutaj funkcja o nazwie ":" nie przyjmująca żadnego parametru. W swoim ciele (ograniczanym przez "{" i "}") wywołuje się rekurencyjnie dwukrotnie, przekierowując wyjście pierwszego wywołania na wejście drugiego wywołania poprzez mechanizm nienazwanych potoków (pipes, "|") i przechodzi do tła – "&" – dzięki czemu zabicie procesu-ojca nie zabije procesów-potomków. Średnik kończy definicję funkcji, a końcowy dwukropek jest jej pierwszym wywołaniem(wikipedia.pl). 

Zapis bardziej "normalny":



bomba()
{
   bomba | bomba &
};
bomba


Perl:


perl -e "fork while fork"

Najlepszym zapobieganiem jest ustawienie limitu procesów, które może system uruchomić, aby nie dostać zadyszki, proste ale skuteczne jak prostota kodu, który psuje nam działanie w systemie.

Możemy to zrobić edytując:

nano /etc/security/limits.com

Możemy ustawić parametr nproc i tym samym ograniczyć liczbę procesów, obrazują  to dobrze przykłady wykorzystania zawarte w tym configu, np:

SafeGroup soft nproc 30
SafeGroup hrad nproc 100

Utworznie grupy SafeGroup i dodanie do niej zwykłych użytkowników pozwoli ustrzec się nam przed fork'iem, gdyby zwykły user chciał odpalić taki kod będzie mógł uruchomić tylko 100 kopi procesu, oczywiście liczby można zmieniać.


W następnej części zajmę się ustawieniem iptables.






Brak komentarzy:

Prześlij komentarz