Freeradius + Google Authenticator + LDAP + Fortigate

Cosa fare se desideri utilizzare l'autenticazione a due fattori ma senza spendere per token hardware, e in generale ci si sta chiedendo come affrontare la situazione con ottimismo.

Questa soluzione non è qualcosa di super originale, piuttosto un mix di diverse soluzioni trovate online.

Allora, abbiamo

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.

Politica Fortinet riguardo ai propri token non è affatto generosa — ci sono 10 token gratuiti, gli altri a un prezzo piuttosto alto. Non ho considerato RSASecureID, Duo e simili, poiché voglio qualcosa di open source.

Requisiti preliminari: host *nix con installato freeradius, sssd — è entrato nel dominio, gli utenti di dominio possono autenticarsi senza problemi.

Pacchetti aggiuntivi: shellinabox, figlet, freeradius-ldap, font rebel.tlf dal repository https://github.com/xero/figlet-fonts.

Nel mio esempio — CentOS 7.8.

La logica di funzionamento è che, durante la connessione alla VPN, l'utente deve inserire il login di dominio e OTP invece della password.

Configurazione dei servizi

In /etc/raddb/radiusd.conf cambia solo l'utente e il gruppo da cui parte freeradius, poiché il servizio radiusd deve essere in grado di leggere i 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 := "Welcome Admin"
                }
        }
    else {
        update reply {
        &Reply-Message := "Not authorized for vpn"
            }
        reject
        }
}

Dopo l'installazione freeradius-ldap nella directory raddb/mods-available viene creato un file ldap.

Devo creare un collegamento simbolico nella cartella raddb/mods-enabled.

ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldap

Porto il suo contenuto a questo stato:

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/sites-enabled/default e raddb/sites-enabled/inner-tunnel nella sezione autenticazione aggiungo il nome della politica da utilizzare — group_authorization. È importante notare che il nome della politica è determinato non dal nome del file nella directory policy.d, ma dalla direttiva all'interno del file, prima delle parentesi graffe.
Nella sezione autenticare in questi stessi file è necessario decommentare la riga pam.

Nel file clients.conf specificare 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

Opzioni di implementazione predefinite freeradius con google authenticator presuppongono l'immissione delle credenziali da parte dell'utente nel formato: username/password+OTP.

Considerando la quantità di maledizioni che piomberanno sulla testa nel caso venga utilizzata la combinazione predefinita freeradius con Google Authenticator, è stata presa la decisione di utilizzare la configurazione del modulo pam in modo da controllare solo il token Google Authenticator.

Quando si connette un utente, succede quanto segue:

  • Freeradius verifica se l'utente è presente nel dominio e in un determinato gruppo e, in caso di successo, viene effettuato il controllo del token OTP.

Tutto sembrava andare abbastanza bene fino a quando non mi sono chiesto: «E come posso registrare OTP per 300+ utenti?»

L'utente deve accedere al server con freeradius e dalla sua account deve avviare l'applicazione Google authenticator, che genererà per l'utente un codice QR per l'app. Qui 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 resta che accedere tramite il link, inserire le credenziali di dominio e ottenere il codice QR per l'app.

L'algoritmo è il seguente:

  • L'utente accede alla macchina tramite il browser.
  • Si verifica se l'utente è di tipo dominio. In caso contrario, non vengono intraprese azioni.
  • Se l'utente è di tipo dominio, si verifica l'appartenenza al gruppo degli amministratori.
  • Se non è un admin, si controlla 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, si procede semplicemente alla disconnessione.
  • Se è un admin, si verifica nuovamente 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

Configurazione di Fortigate:

  • Creiamo Raggio-server

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Creiamo i gruppi necessari nel caso sia necessario limitare l'accesso per gruppi. Il nome del gruppo in Fortigate deve corrispondere al gruppo trasmesso in Vendor Specific Attribute Fortinet-Group-Name.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Modifichiamo i portali necessari. SSL-portali.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Aggiungiamo i gruppi alle politiche.

    Freeradius + Google Authenticator + LDAP + Fortigate

Vantaggi di questa soluzione:

  • C'è la possibilità di autenticazione OTP su Fortigate soluzione open source.
  • L'accesso al dominio da parte dell'utente tramite VPN non richiede più l'inserimento della password, semplificando così il processo di connessione. È più facile inserire una password di 6 cifre rispetto a quella richiesta dalla politica di sicurezza. Di conseguenza, il numero di ticket con il tema: 'Non riesco a connettermi a VPN' diminuisce.

P.S. Abbiamo in programma di migliorare questa soluzione fino a un'autenticazione a due fattori completa con un sistema di challenge-response.

Aggiornamento:

Come promesso, ho finalmente implementato la soluzione con challenge-response.
Quindi:
Nel file /etc/raddb/sites-enabled/default sezione autenticazione si presenta nel seguente modo:

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), forzare LDAP:
            update control {
                Ldap-UserDN := "%{User-Name}"
                Auth-Type := LDAP
            }
        }
        else {
            reject
        }
    }
    else {
        # Se State, quindi richiesta proxy:
        group_authorization
    }
pap
}

Sezione autenticare ora ha il seguente aspetto:

autenticare {
        Auth-Type PAP {
                pap
        }
        Auth-Type CHAP {
                chap
        }
        Auth-Type MS-CHAP {
                mschap
        }
        mschap
        digest
        # Tentativo di autenticazione con un binding LDAP diretto:
        Auth-Type LDAP {
        ldap
        if (ok) {
            update reply {
                # Crea un attributo State casuale:
                State := "%{randstr:aaaaaaaaaaaaaaaa}"
                Reply-Message := "Inserisci OTP"
                }
            # Restituisce Access-Challenge:
            challenge
            }
        }
        pam
        eap
}

Adesso la verifica dell'utente avviene secondo il seguente algoritmo:

  • L'utente inserisce le credenziali del 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.
  • Profitto).

Fonte: habr.com

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