Nowości O Extended Slackware Lista pakietów Changelog Kto dał paczki Dział porad Lista mirrorów pkgtools-ng English version |
Migracja slackware'owca na PAMData dodania: Sun, 16 Oct 2005 06:12:25 +0200 Autor: dozzie Co to jest PAM? Czym PAM nie jest?PAM to skrót od pluggable authentication module. PAM jest biblioteką służącą do uwierzytelniania użytkowników, zmiany haseł i tym podobnych rzeczy. Dzięki PAM możesz scentralizować zarządzanie użytkownikami, na przykład przenosząc konta do bazy MySQL albo LDAP, przy czym aplikacje wymagające uwierzytelnienia nie muszą być rekompilowane. Ba! Nie muszą być nawet przystosowane do pracy z MySQL czy LDAP! Aplikacja pyta się biblioteki PAM, czy dany użytkownik ma prawo się połączyć, a PAM odpowiada TAK lub NIE. PAM jednak nie jest zamiennikiem dla prawa SUID. PAM nie przydziela dodatkowych praw. PAM służy jedynie do potwierdzenia, że użytkownik jest tym, za kogo się podaje i ma w danej chwili prawo połączyć się z daną usługą. Przyznanie uprawnień przyznanych użytkownikowi należy do aplikacji, co zwykle oznacza, że musi ona być uruchomiona z dodatkowymi prawami (na przykład prawami roota). Kiedy warto używać PAM?Wystarcza ci logowanie na podstawie haseł z /etc/passwd i /etc/shadow? Nie potrzebujesz wymuszać odpowiedniej siły hasła przy jego zmianie? Polityka pozwala użytkownikom logować się, kiedy tylko chcą? To nie potrzebujesz PAM. Moduł pam_cracklib automatycznie sprawdza przy zmianie hasła, czy podane hasło nie jest zbyt łatwe do złamania przy użyciu słownika, a pam_opie pozwoli na zalogowanie się za pomocą haseł jednorazowych. pam_ldap i pam_mysql z kolei pobiorą dane o użytkowniku ze stosownej bazy danych, niekoniecznie znajdującej się na tej samej maszynie, na której loguje się użytkownik. Niestety, nic za darmo. PAM jest trudny w konfiguracji, jeśli zaczynasz od zera. Nawet gdy masz już wcześniej przygotowane pakiety, bardzo łatwo jest popełnić pomyłkę i wystawić jakieś konto bez hasła albo zablokować sobie dostęp do roota. Tak więc najpierw RTFM, potem dokładnie przemyśl, co robisz, przygotuj sobie możliwość logowania z pominięciem PAM (/bin/su z pakietu shadow ze standardowej dystrybucji Slackware jest całkiem dobry, o ile pamięta się o ustawieniu na nim prawa SUID), a dopiero na koniec zabieraj się do zmieniania czegokolwiek. InstalacjaNajprościej jest zainstalować PAM z pakietu. Extended Slackware zawiera pakiet z PAM od dość dawna, podobnie jak pakiety openssh, shadow i sudo skompilowane z obsługą PAM. Jeśli masz ochotę na samodzielną kompilację, to ./configure && make && make install załatwia sprawę. Nie zalecam jednak tej metody instalacji z powodów, które zostały wymienione w slackbuild howto. Sama instalacja PAM to nie wszystko. Daemony usług wymagających zalogowania się, takie jak SSH, FTP, shadow (/bin/login, /bin/su) i sudo, powinny jeszcze zostać skompilowane z obsługą PAM (zwykle jest to opcja --enable-pam lub --with-pam przy ./configure). Zwykle nie sprawia kłopotów dodanie odpowiedniej opcji do slackbuilda i przekompilowanie pakietu. KonfiguracjaPAM jest konfigurowany osobno dla każdej aplikacji (a w zasadzie dla każdej usługi, bo aplikacja korzystająca z biblioteki PAM podaje nazwę usługi; zwykle jedna aplikacja nie używa więcej niż jednej nazwy usługi). Wybrane moduły dla programów znajdują się w plikach /etc/pam.d/<appname> (możliwe jest umieszczenie konfiguracji w jendym wspólnym pliku /etc/pam.conf, jednak takie rozwiązanie jest niewygodne z punktu widzenia systemu pakietów). Każda usługa może korzystać z czterech kontekstów wywołania biblioteki: uwierzytelnienie użytkownika (authentication, w konfiguracji zwana auth), autoryzacja, zwana zarządzaniem kontem (account management, w konfiguracji określane jako account), otwarcie/zamknięcie sesji (session management, w konfiguracji session) i zmiana właściwości hasła (password management, w konfiguracji password). Podczas uwierzytelniania sprawdzane jest tylko to, czy użytkownik jest tym, za kogo się podaje (zwykle oznacza to sprawdzenie podanego hasła z zapisem w bazie użytkowników). Stan konta (na przykład termin ważności hasła lub konta) nie jest tutaj sprawdzany, podobnie jak to, czy użytkownik ma prawo zalogować się o tej porze czy skorzystać z tej właśnie usługi (przynajmniej bezpośrednio). Do tego wszystkiego został przeznaczony kontekst account. Kontekst session służy do zapisania w dzienniku logowania użytkownika, ustawienia zmiennych środowiskowych, nałożenia limitów na ilość czasu procesora i wypisania różnych komunikatów powitalnych, jak "You have new mail" czy MOTD. W password dzieje się trochę więcej, niż sama zmiana hasła. Ten kontekst dotyczy również zmiany daty ostatniej modyfikacji i terminu ważności hasła.
Nie wszystkie wymienione moduły muszą być wymagane do poprawnego zalogowania
się. Niektóre mogą być opcjonalne, a niektóre mogą wystarczać bez pozostałych
modułów z konfiguracji (taka konfiguracja w danym kontekście jest nazywana
łańcuchem). PAM pozwala użycie czterech sposobów reakcji na porażkę modułu
w danym łańcuchu: required, requisite, sufficient
i optional. W konfiguracji PAM (a przynajmniej Linux PAM, który do tej pory miałem okazję dostosowywać) dzięki dyrektywie include daje się użyć wspólnych, globalnych ustawień. Zamiast wszędzie wpisywać auth required pam_unix.so wystarczy dla kontekstu auth wstawić auth include common-auth. To oczywiście oznacza, że w /etc/pam.d musi istnieć plik common-auth zawierający moduły niezbędne do uwierzytelnienia użytkownika, jak pam_unix, pam_unix2 czy pam_opie. Jesli konfiguracja dla danej usługi nie zostanie znaleziona, wtedy brany pod uwagę jest łańcuch z pseudousługi other (/etc/pam.d/other). Teorii chyba na razie już dość. Pewnie interesują cię przykłady konfiguracji. # # /etc/pam.d/common-account - authorization settings common to all services # # This file is included from other service-specific PAM config files, # and should contain a list of the authorization modules that define # the central access policy for use on the system. The default is to # only deny service to users whose accounts are expired in /etc/shadow. # account required pam_unix.so To jest dość prosta konfiguracja sprawdzania stanu konta. pam_unix sprawdzi w /etc/shadow (albo w bazie NIS), czy konto użytkownika, na którego jest przeprowadzana próba logowania, nie jest przeterminowane. Ten plik jest zwykle włączany przez wszystkie pliki konfiguracyjne usług wymagających kontekstu account. Teraz coś nieco bardziej skomplikowanego: konfiguracja dla su. # # The PAM configuration file for the Shadow `su' service # # Allow root to su to everybody without prompting for password auth sufficient pam_rootok.so # Disallow using su to any user not in wheel group auth requisite pam_wheel.so use_uid group=wheel auth include common-auth account include common-account session include common-session
W kontekście uwierzytelniania użytkownika wystarczający jest UID równy
0. Pytania o hasło nie zostaną zadane, ponieważ root ma prawo zmienić UID na
dowolny, niezależnie od tego, czy zna hasło na to konto, czy nie. To
zachowanie jest zapewniane przez moduł pam_rootok. # # /etc/pam.d/common-auth - authentication settings common to all services # # This file is included from other service-specific PAM config files, # and should contain a list of the authentication modules that define # the central authentication scheme for use on the system # (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the # traditional Unix authentication mechanisms. # Last authentication method should be required, because in the other case if # some config file which includes common-auth has 'auth required' or 'auth # requisite', then even if all authentication methods fail, user could use # program. # Try unix password. It's enough for me if it passes. auth sufficient pam_unix.so nullok # If normal password fails, try asking user for one time password. Of course # this line is useless unless you've installed OPIE PAM module. auth sufficient pam_opie.so auth required pam_deny.so Tym razem oglądamy konfigurację procesu uwierzytelniania. Zgodnie z komentarzem, w tym pliku przynajmniej jeden moduł powinien być wymagany. Ja zdecydowałem się na pam_deny, który odrzuca wszelkie próby uwierzytelnienia. Wcześniej znajdują się dwa moduły, które są do uwierzytelnienia wystarczające. Jeśli pierwszy zawiedzie, nie stanie się nic strasznego i zostanie wywołany drugi. Jeśli i on zawiedzie, wywołany zostanie kolejny. Natomiast jeśli któryś zwróci kod sukcesu (użytkownik poda poprawne hasło wielokrotne albo jednorazowe), proces uwierzytelniania zostanie natychmiast zakończony sukcesem. To oznacza, że dołączenie tego pliku powinno się odbywać po uwierzytelnianiu specyficznym dla danej usługi. Jeszcze słowo o konfiguracji domyślnej (usługa other). Moim zdaniem tutaj powinien się znaleźć bardzo restrykcyjny zestaw modułów. # # /etc/pam.d/other - fallback for non-configured services # # Appropriate section from this file is used if one service doesn't have # configuration for it's PAM request type. By default we don't allow anything, # but warn in syslog(8) that there is something to be configured. # auth required pam_warn.so auth required pam_deny.so password required pam_warn.so password required pam_deny.so session required pam_warn.so session required pam_deny.so account required pam_warn.so account required pam_deny.so pam_warn zapisze w syslogu informacje o próbie użycia biblioteki PAM przez nieskonfigurowaną usługę (jako typ zdarzenia auth; te zdarzenia w Slackware zostają zapisane w /var/log/secure, w innych dystrybucjach to może być /var/log/auth.log). pam_deny odmówi usługi użytkownikowi. Tak naprawdę tylko zwróci kod błędu, na co jednak aplikacje zwykle reagują odmową dostępu. Dlaczego akurat tak? Dzięki pam_deny brak konfiguracji usługi nie przejdzie niezauważony, a dzięki pam_warn będzie wiadomo, dla którego kontekstu konfiguracji brakuje. Wpisy w syslogu wyglądają następująco: Oct 16 15:11:38 hans PAM-warn[2132]: function=[pam_sm_authenticate] service=[su] terminal=[pts/3] user=[dozzie] ruser=[dozzie] rhost=[<unknown>] Oct 16 15:12:55 hans PAM-warn[2149]: function=[pam_sm_acct_mgmt] service=[su] te rminal=[pts/3] user=[dozzie] ruser=[dozzie] rhost=[<unknown>] Oct 16 15:13:27 hans PAM-warn[2152]: function=[pam_sm_open_session] service=[su] terminal=[pts/3] user=[dozzie] ruser=[dozzie] rhost=[<unknown>] Oct 16 15:14:04 hans PAM-warn[2158]: function=[pam_sm_chauthtok] service=[passwd ] terminal=[<unknown>] user=[dozzie] ruser=[<unknown>] rhost=[<unknown>] Wszystkie cztery wpisy pochodzą z modułu pam_warn w kontekstach auth (function=pam_sm_authenticate), account (function=pam_sm_acct_mgmt) i session (function=pam_sm_open_session) w konfiguracji usługi su (service=su). Ostatni jest wynikiem braku konfiguracji usługi passwd w kontekście password (function=pam_sm_chauthtok). Jest jeszcze jedna rzecz, na którą warto zwrócić uwagę. Sam już dwukrotnie popełniłem ten błąd, przy czym w pierwszym przypadku wyśledzenie miejsca wystąpienia zajęło mi dobre dwa dni. Oct 16 15:15:11 hans su[2168]: PAM pam_parse: expecting return value; [...requir e] Taki wpis pojawia się, gdy w pliku konfiguracyjnym zamiast słowa required zostanie użyte require. Bardziej obrazowo, zamiast account required pam_unix.so w pliku konfiguracyjnym pojawi się account require pam_unix.so Wpis w syslogu jest niezależny od kontekstu, w którego opisie błąd został popełniony. Konfiguracja OpenSSHOpenSSH domyślnie nie używa PAM, nawet mimo zlinkowania go z tą biblioteką. Chęć korzystania z PAM trzeba jeszcze zaznaczyć w konfiguracji. Na szczęście wystarczy dodać UsePAM yes w /etc/ssh/sshd_config i zrestartować daemona SSH. Uwaga: użyj polecenia /etc/rc.d/rc.sshd restart, a nie kolejno ... stop i ... start. stop odcina wszystkie połączenia SSH włącznie z bieżącą sesją, w przeciwieństwie do restart, więc nie będziesz mieć nawet szansy ponownego uruchomienia daemona SSH. Uwagi końcowe
Wiem z doświadczenia, że łącza potrafią być zawodne. Staraj się nie pracować
nad konfiguracją PAM zdalnie, bo to się może skończyć odcięciem dostępu.
Jeśli naprawdę nie masz innego wyjścia, upewnij się, że logujesz się przez
SSH za pomocą klucza publicznego (zwykle jest sprawdzany przed
logowaniem interaktywnym, czyli przed użyciem PAM). Oprócz tego zapewnij sobie
możliwość zdobycia uprawnień roota. Możesz do tego użyć /bin/su
z pakietu shadow z oryginalnej dystrybucji Slackware (rozpakowujesz ten plik,
zmieniasz właściciela na użytkownika root, po czym nadajesz prawa 4711). Ja
sam mam zainstalowane i skonfigurowane sudo, przy czym
sudo ma autonomiczną konfigurację PAM, bez żadnego włączania
plików globalnych. Wprawdzie to nieco utrudnia zmianę metody uwierzytelniania
(zmiany trzeba wprowadzić w dwóch miejscach, a nie w jednym), z drugiej jednak
strony dzięki temu ewentualna pomyłka w konfiguracji globalnej nie odcina mi
możliwości wykonania poleceń jako root. Rzecz jasna, sudo
wymaga jeszcze odpowiedniej konfiguracji
w /etc/sudoers. |