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