Cosa fare se la doppia autenticazione è desiderata ma difficile, e non ci sono soldi per token hardware e in generale si consiglia di mantenere un buon umore.
Questa soluzione non è qualcosa di super originale, piuttosto è un mix di diverse soluzioni trovate nel vasto internet.
Quindi, dato
Dominio Active Directory.
Gli utenti del dominio, che lavorano tramite VPN, come molti oggi.
Il gateway VPN è Fortigate.
Il salvataggio della password per il client VPN è vietato dalla politica di sicurezza.
La politica Fortinet in merito ai token propri non può essere definita meno che avara - ci sono addirittura 10 token gratuiti, gli altri a un prezzo molto poco conveniente. Non ho considerato RSASecureID, Duo e simili, poiché voglio un'opzione open source.
Requisiti preliminari: host *nix con installato freeradius, sssd che è stato introdotto nel dominio, gli utenti di dominio possono tranquillamente autenticarsi su di esso.
Pacchetti aggiuntivi: shellinabox, figlet, freeeradius-ldap, carattere rebel.tlf dal repository .
Nel mio esempio - CentOS 7.8.
La logica operativa prevede che, durante la connessione alla VPN, l'utente debba inserire il login di dominio e OTP al posto della password.
Configurazione dei servizi
In /etc/raddb/radiusd.conf cambia solo l'utente e il gruppo con cui parte freeradius, poiché il servizio radiusd deve essere in grado di leggere file in tutte le sottodirectory /home/.
user = root
group = root
Per poter utilizzare i gruppi nelle impostazioni Fortigate, è necessario passare Vendor Specific Attribute. Per questo, nella directory raddb/policy.d creo un file con il seguente contenuto:
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 := "Benvenuto Admin"
}
}
else {
update reply {
&Reply-Message := "Non autorizzato per vpn"
}
reject
}
}
Dopo l'installazione freeradius-ldap nella directory raddb/mods-available viene creato un file ldap.
È necessario creare un collegamento simbolico nella directory raddb/mods-enabled.
ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldapPorto il suo contenuto a questa forma:
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'
}
} Nei file raddb/siti-abilitati/default e raddb/siti-abilitati/inner-tunnel nella sezione authorize aggiungendo il nome della policy che verrà utilizzata — group_authorization. Un punto importante è che il nome della policy è definito non dal nome del file nella directory policy.d, ma dalla direttiva all'interno del file prima delle parentesi graffe.
Nella sezione authenticate in questi stessi file bisogna decommentare la riga pam.
Nel file clients.conf specificando i parametri con cui ci si connetterà Fortigate:
client fortigate {
ipaddr = 192.168.1.200
secret = testing123
require_message_authenticator = no
nas_type = other
}
Configurazione del modulo 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
Le opzioni predefinite per l'integrazione del pacchetto freeradius con google authenticator richiedono che l'utente inserisca le credenziali nel formato: username/password+OTP.
Tenendo conto del numero di maledizioni che si potrebbero abbattere sulla testa in caso di utilizzo della combinazione predefinita freeradius con Google Authenticator, è stata presa la decisione di utilizzare la configurazione del modulo pam in modo da verificare solo il token Google Authenticator.
Durante la connessione dell'utente avviene quanto segue:
- Freeradius verifica la presenza dell'utente nel dominio e in un gruppo specificato e, in caso di successo, viene effettuato il controllo del token OTP.
Tutto sembrava funzionare abbastanza bene fino a quando non mi sono chiesto: «E come si registra l'OTP per oltre 300 utenti?»
L'utente deve effettuare il login sul server con freeradius e dal proprio account e avviare l'applicazione Google authenticator, che genererà per l'utente un codice QR per l'app. Ecco dove entra in gioco shellinabox in combinazione con .bash_profile.
[root@freeradius ~]# yum install -y shellinabox
Il file di configurazione del demone si trova in /etc/sysconfig/shellinabox.
Indico lì la porta 443 e posso specificare il mio certificato.
[root@freeradius ~]#systemctl enable --now shellinaboxdAll'utente non rimane che accedere tramite il link, inserire le credenziali del dominio e ricevere il codice QR per l'app.
L'algoritmo è il seguente:
- L'utente accede alla macchina tramite il browser.
- Si verifica se l'utente è di dominio. In caso contrario, non vengono intraprese azioni.
- Se l'utente è di dominio, si verifica l'appartenenza al gruppo degli amministratori.
- Se non è un admin, si verifica se Google Authenticator è configurato. Se non lo è, viene generato un codice QR e l'utente viene disconnesso.
- Se non è un admin e Google Authenticator è configurato, l'utente viene semplicemente disconnesso.
- Se è un admin, si verifica di nuovo Google Authenticator. Se non è configurato, viene generato un codice QR.
Tutta la logica viene eseguita utilizzando /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
Impostazione di Fortigate:
- Creiamo Radius-server

- Creiamo i gruppi necessari, se necessario, per limitare l'accesso per gruppo. Il nome del gruppo deve Fortigate corrispondere al gruppo che viene passato a Vendor Specific Attribute Fortinet-Group-Name.

- Modifichiamo i portali necessari. SSL-portali.

- Aggiungiamo gruppi nelle politiche.

Vantaggi di questa soluzione:
- C'è la possibilità di autenticazione tramite OTP su Fortigate soluzione open source.
- Si evita l'inserimento della password di dominio da parte dell'utente quando ci si connette tramite VPN, semplificando così il processo di connessione. È più facile inserire una password di 6 cifre rispetto a quella prevista dalla politica di sicurezza. Di conseguenza, diminuisce il numero di ticket con l'oggetto: «Non riesco a connettermi alla VPN».
P.S. Nei piani c'è di perfezionare questa soluzione in un'autenticazione a due fattori completa con challenge-response.
Aggiornamento:
Come promesso, l'ho perfezionata per la variante con challenge-response.
Ecco:
Nel file /etc/raddb/sites-enabled/default sezione authorize si presenta come segue:
authorize {
filter_username
preprocess
auth_log
chap
mschap
suffix
eap {
ok = return
}
files
-sql
#-ldap
expiration
logintime
if (!State) {
if (&User-Password) {
# Se !State e User-Password (PAP), allora forzare LDAP:
update control {
Ldap-UserDN := "%{User-Name}"
Auth-Type := LDAP
}
}
else {
reject
}
}
else {
# Se State, quindi proxy request:
group_authorization
}
pap
}
Sezione authenticate ora ha il seguente aspetto:
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
mschap
digest
# Tentativo di autenticazione con un legame diretto LDAP:
Auth-Type LDAP {
ldap
if (ok) {
update reply {
# Crea un attributo State casuale:
State := "%{randstr:aaaaaaaaaaaaaaaa}"
Reply-Message := "Per favore inserisci OTP"
}
# Restituisci Access-Challenge:
challenge
}
}
pam
eap
}
Ora la verifica dell'utente avviene secondo il seguente algoritmo:
- L'utente inserisce le credenziali di dominio nel client VPN.
- Freeradius verifica la validità dell'account e della password
- Se la password è corretta, viene inviata una richiesta per il token.
- Si verifica il token.
- Profitti).
Fonte: habr.com




