Freeradius + Google Authenticator + LDAP + Fortigate

Que faire si l'authentification à deux facteurs est souhaitée, mais que l'on n'a pas d'argent pour des tokens matériels et qu'on nous conseille simplement de rester de bonne humeur ?

Cette solution n'est pas quelque chose de super original, plutÎt un mélange de différentes solutions trouvées sur Internet.

Donc, voici les données

Domaine Active Directory.

Les utilisateurs de domaine qui travaillent via VPN, comme beaucoup aujourd'hui.

Agissant comme passerelle VPN Fortigate.

La sauvegarde du mot de passe pour le client VPN est interdite par la politique de sécurité.

La politique Fortinet concernant les tokens propres n'est pas moins que mesquine — il y a jusqu'Ă  10 tokens gratuits, les autres Ă  un prix trĂšs peu avantageux. Je n'ai pas considĂ©rĂ© RSASecureID, Duo et similaires, car je prĂ©fĂšre l'open source.

Exigences prĂ©liminaires : hĂŽte *nix avec installĂ© freeradius, sssd — ajoutĂ© au domaine, les utilisateurs de domaine peuvent s'authentifier sans problĂšme.

Paquets supplémentaires : shellinabox, figlet, freeeradius-ldap, police rebel.tlf du dépÎt https://github.com/xero/figlet-fonts.

Dans mon exemple — CentOS 7.8.

La logique de fonctionnement est la suivante : lors de la connexion au VPN, l'utilisateur doit entrer son identifiant de domaine et OTP au lieu d'un mot de passe.

Configuration des services

Dans /etc/raddb/radiusd.conf seul l'utilisateur et le groupe à partir desquels commence freeradius, puisque le service radiusd doit pouvoir lire les fichiers dans tous les sous-répertoires /home/.

user = root
group = root

Pour pouvoir utiliser les groupes dans les paramÚtres Fortigate, il est nécessaire de passer Vendor Specific Attribute. Pour cela, dans le répertoire raddb/policy.d je crée un fichier avec le contenu suivant :

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 := "Bienvenue Admin"
                }
        }
    else {
        update reply {
        &Reply-Message := "Non autorisé pour le vpn"
            }
        reject
        }
}

AprÚs l'installation freeradius-ldap dans le répertoire raddb/mods-available un fichier est créé ldap.

Il faut créer un lien symbolique dans le répertoire raddb/mods-enabled.

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

J'adapte son contenu comme suit :

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

Dans les fichiers raddb/sites-enabled/default et raddb/sites-enabled/inner-tunnel dans la section authorize j'ajoute le nom de la politique qui sera utilisĂ©e — group_authorization. Un point important — le nom de la politique n'est pas dĂ©fini par le nom du fichier dans le rĂ©pertoire policy.d, mais par la directive Ă  l'intĂ©rieur du fichier avant les accolades.
Dans la section authenticate dans ces mĂȘmes fichiers, il faut dĂ©commenter la ligne pam.

Dans le fichier clients.conf nous décrivons les paramÚtres avec lesquels il se connectera Fortigate:

client fortigate {
    ipaddr = 192.168.1.200
    secret = testing123
    require_message_authenticator = no
    nas_type = other
}

Configuration du module 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

Les options par défaut d'implémentation du lien freeradius avec google authenticator supposent que l'utilisateur entre ses informations d'identification au format : nom d'utilisateur/mot de passe+OTP.

En considĂ©rant le nombre de malĂ©dictions qui tomberaient sur ma tĂȘte en utilisant le lien par dĂ©faut freeradius avec Google Authenticator, il a Ă©tĂ© dĂ©cidĂ© d'utiliser la configuration du module pam de sorte Ă  vĂ©rifier uniquement le token Google Authenticator.

Lors de la connexion de l'utilisateur, il se passe ce qui suit :

  • Freeradius vĂ©rifie la prĂ©sence de l'utilisateur dans le domaine et dans un groupe spĂ©cifique et, en cas de succĂšs, procĂšde Ă  la vĂ©rification du token OTP.

Tout semblait relativement bien jusqu'au moment oĂč je me suis demandĂ© « Comment enregistrer l'OTP pour plus de 300 utilisateurs ? »

L'utilisateur doit se connecter sur le serveur avec freeradius et sous son compte et lancer l'application Google authenticator, qui génÚre pour l'utilisateur un code QR pour l'application. C'est ici qu'intervient shellinabox en combinaison avec .bash_profile.

[root@freeradius ~]# yum install -y shellinabox

Le fichier de configuration du démon se trouve dans /etc/sysconfig/shellinabox.
J'indique le port 443 là-bas et je peux spécifier mon certificat.

[root@freeradius ~]#systemctl enable --now shellinaboxd

L'utilisateur n'a plus qu'Ă  se rendre Ă  l'adresse, entrer les identifiants de domaine et obtenir le code QR pour l'application.

L'algorithme est le suivant :

  • L'utilisateur se connecte Ă  la machine via le navigateur.
  • VĂ©rifie si l'utilisateur est de domaine. Si non, aucune action n'est entreprise.
  • Si l'utilisateur est de domaine, il vĂ©rifie l'appartenance au groupe des administrateurs.
  • S'il n'est pas admin, il vĂ©rifie si Google Authenticator est configurĂ©. Si ce n'est pas le cas, un code QR est gĂ©nĂ©rĂ© et l'utilisateur est dĂ©connectĂ©.
  • S'il n'est pas admin et que Google Authenticator est configurĂ©, il est simplement dĂ©connectĂ©.
  • S'il est admin, alors on vĂ©rifie encore Google Authenticator. S'il n'est pas configurĂ©, un code QR est gĂ©nĂ©rĂ©.

Toute la logique s'exécute en utilisant /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

Configuration de Fortigate :

  • CrĂ©ons Radius-serveur

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Nous crĂ©ons les groupes nĂ©cessaires, en cas de besoin de limiter l'accĂšs par groupes. Le nom du groupe pour Fortigate doit correspondre au groupe qui est transmis Ă  Vendor Specific Attribute Fortinet-Group-Name.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Nous modifions les nĂ©cessaires SSL-portails.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Nous ajoutons des groupes aux politiques.

    Freeradius + Google Authenticator + LDAP + Fortigate

Avantages de cette solution :

  • Il est possible de s'authentifier par OTP sur Fortigate une solution open-source.
  • L'utilisateur n'a pas besoin de saisir le mot de passe de domaine lors de la connexion via VPN, ce qui simplifie un peu le processus de connexion. Il est plus facile de saisir un mot de passe Ă  six chiffres que celui prĂ©vu par la politique de sĂ©curitĂ©. En consĂ©quence, le nombre de tickets avec le sujet : « Je ne peux pas me connecter au VPN » diminue.

P.S. Nous prévoyons d'affiner cette solution pour l'authentification à deux facteurs complÚte avec challenge-response.

Mise Ă  jour :

Comme promis, je l'ai effectivement affiné avec une option challenge-response.
Donc :
Dans le fichier /etc/raddb/sites-enabled/default section authorize se présente comme suit :

authorize {
    filter_username
    preprocess
    auth_log
    chap
    mschap
    suffix
    eap {
        ok = return
    }
    files
    -sql
    #-ldap
    expiration
    logintime
    if (!State) {
        if (&User-Password) {
            # Si !State et User-Password (PAP), alors forcer LDAP :
            update control {
                Ldap-UserDN := "%{User-Name}"
                Auth-Type := LDAP
            }
        }
        else {
            reject
        }
    }
    else {
        # Si State, alors proxy request :
        group_authorization
    }
pap
}

Section authenticate a maintenant l'apparence suivante :

authenticate {
        Auth-Type PAP {
                pap
        }
        Auth-Type CHAP {
                chap
        }
        Auth-Type MS-CHAP {
                mschap
        }
        mschap
        digest
        # Essayer l'authentification avec une liaison LDAP directe :
        Auth-Type LDAP {
        ldap
        if (ok) {
            update reply {
                # Créer un attribut State aléatoire :
                State := "%{randstr:aaaaaaaaaaaaaaaa}"
                Reply-Message := "Veuillez entrer l'OTP"
                }
            # Retourner Access-Challenge :
            challenge
            }
        }
        pam
        eap
}

La vérification de l'utilisateur se fait maintenant selon l'algorithme suivant :

  • L'utilisateur entre les identifiants de domaine dans le client VPN.
  • Freeradius vĂ©rifie la validitĂ© du compte et du mot de passe
  • Si le mot de passe est correct, une demande de jeton est envoyĂ©e.
  • La vĂ©rification du jeton a lieu.
  • Profit).

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster