Generowanie i używanie kluczy SSH
Ciągłe wpisywanie hasła dostępu do serwera potrafi zmęczyć każdego, bywa upierdliwe gdy potrzebujemy zrobić coś w 2 sekundy, a w przypadku mnogości danych uwierzytelniających można pomylić lub zapomnieć tego właściwego hasła. Z pomocą przychodzą klucze SSH.
Oczywiście żeby korzystać z dobrodziejstw protokołu SSH musimy posiadać odpowiedniego klienta i/lub zainstalowane wymagane pakiety. W systemach Linux czy MacOSX nie ma z tym problemu, bo domyślnie są zainstalowane. Windows nie oferuje tego typu połączeń, ale instalując PuTTY, MSysGit lub Cygwin wzbogacamy system o tę (i nie tylko tę) funkcjonalność.
Na początek może kilka słów czym w ogóle są klucze SSH. Funkcjonalność ta, jak i cały protokół SSH, wymyślona została przez Fina Tatu Ylönen’a, który zirytowany próbą wykradnięcia jego hasła w sieci uniwersyteckiej postanowił stworzyć coś, co nie będzie przesyłało w świat nieszyfrowanych haseł. Jego pomysł zrobił całkiem niemałą furorę, więc z początkowo otwartego kodu stał się komercyjnym oprogramowaniem, a z ostatniej wersji wydanej na licencji open source (1.2.12), podrasowanej przez ludzi z OpenBSD, powstał darmowy odpowiednik – OpenSSH. Tyle z historii, a co do samego protokołu i funkcjonalności kluczy, to polega ona na uwierzytelnianiu użytkownika nie za pomocą hasła, a pary odpowiadających sobie ciągów znaków: klucza prywatnego (fizycznie mieszczącego się na urządzeniu użytkownika) oraz klucza publicznego (który z kolei umieszczony jest w odpowiednim miejscu na serwerze, do którego użytkownik się łączy). Dzięki takiej konfiguracji można błyskawicznie łączyć się z serwerem wydając jedną krótką komendę ssh nazwa_serwera
, nie podając hasła. A co jeśli ktoś wykradnie mój klucz? Nie ma obaw, sam klucz nie zawiera informacji dla jakiego serwera został wygenerowany, a nawet jeśli ktoś doskonale wie do jakiego połączenia (lub wielu połączeń) służy, to istnieje jeszcze jedno zabezpieczenie: passphrase, które to podaje się podczas generowania kluczy. Jest to teoretycznie odpowiednik hasła, z tą różnicą, że system ma możliwość zapamiętania go dzięki czemuś, co zwie się ssh-agent (o tym później). W takiej sytuacji uwierzytelniamy się permanentnie, dzięki czemu każde następne połączenie nie wymaga od nas żadnych dodatkowych działań (nie licząc oczywiście sytuacji postawienia świeżego systemu i nowych kluczy, lub sytuacji gdy cały serwer jest konfigurowany od nowa i w jakiś sposób dane użytkowników zostaną utracone). Podczas generowania kluczy można oczywiście pominąć krok dotyczący passphrase (a w zasadzie zostawić je puste wciskając dwa razy enter w odpowiednim momencie), ale jest to bardzo niewskazane. Po prostu w takiej sytuacji każda osoba, która w jakiś sposób wejdzie w posiadanie naszego klucza prywatnego jest w stanie połączyć się z serwerem korzystając z naszych danych, a nie trzeba chyba podkreślać, że można mieć z tego powodu nieprzyjemności (delikatnie mówiąc). Passphrase różni się od zwykłego hasła także tym, że może być dowolnym ciągiem znaków, zawierającym znaki interpunkcyjne, białe znaki i co tylko chcemy. Jest także nieodzyskiwalne, czyli jeśli zapomnimy naszej frazy, klucz jest do wyrzucenia…
Co więc konkretnie trzeba zrobić żeby utworzyć parę kluczy SSH? Nie jest to czynność skomplikowana i generalnie wydzielić tu możemy 2 sposoby: w konsoli za pomocą odpowiedniej komendy lub z wykorzystaniem narzędzia PuTTYgen (oczywiście drugi sposób dotyczy użytkowników Windowsa).
Linia poleceń (konsola)
Aby wygenerować parę kluczy wydajemy polecenie ssh-keygen, które rozpocznie proces ich tworzenia, zanim jednak to zrobimy, jeszcze drobna uwaga. Wspomniana komenda domyślnie generuje klucze typu RSA dla protokołu SSH w wersji 2, natomiast korzystając z modyfikatora -t
możemy sami zdecydować o typie klucza jakiego potrzebujemy (RSA1 dla SSH1 lub DSA, ECDSA i RSA dla SSH2). Istnieje zresztą cała masa innych modyfikatorów, o których można poczytać wydając komendę man ssh-keygen
. Załóżmy, że chcemy 2048-bitowy klucz RSA dla protokołu SSH2, wydajemy więc polecenie:
Modyfikator -C
tworzy komentarz do klucza, dzięki któremu możemy sobie ułatwić jego późniejszą identyfikację. Oczywiście złym pomysłem byłoby dodanie komentarza w stylu „klucz użytkownika jurek do serwera alpha.praca.lan”, raczej powinna być to informacja zrozumiała dla nas, a niekoniecznie dla wszystkich. Oczywiście komentarz dodawany jest jedynie do klucza publicznego, którego przejęcie jest niegroźne, bo jest on tak naprawdę „zamkiem”, do którego dopasowujemy nasz klucz prywatny, jednak zbytnia wylewność nie jest tu potrzebna.
Po wydaniu powyższej komendy w konsoli powinniśmy ujrzeć:
Enter file in which to save the key (~/.ssh/id_rsa):
W tym momencie możemy wybrać nazwę pliku, w którym zostanie zapisany nasz klucz. W zasadzie to pełną ścieżkę z nazwą pliku, bo jeśli podamy tylko nazwę, to pliki zapiszą się bezpośrednio w katalogu domowym, a nie w podkatalogu .ssh/
. Pliki będą dwa: jeden dla klucza prywatnego (o nazwie takiej, jaką wybierzemy, lub tej, która jest domyślna i wyświetla się w nawiasie przy prośbie o podanie nazwy) oraz klucz publiczny (o takiej samej nazwie, ale z rozszerzeniem .pub). <homedir> jest ścieżką do katalogu domowego użytkownika i jest różny dla każdego systemu – w Windowsie będzie to C:\Users\nasz_login\
(w środowisku Cygwin zamienione na /cygdrive/c/Users/nasz_login/
), podczas gdy dla Linuxa będzie to po prostu /home/nasz_login/
. Jeśli chcemy korzystać z różnych kluczy dla różnych połączeń (o tym wkrótce) to możemy wpisać jakąś rozpoznawalną nazwę, jednak jeśli zamierzamy korzystać zawsze z tego samego klucza, to można zostawić domyślną nazwę, gdyż nie ma ona większego znaczenia. Na potrzeby tego przykładu zostawiamy ścieżkę i nazwę domyślną, czyli przy pytaniu o nazwę pliku po prostu wciskamy enter. Powinniśmy zobaczyć:
Enter passphrase (empty for no passphrase):
I tu wraca temat passphrase. Owszem, można po prodtu wcisnąć enter i wygenerować klucz bez frazy zabezpieczającej, ale jest to kiepski pomysł. Lepiej wpisać chociażby jeden wyraz minimalnie utrudniający życie komuś, kto wszedł by w posiadanie naszego klucza prywatnego, a najlepiej jakąś konkretną, udziwnioną frazę w stylu „szybka ŁASICA zrobiła 1 KrOk w Tył” lub inny surrealistyczny tekst, który raczej nikomu do głowy nie przyjdzie. Warto zastosować losowość wielkich i małych liter, znaków interpunkcyjnych czy też cyfr – znacznie zwiększa to bezpieczeństwo naszych danych uwierzytelniających. Kiedy już wybierzemy frazę zostaniemy oczywiście poproszeni o ponowne jej wpisanie:
I jeśli się nie pomylimy, to po zatwierdzeniu klawiszem enter powinniśmy ujrzeć komunikat typu:
Your public key has been saved in ~/.ssh/id_rsa.pub.
The key fingerprint is:
7e:46:a0:bc:e7:eb:f0:4e:71:4e:18:69:43:ea:43:f6
The key's randomart image is:
+--[ RSA 2048]----+
| . |
| o . |
| + * |
| = + = |
| = E + |
| + * |
| o + + |
| * o |
| o*. |
+-----------------+
W tym momencie mamy już wygenerowany klucz. Tylko co dalej? Zależy co chcemy zrobić – jeśli na przykład potrzebujemy klucza publicznego do GitHub’a, to po prostu otwieramy w pierwszym lepszym edytorze wygenerowany plik id_rsa.pub (lub inny, jeśli wybraliśmy inną nazwę) i kopiujemy go sobie, by następnie wkleić w profilu na github.com. Jeśli mamy ochotę, to ręcznie możemy dodawać nasz klucz publiczny do pliku .ssh/authorized_keys w naszym katalogu domowym na serwerze, co w zupełności wystarczy by móc korzystać z dobrodziejstw połączeń bezhasłowych.
Klucze można też wykorzystywać by logować się jako inny użytkownik, w takim przypadku parą uwierzytelniającą będzie klucz prywatny leżący u nas oraz klucz publiczny dodany do .ssh/authorized_keys w katalogu wybranego użytkownika. Jedyne co musimy zrobić to podać odpowiedni login podczas połączenia, czyli wydać komendę ssh inny_uzytkownik@serwer
. Może jednak zaistnieć sytuacja taka, że nie będziemy mieć uprawnień do inny_uzytkownik/.ssh/authorized_keys
i wtedy musimy poprosić administratora serwera lub inną osobę, która ma dostęp do tego pliku, by dodała nasz klucz. Istnieje wiele możliwości bardziej złożonego wykorzystania kluczy ssh, ale to nie jest odpowiednie miejsce by temat rozwijać – zainteresowanych odsyłam do wpisu o konfiguracji połączeń ssh.
Wracając do naszych wygenerowanych kluczy. Zapewne część z Was nie ma ochoty grzebać w plikach i ręcznie dodawać kluczy do każdego z serwerów. Na szczęście nie jest to żaden wymóg, można to zrobić z poziomu konsoli.
Aby dodać klucz do serwera, nazwijmy go alpha, wystarczy wydać polecenie:
przy czym jeśli nie podawaliśmy innej nazwy klucza niż domyślna, to można zupełnie pominąć modyfikator -i
. Również podawanie loginu jest opcjonalne, więc jeśli nasz login na serwerze jest identyczny z loginem na komputerze, z ktorego korzystamy, to cała komenda skraca się znacznie do ssh-copy-id alpha
.
Komenda ta dodaje na serwerze alpha nasz klucz publiczny do pliku .ssh/authorized_keys
w katalogu użytkownika, którego login podaliśmy (jeśli nie podawaliśmy loginu to używany jest nasz login systemowy), a co ważne: jeśli takowy katalog i plik nie istnieją (czyli jest to nasze pierwsze połączenie ssh) zostaną one utworzone. Zakładając, że łączymy się z serwerem alpha po raz pierwszy, po wykonaniu powyższej komendy ujrzymy w konsoli coś w rodzaju:
RSA key fingerprint is 1b:3c:d5:37:56:60:33:a5:e1:c0:51:05:e7:bd:c1:e1.
Are you sure you want to continue connecting (yes/no)?
Oczywiście wpisujemy yes po czym w konsoli ujrzymy informację o dodaniu serwera do listy znanych hostów:
Jeśli jest to nasze kolejne połączenie to bezpośrednio po wydaniu komendy ssh-copy-id
powinniśmy ujrzeć prośbę o podanie hasła (chyba, że wcześniej ustanowiliśmy połączenie i sesja wciąż jest aktywna, to ten krok zostanie pominięty). Prośbę o hasło ujrzymy też bezpośrednio po powyższym komunikacie w przypadku pierwszego połączenia.
Wpisujemy więc hasło (już po raz ostatni ;)) i widzimy:
~/.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
Dzięki temu nasz klucz publiczny ląduje na serwerze i tworzy parę z naszym lokalnym kluczem prywatnym – jesteśmy gotowi, by nawiązać połączenie! Ale, ale… po wykonaniu komendy ssh alpha
powraca do nas passphrase, a przecież po to robimy klucze, by łączyć się nie musząc wpisywać niczego poza wspomnianą komendą. Z pomocą przychodzi tu wymieniony na początku notki ssh-agent, gdyż wystarczy wykonać polecenie ssh-agent sh -c 'ssh-add < /dev/null && bash'
, a ujrzymy prośbę o podanie frazy zabezpieczającej:
Po wpisaniu poprawnej frazy ujrzymy komunikat w stylu
Dzięki temu zabiegowi nasza fraza trzymana jest w systemie w bezpieczny sposób, a my nie będziemy jej musieli wpisywać za każdym razem przy połączeniu z serwerem. Brawo, gotowe!
Kategoria:Użyteczne
Przekaż dalej:
Polecam ci dokument "securing ssh by passwordless logons" oraz changelog od putygen (bo generowane klucze nim zwykle sa odwracalne). Generalnie klucze powinny miec passprase na sobie a by nie podawac tego ciagle popatrz na ssh-agent i keychain na lin lub peagent na win (PS nie czytalemn calego wpisu wiec ja wspomniales o tym to sorki)
Poza keychain to o reszcie owszem, wspomniałem 🙂
wiem – doczytalem pozniej :).
keychain laczy sie do ddzialajacego ssh-agent w tle (wiec dla kazdej powloki nie starujesz ssh-agent) plus daje inne sunkcje jak np zabicie wszystkich agentow (security) itp.