Użycie drugiego składnika logowania zabezpiecza dostęp ale może powodować pewne trudności lub koszty we wdrożeniu. Chciałbym pokazać jak za pomocą darmowego radiusa, biblioteki google authenticator i aplikacji w telefonie można zrealizować to zadanie.
Cel jest taki aby zabezpieczyć logowanie do urządzenia na login i hasło + drugi zmienny składnik. Login i hasło będą pobierane lokalnie z radiusa i będą danymi wygenerowanym przy zakładaniu konta systemowego. Natomiast drugim zmiennym składnikiem względem czasu będzie biblioteka google-authenticator. Czyli użytkownik logując się np. do routera poda swój login i hasło a po haśle wpisze sześcio cyfrowy kod. Plusem oprócz zwiększonego bezpieczeństwa jest zarządzanie użytkownikami z poziomu radiusa.
Chciałbym zaznaczyć, że aplikacja google authentocator to nie jest żadna usługa online. Aplikacja w telefonie bazuje na kluczu, który nie jest nigdzie wysyłany. Nawet google backup nie zachowuje tych danych w chmurze.
Kolejną rzeczą o której trzeba pamiętać to, że hasło admina czy roota na urządzeniu podłączonego do radiusa magicznie nie znika i zawsze zostaje jako lokalnie zarządzane konto więc musi posiadać przyzwoite hasło. Np. Na wypadek gdyby sam radius uległ awarii.
Instalacja paczek
apt-get install ntp freeradius libpam-google-authenticator
Zmiana grup na których działa demon freeradiusa
/etc/freeradius/3.0/radusd.conf user = root group = root
Włączenie modułu PAM
Włączam moduł pam w freeradius
ln -s /etc/freeradius/3.0/mods-available/pam /etc/freeradius/3.0/mods-enabled/pam
W pliku /etc/freeradius/3.0/users, za wpisem Deny access for a specific user wklejam:
DEFAULT Group == "radius-disabled", Auth-Type := Reject Reply-Message = "Your account has been disabled." DEFAULT Auth-Type := PAM
W pliku /etc/freeradius/3.0/sites-enabled/default, szukam sekcji authenticate o włączam linie pam.
authenticate { pam }
W pliku /etc/pam.d/radiusd wyłączam wszystkie linie i dodaje dwie poniższe
#@include common-auth #@include common-account #@include common-password #@include common-session auth requisite pam_google_authenticator.so forward_pass auth required pam_unix.so use_first_pass
Definiuje kto może zostać klientem
W pliku /etc/freeradius/3.0/clients.conf dodaje wpis w którym definiuje wpis urządzenia.
client private-network-1 { ipaddr = 172.18.10.1 secret = secret }
Dodaje testowego użytkownika
Dodałem użytkowniak test z hasłem q1w2e3r4
adduser test su - test
Google authentocator
Aby wygenerować swoje kody i obrazek do zeskanowania aplikacją w telefonie (google authentocator) trzeba uruchomić komendę google-authenticator na swoim koncie po zalogowaniu poprzez ssh.
google-authenticator
Start freeradius’a
service freeradius restart
Testy
Do wykonywania testów lokalnych mam polecenie radtest, definiuje serwer localhost, port 18120, hasło testing123. Hasło jest już zdefiniowane w pliku clients.conf.
radtest test <unix_password><google_auth> localhost 18120 testing123
root@raspberrypi:~# radtest test q1w2e3r4 localhost 18120 testing123
Dostęp został zabroniony, hasło się nie zgadza. brakuje drugiego składnika.
Sent Access-Request Id 145 from 0.0.0.0:38089 to 127.0.0.1:1812 length 74 User-Name = "test" User-Password = "q1w2e3r4" NAS-IP-Address = 127.0.1.1 NAS-Port = 18120 Message-Authenticator = 0x00 Cleartext-Password = "q1w2e3r4" Received Access-Reject Id 145 from 127.0.0.1:1812 to 0.0.0.0:0 length 20 (0) -: Expected Access-Accept got Access-Reject
root@raspberrypi:~# radtest test q1w2e3r466889585 localhost 18120 testing123
Dostęp został zezwolony, hasło się zgadza.
Sent Access-Request Id 104 from 0.0.0.0:59800 to 127.0.0.1:1812 length 74 User-Name = "test" User-Password = "q1w2e3r466889585" NAS-IP-Address = 127.0.1.1 NAS-Port = 18120 Message-Authenticator = 0x00 Cleartext-Password = "q1w2e3r466889585" Received Access-Accept Id 104 from 127.0.0.1:1812 to 0.0.0.0:0 length 20
Produkcja
Wszystko działa poprawnie można podłączać środowisko produkcyjne. Jeśli ktoś się zastanawia gdzie będzie wpisywać drugi składnik logowania to będzie musiał on być podany tak samo jak w powyższym teście czyli zaraz po haśle. Poniżej konfiguracja radiusa w której podaje serwer radiusa, port i hasło z clients.conf.
Poniżej widać że logowanie nie nie różni się niczym od zwykłego logowania. Po wpisaniu loginu i hasła trzeba odczytać czasowy kod z aplikacji w telefonie i wpisać zaraz po haśle.
Debug
Aby sprawdzić co jest nie tak można zatrzymać radiusa i odpalić go z opcją -X
freeradius -X