Wielu zwykłym administratorom serwerów wystarcza możliwość logowania do SSH za pomocą loginu i hasła. Niektórzy używają też swojego klucza. My chcemy zaproponować inne ciekawe rozwiązanie – tokeny z aplikacji Google Authenticator.
W poprzednich artykułach opisywaliśmy w jaki sposób możemy udowodnić swoją tożsamość łącząc się do usługi SSH z wykorzystaniem kluczy publicznych oraz prywatnych. W tym artykule przedstawimy kolejny sposób na wzmocnienie procesu uwierzytelniania stosując uwierzytelnianie wielopoziomowe (ang. multi-factor authentication).
We współpracy z firmą ArubaCloud pokazaliśmy Wam, jak postawić swój serwer backupów, jak skonfigurować własny serwer VPN i podłączyć do niego komputer, telefony komórkowe oraz domowy ruter a także jak schować się przed cenzurą sieci i jak zacząć serwer zabezpieczać, jak postawić swój własny zdalny pulpit, swój serwer WWW, jak monitorować zmiany w plikach, jak zablokować reklamy na komórce oraz jak skonfigurować bezpieczną kopię zapasową.
Jeśli nie macie jeszcze swojego własnego serwera, to jest to dobra okazja by się w taki wyposażyć. Aruba oferuje dwa miesiące korzystania ze swojego podstawowego serwera gratis – a po zakończeniu promocji będzie on Was kosztował zaledwie 4 złote miesięcznie. Instrukcję jak krok po kroku skorzystać z promocji i uruchomić swój serwer znajdziecie w tym artykule. Jeśli macie już swój serwer – to zapraszamy do lektury kolejnych akapitów.
Uwierzytelnianie
Uwierzytelnianie jest procesem udowadniania swojej tożsamości. Jednym z powszechnych sposobów uwierzytelniania jest podanie informacji, które znamy (ang. somehing you know) – zazwyczaj jest to nazwa użytkownika i hasło. Proces uwierzytelniania może wymagać od nas dodatkowych czynników, tj:
– czegoś co posiadamy (ang. something you have) – na przykład urządzenie z kodem uwierzytelniającym, token,
– czegoś unikatowego powiązanego z naszą osobą (ang. something you are), na przykład odcisk palca, głos, obraz siatkówki oka.
Dwuskładnikowe uwierzytelnianie
Często stosuje się dwuskładnikowe uwierzytelnianie (two-factor authentication, 2FA) czyli łączące dwie wyżej wymienione metody. Przykładem takiego użycia może być proces logowania przez protokół SSH: po podaniu poprawnego loginu (coś, co wiemy) zostaniemy poproszeni o podanie informacji z tokena (coś, co posiadamy). W niniejszym artykule pokażemy jak skonfigurować serwer w Aruba Cloud aby po nawiązaniu połączenia przez protokół SSH uwierzytelnić się za pomocą loginu, hasła oraz tokenu.
Urządzenie mobilne jako token
Przed rozpoczęciem konfiguracji serwera musimy zaopatrzyć się w aplikację, która będzie pełniła rolę naszego programowego tokenu. W tym celu skorzystamy z aplikacji „Google Authenticator”, dostępnej dla Androida oraz dla iOS. Aplikacja ta może przydać się także do zabezpieczenia konta Google, Twittera czy nawet Wykopu.
Konfiguracja serwera
Cały proces możecie obejrzeć na poniższym filmie, a pod nim znajdziecie wersję tekstową instrukcji.
Zanim przystąpisz do konfiguracji upewnij się, że na Twoim serwerze jest poprawnie ustawiony czas. Tokeny są powiązane z funkcją czasu.
1) Instalujemy repozytorium EPEL – w nim znajduje się wymagany pakiet – google-authenticator
# yum install epel-release
2) Instalujemy pakiet google-authenticator z repozytorium EPEL:
# yum install google-authenticator
3) Rekonfigurujemy PAM i wskazujemy bibliotekę pam_google_authenticator.so dopisując na końcu pliku /etc/pam.d/sshd następującą linię:
auth required pam_google_authenticator.so nullok
Słowo „nullok” na końcu linii oznacza, że metoda autoryzacji za pomocą tokenu jest opcjonalna. Użytkownicy, którzy nie mają wygenerowanych tokenów autoryzacyjnych wciąż będą mogli zalogować się na przykład za pomocą kluczy SSH.
4) Restartujemy usługę SSH
# service sshd restart
Tworzenie tokenu
1) Uruchamiamy polecenie google-authenticator z konta, które będzie wymagało dwuskładnikowego logowania. W naszym przypadku będzie to konto o loginie `krystian`:
$ google-authenticator
Do you want authentication tokens to be time-based (y/n) y https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/krystian@aruba-cloud%3Fsecret%3DFKNIJIGAEUJNR7ETHDWQJK3ZHU%26issuer%3Daruba-cloud Your new secret key is: FKNIJIGAEUJNR7ETHDWQJK3ZHU Your verification code is 148080 Your emergency scratch codes are: 85594429 47984450 29535448 18966056 35833203 Do you want me to update your "/home/krystian/.google_authenticator" file? (y/n) y Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y By default, tokens are good for 30 seconds. In order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. If you experience problems with poor time synchronization, you can increase the window from its default size of +-1min (window size of 3) to about +-4min (window size of 17 acceptable tokens). Do you want to do so? (y/n) y If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting (y/n) y
W konsoli zostanie wygenerowany obraz QR. Jeśli napotkamy problemy ze zeskanowaniem kodu QR możemy odwiedzić adres www, który został wygenerowany w domenie google.com.
Jak korzystać z 2FA?
Łącząc się do serwera Aruba Cloud za pomocą protokołu SSH zostaniemy poproszeni o podanie kodu jednorazowego:
$ ssh krystian@aruba-cloud Password: Verification code: [krystian@aruba-cloud ~]$
Jak zatem widać, nie jest to szczególnie skomplikowane, a może w znaczący sposób podnieść bezpieczeństwo procesu logowania. Co jednak zrobić gdy zgubimy telefon lub nie mamy go akurat przy sobie? Jeśli utracimy urządzenie autoryzacyjne wciąż będziemy mogli zalogować się do konta korzystając z kodów pomocniczych. Kody te (’emergency scratch codes’) zostały wygenerowane podczas tworzenia tokenu i są zapisane w pliku /home/krystian/.google_authenticator (linie 8-12):
$ cat .google_authenticator FKNIJIGAEUJNR7ETHDWQJK3ZHU " RATE_LIMIT 3 30 1495813727 " WINDOW_SIZE 17 " DISALLOW_REUSE 49860448 49860450 " TOTP_AUTH 85594429 47984450 29535448 18966056 35833203
Warto je zapisać w bezpiecznym ale jednocześnie dostępnym miejscu by nie stracić możliwości połączenia z serwerem w krytycznym momencie. Łącząc się do usługi SSH możemy podać jeden ze zdefiniowanych kodów pomocniczych. Każdy kod możemy wykorzystać tylko raz – po zalogowaniu się kod pomocniczy jest usuwany z pliku .google_authenticator.
Oczywiście opisywana metoda dwuskładnikowego uwierzytelnienia jest jednym z wielu dostępnych wariantów – biorąc jednak pod uwagę fakt, że jego wdrożenie generuje jedynie koszt spędzonego nad nim czasu a poziom bezpieczeństwa rośnie, to rekomendujemy je wszystkim administratorom.
Dla pełnej przejrzystości – za przygotowanie oraz opublikowanie powyższego artykułu otrzymujemy wynagrodzenie.
Komentarze
Działa przy tym „Google Prompt” – powiadomienia push z opcją zatwierdź logowanie? Czy trzeba przepisywać kod za każdym razem?
Pomysł super, tylko czy jest jakieś rozwiązanie bez słowa „Google”? Chętnie widziałbym w tym miejscu słowo „open”.
Algorytm generowania kodów jest otwarty, tutaj apki, które wygenerują Ci te same kody:
https://play.google.com/store/search?q=2fa&c=apps&hl=pl
Generowanie kodów po stronie serwera, też może / powinno się odbywać offline.
możesz na przykład wykorzystać swój skrypt do generowania: OATH-TOTP lub OATH-HOTP.
Na stronie https://chojnowski.it wpis: [SCRIPT] Oath (event/time token) on Linux.
Da się: PAM + OAUTH + FreeOTP.
Źródło:
https://jonarcher.info/2015/07/hardening-ssh-with-otp-for-2-factor-authentication/
LastPass authenticator? …i wiele temu podobnych?
A czy w ten sposob da sie zabezpieczyć, by 2fa dotyczył tylko specyficznej grupy w systemie ?
O ile dobrze pamiętam da się do konkretnych użytkowników
Czy nie da się takiego rozwiązania wdrożyć bez informowania Google kiedy i gdzie się logujemy?
yubikey
Rozwiązanie opisane w artykule nie wysyła nic do Google.
Możecie też użyć yubi key.
Zawsze się zastanawiam, czy to bezpieczniejsze niż klucze SSH. Co myślicie?
do przejęcia klucza zazwyczaj wystarczy przejęcie komputera
Wszystko fajnie, tylko… nie dziala. Przynajmniej na debianie. Wszystko zainstalowane jak byc powinno, konfig zmieniony wg informacji tutaj, ale jednak nie dziala.
Nie pyta o token, pyta o haslo. Jak wpisuje prawidlowe haslo, to w logach jest:
sshd(pam_google_authenticator)[7285]: Invalid verification code
Gdzie zatem robie blad? Ktos? Cos? Debian 8.
Musisz dodać metodę autoryzacji do sshd_config o ktorej autor nie wspomina:
#1
ChallengeResponseAuthentication yes
#2
User krystian# w tym przypadku AuthenticationMethods keyboard-interactive
Daj znac czy działa
Pawel: zagadalo jak powinno:
Password:
Verification code:
Możesz wrzucić sshd_confg
Bo ja nie mogę zmienić tej kolejności i męczę się już 2 godziny
Zawsze woła o google auth na początku ale nie wyświetla promptu
W podobny sposób (i w pełni darmowy), można zabezpieczyć dostęp do serwerów Windows z wykorzystaniem aplikacji Ekran System https://www.ekransystem.com/pl/two-factor-authentication-tool
1. „Działa przy tym „Google Prompt”” – nie, zawsze należy przepisać kod
2. „Chętnie widziałbym w tym miejscu słowo „open”.”- źródła są „open” na GitHubie i nic nie idzie na serwery Googla.
3. „(…) da sie zabezpieczyć, by 2fa dotyczył tylko specyficznej grupy w systemie ?” – tak, można zrobić to przez modyfikacje w pam, ale prościej jest skorzystać z instrukcji i nie generować plików .google_authenticator dla tych, którzy nie mają się tak logować
4. „Czy nie da się takiego rozwiązania wdrożyć bez informowania Google kiedy i gdzie się logujemy?” – nic nie wychodzi za serwer. W skrócie soft liczy sumę kontrolną czasu, to samo na telefonie i porównuje się wyniki.
5. „Zawsze się zastanawiam, czy to bezpieczniejsze niż klucze SSH. Co myślicie?” – bezpieczniejsze, ale tylko dlatego, że kradzież/skopiowanie klucza może być dla ofiary niezauważalne, a telefonu już raczej nie.
Osobiście stosuję to tak:
konta admina: login + klucz (z ustawionym hasłem) + google_authenticator.
Uprzywilejowani login + klucz
Konto, na które muszę się czasem awaryjnie zalogować z niezaufanego PC to login + hasło + google_authenticator
Login + klucz ma tę przewagę, że pod dodaniu klucza do ssh_agent nie trzeba nic robić co logowanie.
Proponuje alternatywę – sprzętowe portfele:
– trezor https://doc.satoshilabs.com/trezor-apps/sshagent.html
i chyba wkrótce też ledger
http://www.dongleauth.info/#remote
Ok, tylko to rozwiązanie nie działa w połączeniu z logowaniem po kluczu :p
Szymon mogę Cię zapewnić że działa w połączeniu z kluczem. Sprawdzone na Debianie.
Oczywiscie ze działa w kombinacji mieszanej:
#1
PasswordAuthentication no
#2
Match User krystian# w tym przypadku
#3
AuthenticationMethods publickey,keyboard-interactive
Ale można bez google. Można skorzystać np z FIDO U2F SECURITY KEY.
A jeszcze inni w sposób szyfrowany z przez dowolny hosting wysyłają sobie IP w celu dostępu do serwera.
Potem dostęp jest chroniony haslem, kluczem i okreslonym czasem.
Wpisałem kawałek konfigu sshd i pama i dostałem ze strony z3s alarm cloudflare ze probuje hackować stronę. Dobre hehe
Udało mi sie uruchomić ale tylko wersję bez hasła. Tzn wpisuję login zaraz potem dostaje prompta o topt i loguję się z sukcesem
sshd_config
AuthenticationMethods keyboard-interactive
pam.d sshd
auth required pam_google_authenticator.so nullok
Gdy zmieniam na
AuthenticationMethods password,keyboard-interactive
niestety pyta o hasło i nawet jak wpiszę poprawne to w logach sshd zrzuca „niepoprawne topt” a w ogole nie dostaje prompta o topt. Z kolei klient dostaje „wrong password”
Rozwizanie podane przez Pawła wyżej w komentarzach działa tzn wystarczy samo
AuthenticationMethods keyboard-interactive
taka konfiguracja oznacza ze PAM zapyta zarówno o hasło jak i o OTP w drugim kroku.
Wiersz include common-auth powinien być zahaszowany bo jeśli mamy autentykację PAM interactive to on już zadba o zapytanie o hasło i otp