Uwaga: Oryginalna wersja tego artykułu została opublikowana w IBM developerWorks i jest własnością Westtech Information Services. Poniższy dokument jest poprawioną przez zespół GDP wersją oryginalnego tekstu i nie jest już aktualizowany. |
OpenSSH (patrz Zasoby) to bezpieczny, szyfrowany zamiennik znanych programów telnet oraz rsh. Do jego najbardziej fascynujących zalet należy możliwość autoryzacji użytkowników za pomocą protokołów DSA oraz RSA, opartych o parę uzupełniających się liczbowych kluczy. DSA i RSA pozwalają nawiązywać połączenia ze zdalnymi systemami bez podawania hasła. Jakkolwiek brzmi to zachęcająco, wielu początkujących użytkowników konfiguruje OpenSSH na szybko i otwiera poważną lukę w bezpieczeństwie całego procesu logowania.
Na czym polega autoryzacja RSA/DSA?
SSH, a konkretnie OpenSSH (czyli wolna implementacja SSH) to niesamowite narzędzie. Podobnie jak telnet i rsh, klient ssh pozwala zalogować się na zdalnej maszynie. Wymaga to jedynie uruchomienia na niej sshd, czyli serwera ssh. W przeciwieństwie do telnetu, protokół ssh jest bardzo bezpieczny. Za pomocą specjalnych algorytmów szyfruje strumień danych, zapewnia jego integralność, a ponadto w bezpieczny sposób przeprowadza autoryzację.
Pewien aspekt ssh jest często ignorowany, niebezpiecznie nadużywany lub zwyczajnie niezrozumiany. Aspekt ten to system autoryzacji za pomocą par kluczy RSA/DSA, alternatywny dla standardowego logowania z użyciem haseł, którego OpenSSH używa domyślnie.
Uwierzytelnianie RSA i DSA w OpenSSH jest oparte na parze specjalnie wygenerowanych kluczy, nazywanych kluczem prywatnym i kluczem publicznym. Plusem korzystania z autoryzacji opartej na kluczach jest fakt, że w wielu przypadkach możliwe jest nawiązanie połączenia bez podawania hasła.
Podczas gdy autoryzacja oparta na kluczach jest względnie bezpieczna, problem pojawia się gdy użytkownicy ułatwiają sobie pewnymi skrótami proces logowania, nie rozumiejąc w pełni wpływu tych ułatwień na bezpieczeństwo. Niniejszy artykuł pokazuje jak poprawnie używać RSA i DSA do logowania bez wystawiania się na niepotrzebne ryzyko. W kolejnym pokażę jak korzystać z ssh-agent oraz przedstawię keychain, nakładkę na ssh-agent oferującą wiele ułatwień i nie narażającą przy tym bezpieczeństwa.
Oto krótkie wprowadzenie do kluczy RSA/DSA. Załóżmy, że chcemy za pomocą RSA umożliwić logowanie się z lokalnej maszyny z zainstalowanym Linuksem (localbox) do zdalnej powłoki na remotebox, komputerze naszego ISP. Obecnie, gdy próbujemy się połączyć z remotebox klientem ssh, widzimy następujący komunikat:
Listing 1.1: Łączenie z remotebox |
$ ssh drobbins@remotebox
drobbins@remotebox's password:
|
Jest to przykład domyślnego sposobu autoryzacji ssh. ssh po prostu pyta o hasło do konta drobbins na remotebox. Jeśli je podamy, ssh skorzysta ze swojego bezpiecznego protokołu autoryzacji i prześle je do weryfikacji na remotebox. Jednakże, w przeciwieństwie do telneta, tutaj nasze hasło podlega wcześniej szyfrowaniu, zatem nie może zostać przechwycone przez nikogo podsłuchującego nasze połączenie. Kiedy remotebox porówna podane hasło ze swoją bazą haseł i uzna je za poprawne, zostaniemy zalogowani i zobaczymy znak zachęty powłoki na remotebox. Jakkolwiek metoda ta jest dosyć bezpieczna, RSA i DSA oferują nieco więcej możliwości.
W przeciwieństwie do logowania za pomocą hasła, autoryzacja RSA wymaga wstępnej konfiguracji. Wystarczy ją przeprowadzić raz. Później, logowanie pomiędzy localbox i remotebox odbywać się będzie zupełnie bezboleśnie. Konfigurację rozpoczynamy od wygenerowania pary kluczy, prywatnego oraz publicznego. Klucze te mają pewne ciekawe właściwości. Klucz publiczny służy do szyfrowania wiadomości, którą odszyfrować może jedynie posiadacz klucza prywatnego. Tak więc klucza publicznego używamy wyłącznie do szyfrowania, natomiast prywatnego do rozszyfrowywania wiadomości. Protokół RSA (a także DSA) wykorzystuje te możliwości do przeprowadzania bezpiecznej autoryzacji bez konieczności przesyłania przez sieć jakichkolwiek poufnych informacji.
Następny jednorazowy krok konfiguracji polega na skopiowaniu klucza publicznego na remotebox. Na klucz ten mówimy "publiczny" nie bez powodu. Ponieważ służy on jedynie do szyfrowania wiadomości dla nas, nie musimy się obawiać, że wpadnie w niepowołane ręce. Następnie na remotebox należy go umieścić w specjalnym pliku ~/.ssh/authorized_keys, aby sshd mógł go odnaleźć. Teraz jesteśmy gotowi do logowania za pomocą RSA.
W tym celu wystarczy jak zwykle wpisać na localbox polecenie ssh drobbins@remotebox. Tym razem jednak, ssh informuje sshd na remotebox, że chce skorzystać z RSA. Interesujące jest to co następuje później. sshd z remotebox generuje losową liczbę i szyfruje ją za pośrednictwem naszego klucza publicznego, który wcześniej tam umieściliśmy. Następnie wysyła ją z powrotem do ssh na localbox, który ją odszyfrowuje i przesyła ponownie do remotebox. Przekazuje w ten sposób wiadomość "Widzisz, naprawdę posiadam odpowiedni klucz prywatny; Udało mi się odszyfrować twoją wiadomość!". W końcu sshd uznaje, że może pozwolić się zalogować. Do autoryzacji wystarcza zatem sam fakt posiadania odpowiedniego klucza prywatnego.
Warto zauważyć dwie rzeczy. Po pierwsze, wystarcza wygenerować jedną parę kluczy. Klucz publiczny możemy umieścić na wszystkich maszynach, na których chcemy się logować i wszystkim wystarczy nasz jeden klucz prywatny. Innymi słowy, nie potrzebujemy osobnej pary kluczy dla każdego systemu.
Po drugie, nasz klucz prywatny nie powinien dostać się w niepowołane ręce. Każdy, który go posiada ma dokładnie takie same uprawnienia dostępu jak my. Podobnie jak nie chcielibyśmy, żeby ktoś obcy miał klucze do naszego domu, powinniśmy chronić klucz prywatny. W świecie bitów i bajtów oznacza to, że nikt inny nie powinien mieć uprawnień do jego odczytu oraz kopiowania.
Deweloperzy ssh oczywiście zdają sobie sprawę z ważności kluczy prywatnych. Wbudowali w ssh i ssh-keygen kilka zabezpieczeń, żeby ochronić je przed nadużyciami. Przede wszystkim, ssh wyświetla duże ostrzeżenie jeśli nasz klucz posiada uprawnienia pozwalające komukolwiek oprócz nas go odczytać. Ponadto, kiedy tworzymy parę kluczy, ssh-keygen zapyta o passphrase. Jeśli je podamy, klucz prywatny zostanie zaszyfrowany z jego użyciem, zatem nawet gdy zostanie skradziony, pozostanie bez niego bezużyteczny. Uzbrojeni w tę wiedzę, spójrzmy jak skonfigurować ssh aby używało protokołów RSA i DSA.
Pierwszym krokiem w konfiguracji autoryzacji RSA jest wygenerowanie pary kluczy. Autoryzacja RSA to pierwotna wersja autoryzacji za pomocą kluczy w ssh, zatem będzie działać z każdą wersją OpenSSH. Oczywiście zalecana jeset instalacja możliwie najnowszej dostępnej wersji. W czasie powstania tego artykułu było to openssh-2.9_p2. Wygenerowanie pary kluczy wygląda następująco:
Listing 1.2: Generowanie pary kluczy |
$ ssh-keygen Generating public/private rsa1 key pair. Enter file in which to save the key (/home/drobbins/.ssh/identity): (wciśnij enter) Enter passphrase (empty for no passphrase): (podaj passphrase) Enter same passphrase again: (podaj je ponownie) Your identification has been saved in /home/drobbins/.ssh/identity. Your public key has been saved in /home/drobbins/.ssh/identity.pub. The key fingerprint is: a4:e7:f2:39:a7:eb:fd:f8:39:f1:f1:7b:fe:48:a1:09 drobbins@localbox |
Na pytanie o domyślne położenie kluczy wybieramy domyślną opcję, czyli /home/drobbins/.ssh/identity. ssh-keygen zapisze w tym pliku klucz prywatny, natomiast publiczny w pliku o nazwie identity.pub.
Zapytani o passphrase, wybieramy bezpieczne (siedem lub więcej trudnych do odgadnięcia znaków). ssh-keygen zaszyfruje przy jego użyciu klucz prywatny (~/.ssh/identity), dzięki czemu dla kogoś kto go nie zna, pozostanie on bezużyteczny.
Podanie passphrase pozwala zabezpieczyć klucz prywatny przed nadużyciami, jednakże powoduje pewną niewygodę. Teraz przy każdym połączeniu z kontem drobbins@remotebox, ssh zapyta o to passphrase. Zatem zamiast podawania hasła do konta drobbins, będziemy musieli podać passphrase do klucza prywatnego. Kiedy zostanie odszyfrowany, ssh zajmie się resztą procesu. Podczas gdy mechanizm logowania stanie się zupełnie inny, w praktyce wciąż musimy podać jakieś hasło.
Listing 1.3: Logowanie z passphrase |
$ ssh drobbins@remotebox Enter passphrase for key '/home/drobbins/.ssh/identity': (podaj passphrase) Last login: Thu Jun 28 20:28:47 2001 from localbox.gentoo.org Welcome to remotebox! $ |
Chociaż może się to wydać zachęcające, nie należy tworzyć niezaszyfrowanych kluczy bez pełnego zrozumienia ich wpływu na bezpieczeństwo. Każdy, kto włamie się na localbox automatycznie uzyska dostęp do remotebox i wszystkich innych systemów z umieszczonym odpowiednim kluczem publicznym.
Okazuje się, że istnieje lepszy sposób! Pokażę jak skorzystać z wygód bezhasłowej autoryzacji bez narażania bezpieczeństwa. Wykorzystamy w tym celu ssh-agent (o którym więcej napiszę w kolejnym artykule). Oto instrukcje krok po kroku.
Aby skonfigurować autoryzację RSA, należy wygenerować parę kluczy. W tym celu wystarczy wpisać:
Listing 1.4: Generowanie kluczy... |
$ ssh-keygen
|
Akceptujemy domyślne położenie kluczy (zazwyczaj ~/.ssh/identity oraz ~/.ssh/identity.pub) i podajemy bezpieczne passphrase.
Instalacja klucza publicznego RSA
Następnie musimy skonfigurować zdalne systemy z sshd aby mogły wykorzystać do autoryzacji nasz klucz publiczny. Zazwyczaj wystarczy go skopiować następującym poleceniem:
Listing 1.5: Kopiowanie klucza publicznego |
$ scp ~/.ssh/identity.pub drobbins@remotebox:
|
Ponieważ autoryzacja RSA nie została jeszcze w pełni skonfigurowana, zostaniemy zapytani o hasło. Następnie musimy się zalogować na remotebox i dopisać nasz klucz do pliku ~/.ssh/authorized_keys:
Listing 1.6: Instalacja klucza publicznego |
$ ssh drobbins@remotebox drobbins@remotebox's password: (podaj hasło) Last login: Thu Jun 28 20:28:47 2001 from localbox.gentoo.org Welcome to remotebox! $ cat identity.pub >> ~/.ssh/authorized_keys $ exit |
Przy kolejnych próbach logowania z remotebox, ssh powinno już nie pytać o hasło, a o passphrase.
Listing 1.7: Logowanie za pomocą klucza RSA |
$ ssh drobbins@remotebox
Enter passphrase for key '/home/drobbins/.ssh/identity':
|
Hurra, konfiguracja RSA gotowa! Jeśli ssh wciąż nie pyta o passphrase, mamy kilka możliwości. Po pierwsze, można spróbować się zalogować poleceniem ssh -1 drobbins@remotebox, które każe ssh korzystać jedynie z wersji 1 protokołu ssh i może być potrzebne, jeśli zdalny system domyślnie oczekuje autoryzacji DSA. Gdy to nie pomoże, należy upewnić się, że w pliku /etc/ssh/ssh_config nie ma linii RSAAuthentication no. Jeżeli jest, wystarczy ją odkomentować, wstawiając na początku znak "#". Jeśli i to nie pomoże, należy skontaktować się z administratorem remotebox i upewnić, że odpowiednio skonfigurował RSA w /etc/ssh/sshd_config.
Podczas gdy klucze RSA są używane przez wersję 1 protokołu ssh, zaktualizowana wersja 2 korzysta z kluczy DSA. Każda w miarę aktualna wersja OpenSSH powinna obsługiwać oba rodzaje kluczy. Wygenerowanie kluczy DSA programem ssh-keygen wygląda podobnie do generowania kluczy RSA:
Listing 1.8: Generowanie kluczy DSA |
$ ssh-keygen -t dsa
|
Tutaj również zostaniemy zapytani o passphrase. Warto wybrać bezpieczne. Ponadto zostaniemy zapytani o położenie nowych kluczy. Opcja domyślna, zazwyczaj ~/.ssh/id_dsa oraz ~/.ssh/id_dsa.pub, powinna wystarczyć. Po ukończeniu jednorazowej generacji, klucz publiczny trzeba umieścić na zdalnych systemach.
Instalacja klucza publicznego DSA
Instalacja klucza publicznego DSA wygląda niemal identycznie jak w przypadku RSA. Należy skopiować plik ~/.ssh/id_dsa.pub na remotebox i umieścić go tam w ~/.ssh/authorized_keys2. Tym razem plik ten ma inną nazwę niż dla RSA. Po zainstalowaniu klucza, do zalogowania na remotebox zamiast hasła, trzeba podać passphrase.
Uwaga: Obecnie należy używać wyłącznie wersji 2 protokołu ssh, gdyż jest bezpieczniejsza. |
Teraz autoryzacja RSA lub DSA powinna być skonfigurowana, jednakże wciąż musimy podawać passphrase przy każdym połączeniu. W kolejnym artykule pokażę jak korzystać z ssh-agent, wygodnego systemu umożliwiającego nawiązywanie połączeń bez podawania hasła, jednocześnie wykorzystując zaszyfrowane klucze prywatne. Ponadto zaprezentuję keychain, bardzo użyteczną nakładkę na ssh-agent, która dodatkowo zwiększa bezpieczeństwo oraz wygodę. Tymczasem warto przejrzeć poniższe zasoby.