Andrzej Talarek, styczeń 2003
Technologie zapewniające bezpieczeństwo w systemach operacyjnych
1. Po co?
2. Kerberos
3. PAM
Po co?
Dawniej, gdy sieć (internet) nie była jeszcze tak bardzo rozległa, ludzie nie używali szyfrowania (przynajmniej w zastosowaniach domowych).
Teraz niestety protokoły przesyłające nieszyfrowane hasła (ang. plain password) są już niewystarczające.
Problem ten jest częściowo rozwiązany przez użycie "ścian ogniowych", ale te są bezpieczne tylko, gdy założy się jedną rzecz - że atakujący
są "na zewnątrz"... niestety jest to bardzo błędne założenie i spora część niebezpiecznych ataków odbywała się z wewnątrz.
Dodatkowo ściany ogniowe są bardzo sztywne i ciężkie do dostosowania w przypadku dużych dużych projektów.
Na każdym routerze (i w wielu innych miejscach ;), przez którego przechodzi dany pakiet istnieje łatwy sposób "podsłuchania"
(ang. sniff) zawartości pakietu - a stąd już prosta droga do zdobycia hasła i "podszywania" (ang. spoofing)
pod inne osoby - co z kolei prowadzi do...
Z tego właśnie względu protokoły typu http/ftp/telnet/pop3/smtp i wszystkie inne,
które nie używają szyfrowania są niebezpieczne.
W aplikacjach typu klient/serwer potrzebna jest autentykacja oraz autoryzacja każdego użytkownika i to z reguły po
"obu" stronach połączenia.
Nikt obcy nie powinien mieć możliwości podszycia się ani pod klienta, ani pod serwer.
Również całe połączenie i wymiana komunikatów powinna być niedostępna dla niepowołanego użytkownika
- czyli najczęściej szyfrowana.
Z tego to powodu powstało wiele systemu uwierzytelniania użytkowników oraz zapewnienia im bezpiecznego
kanału komunikacyjnego.
Jednym z nich takich systemów jest Kerberos - protokół sieciowej autentykacji.
Został zaprojektowany jako silne narzędzie autentykujące dla aplikacji klient-serwer.
Do szyfrowania używa on dwóch kluczy - prywatnego oraz publicznego.
System został stworzony na Massachusetts Institute of Technology (MIT) i ta implementacja
jest darmowa - ale dostępnych jest również wiele komercyjnych produktów, opartych o
Kerberosa.
Keberos nie tylko służy jako narzędzie uwierzytelniające, lecz również (po nawiązaniu połączenia) szyfruje całą komunikację miedzy serwerem
a klientem.
Autentykacja odbywa się w kilku krokach, które przedstawię za chwilę - wcześniej jednak kilka założeń, z których wychodzi KERBEROS:
- silne hasła - KERBEROS zakłada, że użytkownicy używają silnych haseł; oznacza to, że ataki typu "Brute Force" nie odnoszą skutku,
- bezpieczeństwo lokalne - dla KERBEROSA jedynym niebezpiecznym miejscem jest sieć, przez która odbywa się połączenie,
W systemie KERBEROS najważniejszą sprawą są klucze.
Musi istnieć jakiś serwer autentykujący (AS - authentication server), który generuje (a potem "trzyma") klucze dla
użytkowników na podstawie podanego przez nich hasła.
Jeśli już jest to spełnione, to proces uwierzytelniania wygląda następująco:
- Użytkownik wysyła komunikat do serwera uwierzytelniającego. Informuje on o potrzebie nawiązania komunikacji z serwerem danych.
- Serwer uwierzytelniający przygotowuje dwie kopie klucza sesji. Będzie on wykorzystywany przy wszystkich transakcjach pomiędzy
użytkownikiem a serwerem danych.
- Tworzony jest komunikat informujący o utworzeniu klucza dla ustanawianej sesji (box1). Umieszczana jest w nim również pierwsza kopia
klucza sesji. Szyfrowanie komunikatu jest oparte na kluczu użytkownika przechowywanym na serwerze uwierzytelniającym.
- Druga kopia klucza sesji trafia do kolejnego komunikatu (box2), określanego nazwą bilet (ang. ticket).
W komunikacie tym zawarty jest identyfikator określający nazwę użytkownika inicjującego komunikację.
Szyfrowanie komunikatu jest oparte o klucz usługi, przechowywany na serwerze uwierzytelniającym.
- Oba komunikaty są przesyłane użytkownikowi.
- Użytkownik odbiera skierowaną do niego wiadomość przy użyciu własnego klucza prywatnego. Otrzymuje w ten sposób bezpiecznie
przesłany klucz sesji, który będzie niezbędny w komunikacji z serwerem.
- Użytkownik musi w kolejnym kroku utworzyć trzeci komunikat, określany nazwą wartość uwierzytelniająca (ang. authenticator).
Jego podstawową zawartością jest określenie bieżącego czasu. Dołączone mogą być również inne informacje zapewniające dodatkowe
uwierzytelnienie użytkownika - jako uzupełniające zabezpieczenie przed podszyciem się osoby trzeciej.
Do szyfrowania wykorzystywany jest otrzymany przez użytkownika klucz sesji.
- Zarówno bilet, jak i wartość uwierzytelniająca są przesyłane do serwera danych w celu weryfikacji użytkownika.
- Serwer danych otwiera oba komunikaty. Bilet jest otwierany przy użyciu klucza prywatnego serwera. Odczytuje on z niego klucz sesji.
Przy jego użyciu otwierana jest wartość uwierzytelniająca. Pozwala ona określić czas trwania operacji. Zbyt długa przerwa pomiędzy
wydaniem biletu, a utworzeniem wartości uwierzytelniającej rodzi podejrzenie o przechwycenie biletu w trakcie przesyłania.
Bilet taki mógłby zostać wykorzystany przez system podszywający się pod klienta.
- W zależności od wymaganego poziomu bezpieczeństwa transakcji, użytkownik może wymagać również weryfikacji tożsamości serwera danych.
W tym celu serwer umieszcza znacznik czasu z komunikatu wartości uwierzytelniającej w nowym komunikacie. Dołącza do niego również
identyfikator określający jego nazwę. Dane są szyfrowane przy użyciu klucza sesji i zwracane użytkownikowi.
- Użytkownik otwiera zwrotny komunikat uwierzytelniający przy użyciu klucza sesji. Jeżeli nazwa serwera danych jest poprawna,
realizowanie transakcji pomiedzy obiema stacjami może zostać rozpoczęte. Dalsze transmisje będą już szyfrowane
przy użyciu utworzonego dla pojedyńczej sesji klucza.
Wady systemu Kerberos:
Najpoważniejszą wadą tego protokołu jest buforowanie hasła po stronie klienta.
Za każdym razem, gdy przychodzi do klienta box1, ten musi go odkodować, używając do tego swojego prywatnego klucza.
Jest to najczęściej rozwiązywane przez użycie buforowania hasła. A do zaś umożliwia odczytanie hasła wprost z bufora.
Powoduje to niebezpieczeństwo dostania się hasła w niepowołane ręce.
Problem ten rozwiązywany jest zazwyczaj przez użycie Serwerów Przyznających Bilety (ang. TGS - Ticket Granting Server).
TGS jest usługą rozłączną z AS, chociaż nie ma obowiązku uruchamiania jej na osobnej maszynie.
Teraz użytkownik przed podłączeniem się do żądanej usługi, żąda biletu, do połączenia z TGS - tak jakby była to inna, normalna usługa.
Bilet ten nazywany jest GTG (ang. ticket granting ticket;).
Po otrzymaniu TGT, za każdym razem, gdy użytkownik żąda dostępu do usługi, prosi o bilet nie AS, tylko TGS.
Odpowiedź nie jest szyfrowana kluczem użytkownika, tylko kluczem sesji, dostarczonym przez AS do użytkowania TGS.
W środku odpowiedzi jest nowy klucz sesji, dla żądanej usługi. Reszta komunikacji jest jak poprzednio.
Jest to czymś w rodzaju "tymczasowego dokumetu tożsamości"...
Różnica jest taka, że zazwyczaj hasła ważne są miesiącami (latami?;), podczas gdy TGT ważne jest bardzo krótki okres czasu (zazwyczaj 8 godzin).
Najnowszą wersję Kerberos 5 (1.2.7) można sciągnąć stąd.
Niestety - ze względu na ograniczenia eksportowe narzucone przez rząd Stanów Zjednoczonych na zaawansowane technologie kryptograficzne,
Kerberos w wersji 5 można sciągać tylko w USA...
...lub poszukać innego niż oficjalne źródła, tudzież wersję inną niż tą opracowaną na MIT.
PAM - Pluggable Authentication Modules
Od niepamiętnych czasów uwierzytelnianie w systemach UNIXowych wyglądało tak samo:
Użytkownik wpisywał hasło, system kodował hasło (tzw. jednostronną funkcją), porównywał z wpisem w pliku /etc/passwd
(później dla utrudnienia ataków typu Brute-Force zakodowane hasła przeniesiono do /etc/shadow),
gdzie były uprzednio zakodowane identyczną funkcją "wzory" haseł,
i jeśli oba były równe, to użytkownik zostawał dopuszczony do systemu.
Było to dosyć bezpieczne, lecz miało kilka wad. Największą z nich był całkowity brak elastyczności.
Jeśli jakiś administrator zażyczył sobie innego rodzaju autentykację systemową, wymagała tego jakaś usługa serwera,
bądź opracowano "nową" wersję używanego do tej pory systemu autentykacji, to trzeba było poprawiać wszystkie programy,
które z tego korzystały.
Było tylko kwestią czasu, gdy ktoś wprowadzi nowe rozwiązanie. Zrobiła to w końcu firma SUN.
Dodatkowo znacznie rozwinęła się technika autentykacji. Zaczęto powszechnie stosować rozwiązania sprzętowe typu Dumb Cards, czy potem
Smart Carts, skanowanie siatkówki czy odciska palców. Dostosowanie nowego systemu autentykacji do starego systemu
było bardzo praco(i koszto)chłonne, bo wymagało przebudowywania znacznych ilości oprogramowania.
I tutaj właśnie z pomocą przyszedł system PAM, czyli dołączalnych modułów uwierzytelniających.
PAM opiera się na rozłączneniu procesu uwierzytelniania, od użytego do tego sposobu. System dołącza sobie "w locie" moduł, którego
w danej chwili chce użyć do autentykacji użytkownika. Jest to na podobnej zasadzie, co inetd, czyli internetowy superserwer,
który słucha na różnych portach i w razie potrzeby budzi ("używa") program realizujący daną usługę.
Daje to wielką elastyczność oraz możliwości rozbudowy systemu o wiele działających niezależnie od siebie modułów uwierzytelniających
np. dla każdej usługi oferowanej przez serwer osobno.
Co potrzeba, żeby włączyć obsługę PAM w swoim Linuxie?
- zainstalowaną bibliotekę libpam.so{.X.YY},
- jakiś moduł pam_ZZZZ.so,
- plik /etc/pam.conf,
- jakieś aplikacje, skompilowane do obsługi PAM,
Z reguły do większości oprogramowania istnieją patche, umożliwiające współpracę z PAMem.
Krótki opis składni pliku /etc/pam.conf powinien dać ogólny widok na kształt PAM
service-name | module-type | control-flag | module-path | args |
Teraz następujące wpisy oznaczają:
- service-name - nazwa usługi "żądającej" uwierzytelniania; przy czym słowo-klucz OTHER oznacza "resztę" usług systemowych,
- module-type - jeden z (aktualnie) czterech typów modułów, determinuje on sposób zachowania się modułu,
- control-flag - determinuje jak ma zachować się biblioteka PAM w obliczu sukcesu lub porażki modułu, z którym jest związana,
- module-path - ścieżka dostępu do dynamicznie ładowalnego pliku obiektowego, czyli dołączanego modułu,
- args - argumenty, przekazywane do modułu, gdy ten jest wywoływany,
Od wersji 0.56 jest możliwość konfiguracji PAM przy użyciu katalogu /etc/pam.d, w którym są osobne pliki dla
każdej usługi. Ma to zalety raczej wyłącznie kosmetyczno-porządkowe - trudniej się pomylić, gdy wypełniamy odobny plik dla każdej usługi,
niż gdy ustawiamy setną linijkę podobnych wpisów.
Gdy używamy PAM w praktyce, to trzeba zawsze pamiętać, że wykasowanie jej plików konfiguracyjnych całkowicie zablokuje
nasz system.
Najnowszą wersję Linux-PAM (0.77) można sciągnać z ftp://linux.kernel.org/pub/linux/libs/pam