Ce să faci dacă vrei să folosești autentificarea în doi pași, dar nu ai bani pentru tokenuri hardware și, în general, ți se recomandă să te menții în stare bună de spirit.
Această soluție nu este ceva super original, ci mai degrabă un mix de diferite soluții găsite pe internet.
Deci, avem:
Domeniu Active Directory.
Utilizatorii domeniului care lucrează prin VPN, ca mulți alții în zilele noastre.
În rolul de gateway VPN acționează: Fortigate.
Salvarea parolei pentru clientul VPN este interzisă de politica de securitate.
Politica Fortinet în ceea ce privește tokenurile proprii nu poate fi considerată nicicum generoasă — sunt doar 10 tokenuri gratuite, celelalte - la un preț foarte neplăcut. RSASecureID, Duo și altele de acest tip nu au fost luate în considerare, deoarece prefer opțiuni open-source.
Cerințele preliminare: host *nix cu instalat freeradius, sssd — introdus în domeniu, utilizatorii de domeniu se pot autentifica fără probleme pe acesta.
Pachetele suplimentare: shellinabox, figlet, freeeradius-ldap, fontul rebel.tlf din repository .
În exemplul meu - CentOS 7.8.
Logica de funcționare este următoarea: la conectarea la VPN, utilizatorul trebuie să introducă numele de utilizator de domeniu și OTP în locul parolei.
Configurarea servicii
În /etc/raddb/radiusd.conf se schimbă doar utilizatorul și grupul sub care rulează freeradius, deoarece serviciul radiusd trebuie să fie capabil să citească fișiere din toate subdirectoarele. /home/.
user = root
group = root
Pentru a putea folosi grupurile în setări Fortigate, trebuie să se transmită Vendor Specific Attribute. Pentru aceasta, în directorul raddb/policy.d creez un fișier cu următorul conținut:
group_authorization {
if (&LDAP-Group[*] == "CN=vpn_admins,OU=vpn-groups,DC=domain,DC=local") {
update reply {
&Fortinet-Group-Name = "vpn_admins" }
update control {
&Auth-Type := PAM
&Reply-Message := "Bine ai venit Admin"
}
}
else {
update reply {
&Reply-Message := "Neautorizat pentru vpn"
}
reject
}
}
După instalarea freeradius-ldap în directorul raddb/mods-available se creează un fișier ldap.
Trebuie să creez un link simbolic în directorul raddb/mods-enabled.
ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldapÎi aduc conținutul într-o formă de acest fel:
ldap {
server = 'domain.local'
identity = 'CN=freerad_user,OU=users,DC=domain,DC=local'
password = "SupeSecretP@ssword"
base_dn = 'dc=domain,dc=local'
sasl {
}
user {
base_dn = "${..base_dn}"
filter = "(sAMAccountname=%{%{Stripped-User-Name}:-%{User-Name}})"
sasl {
}
scope = 'sub'
}
group {
base_dn = "${..base_dn}"
filter = '(objectClass=Group)'
scope = 'sub'
name_attribute = cn
membership_filter = "(|(member=%{control:Ldap-UserDn})(memberUid=%{%{Stripped-User-Name}:-%{User-Name}}))"
membership_attribute = 'memberOf'
}
} În fișiere raddb/sites-enabled/default și raddb/sites-enabled/inner-tunnel în secțiunea authorize adaug numele politicii care va fi folosit - group_authorization. Un aspect important - numele politicii este determinat de numele fișierului din director policy.d, dar de directiva din interiorul fișierului înainte de acolade.
În secțiune authenticate în aceste fișiere trebuie să decomentăm linia pam.
În fișierul clients.conf specificăm parametrii cu care se va conecta Fortigate:
client fortigate {
ipaddr = 192.168.1.200
secret = testing123
require_message_authenticator = no
nas_type = other
}
Configurarea modulului pam.d/radiusd:
#%PAM-1.0
auth sufficient pam_google_authenticator.so
auth include password-auth
account required pam_nologin.so
account include password-auth
password include password-auth
session include password-auth
Opțiunile implicite pentru implementarea legăturii freeradius de google authenticator presupun introducerea de către utilizator a datelor de autentificare în formatul: username/password+OTP.
Având în vedere numărul de neajunsuri care se vor abate asupra mea în cazul utilizării legăturii implicite freeradius de Google Authenticator, s-a decis folosirea configurării modulului pam astfel încât să verific doar tokenul Google Authenticator.
Când un utilizator se conectează, se întâmplă următoarele:
- Freeradius verifică existența utilizatorului în domeniu și într-un grup specificat, iar în caz de succes, se verifică tokenul OTP.
Totul a părut destul de bine până când m-am gândit: „Cum pot înregistra OTP pentru 300+ utilizatori?”
Utilizatorul trebuie să se conecteze pe server cu freeradius și din contul său și să lanseze aplicația Google authenticator, care va genera pentru utilizator un cod QR pentru aplicație. Aici intervine shellinabox în combinație cu .bash_profile.
[root@freeradius ~]# yum install -y shellinabox
Fișierul de configurare al demonului se află în /etc/sysconfig/shellinabox.
Specifice acolo portul 443 și se poate indica un certificat propriu.
[root@freeradius ~]#systemctl enable --now shellinaboxdUtilizatorului nu-i rămâne decât să acceseze linkul, să introducă datele de domeniu și să obțină codul QR pentru aplicație.
Algoritmul este următorul:
- Utilizatorul se conectează la mașină prin browser.
- Se verifică dacă utilizatorul face parte din domeniu. Dacă nu, nu se iau măsuri.
- Dacă utilizatorul este din domeniu, se verifică apartenența la grupul de administratori.
- Dacă nu este administrator, se verifică dacă Google Authenticator este configurat. Dacă nu, se generează un cod QR și se face logout utilizatorului.
- Dacă nu este administrator și Google Authenticator este configurat, se face doar logout.
- Dacă este administrator, se verifică din nou Google Authenticator. Dacă nu este configurat, se generează un cod QR.
Toată logica se execută folosind /etc/skel/.bash_profile.
cat /etc/skel/.bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
# Make several commands available from user shell
if [[ -z $(id $USER | grep "admins") || -z $(cat /etc/passwd | grep $USER) ]]
then
[[ ! -d $HOME/bin ]] && mkdir $HOME/bin
[[ ! -f $HOME/bin/id ]] && ln -s /usr/bin/id $HOME/bin/id
[[ ! -f $HOME/bin/google-auth ]] && ln -s /usr/bin/google-authenticator $HOME/bin/google-auth
[[ ! -f $HOME/bin/grep ]] && ln -s /usr/bin/grep $HOME/bin/grep
[[ ! -f $HOME/bin/figlet ]] && ln -s /usr/bin/figlet $HOME/bin/figlet
[[ ! -f $HOME/bin/rebel.tlf ]] && ln -s /usr/share/figlet/rebel.tlf $HOME/bin/rebel.tlf
[[ ! -f $HOME/bin/sleep ]] && ln -s /usr/bin/sleep $HOME/bin/sleep
# Set PATH env to <home user directory>/bin
PATH=$HOME/bin
export PATH
else
PATH=PATH=$PATH:$HOME/.local/bin:$HOME/bin
export PATH
fi
if [[ -n $(id $USER | grep "domain users") ]]
then
if [[ ! -e $HOME/.google_authenticator ]]
then
if [[ -n $(id $USER | grep "admins") ]]
then
figlet -t -f $HOME/bin/rebel.tlf "Welcome to Company GAuth setup portal"
sleep 1.5
echo "Please, run any of these software on your device, where you would like to setup OTP:
Google Autheticator:
AppStore - https://apps.apple.com/us/app/google-authenticator/id388497605
Play Market - https://play.google.com/stor/apps/details?id=com.google.android.apps.authenticator2&hl=en
FreeOTP:
AppStore - https://apps.apple.com/us/app/freeotp-authenticator/id872559395
Play Market - https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp&hl=en
And prepare to scan QR code.
"
sleep 5
google-auth -f -t -w 3 -r 3 -R 30 -d -e 1
echo "Congratulations, now you can use an OTP token from application as a password connecting to VPN."
else
figlet -t -f $HOME/bin/rebel.tlf "Welcome to Company GAuth setup portal"
sleep 1.5
echo "Please, run any of these software on your device, where you would like to setup OTP:
Google Autheticator:
AppStore - https://apps.apple.com/us/app/google-authenticator/id388497605
Play Market - https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en
FreeOTP:
AppStore - https://apps.apple.com/us/app/freeotp-authenticator/id872559395
Play Market - https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp&hl=en
And prepare to scan QR code.
"
sleep 5
google-auth -f -t -w 3 -r 3 -R 30 -d -e 1
echo "Congratulations, now you can use an OTP token from application as a password to VPN."
logout
fi
else
echo "You have already setup a Google Authenticator"
if [[ -z $(id $USER | grep "admins") ]]
then
logout
fi
fi
else
echo "You don't need to set up a Google Authenticator"
fi
Configurarea Fortigate:
- Creăm Radius-server

- Creăm grupurile necesare, în cazul în care este nevoie să restricționăm accesul pe grupe. Numele grupului în Fortigate trebuie să corespundă grupului care este transmis în Vendor Specific Attribute Fortinet-Group-Name.

- Edităm grupurile necesare SSL-portaluri.

- Adăugăm grupurile în politici.

Avantajele acestei soluții:
- Există posibilitatea autentificării prin OTP pe Fortigate soluția open-source.
- Se exclude introducerea parolei de domeniu de către utilizator la conectarea prin VPN, ceea ce simplifică procesul de conectare. Parola de 6 cifre este mai ușor de introdus decât cea prevăzută de politica de securitate. Drept urmare, se reduce numărul de tichete cu tema: „Nu mă pot conecta la VPN”.
P.S. În planuri este să îmbunătățesc această soluție până la autentificarea cu două factorii completă cu challenge-response.
Actualizare:
Așa cum am promis, am dezvoltat varianta cu challenge-response.
Deci:
În fișierul /etc/raddb/sites-enabled/default secțiune authorize arată în următorul mod:
authorize {
filter_username
preprocess
auth_log
chap
mschap
suffix
eap {
ok = return
}
files
-sql
#-ldap
expiration
logintime
if (!State) {
if (&User-Password) {
# Dacă !State și User-Password (PAP), atunci forțăm LDAP:
update control {
Ldap-UserDN := "%{User-Name}"
Auth-Type := LDAP
}
}
else {
reject
}
}
else {
# Dacă State, atunci proxy request:
group_authorization
}
pap
}
Secțiunea authenticate are acum următoarea formă:
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
mschap
digest
# Încercăm autentificarea printr-o legătură directă LDAP:
Auth-Type LDAP {
ldap
if (ok) {
update reply {
# Creăm un atribut State aleator:
State := "%{randstr:aaaaaaaaaaaaaaaa}"
Reply-Message := "Vă rugăm să introduceți OTP"
}
# Returnăm Access-Challenge:
challenge
}
}
pam
eap
}
Acum verificarea utilizatorului se realizează conform următorului algoritm:
- Utilizatorul introduce acreditivele de domeniu în clientul VPN.
- Freeradius verifică validitatea contului și a parolei
- Dacă parola este corectă, se trimite o solicitare pentru token.
- Se verifică tokenul.
- Profit).
Sursa: habr.com




