Freeradius + Google Autenticatore + LDAP + Fortigate

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 https://github.com/xero/figlet-fonts.

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/ldap

Porto 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 shellinaboxd

All'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

    Freeradius + Google Autenticatore + LDAP + Fortigate

  • 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.

    Freeradius + Google Autenticatore + LDAP + Fortigate

  • Modifichiamo i portali necessari. SSL-portali.

    Freeradius + Google Autenticatore + LDAP + Fortigate

  • Aggiungiamo gruppi nelle politiche.

    Freeradius + Google Autenticatore + LDAP + Fortigate

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

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS - ProHoster