Freeradius + Google Authenticator + LDAP + Fortigate

Was tun, wenn man die Zwei-Faktor-Authentifizierung sowohl möchte als auch ablehnt, aber kein Geld für Hardware-Token hat und die allgemeine Empfehlung ist, durchzuhalten und gute Laune zu bewahren.

Diese Lösung ist nichts wirklich Originelles, eher ein Mix aus verschiedenen Lösungen, die im Internet gefunden wurden.

Also, gegeben

Domäne Active Directory.

Domain-Benutzer, die über VPN arbeiten, wie viele heutzutage.

Als VPN-Gateway fungiert Fortigate.

Das Speichern des Passworts für den VPN-Client ist durch die Sicherheitsrichtlinien verboten.

Die Richtlinie Fortinet In Bezug auf eigene Tokens kann man nicht von weniger als geizig sprechen – es gibt 10 kostenlose Tokens, die anderen sind zu einem sehr unverschämten Preis erhältlich. RSASecureID, Duo und ähnliche habe ich nicht in Betracht gezogen, da ich Open Source bevorzugen möchte.

Voraussetzungen: Host *nix mit installiertem freeradius, sssd — ins Domain aufgenommen, Domain-Benutzer können sich problemlos authentifizieren.

Zusätzliche Pakete: shellinabox, figlet, freeeradius-ldap, Schriftart rebel.tlf aus dem Repository https://github.com/xero/figlet-fonts.

In meinem Beispiel – CentOS 7.8.

Die Logik der Funktionsweise wird folgendermaßen angenommen: Bei der Verbindung zum VPN muss der Benutzer den Domain-Login und OTP anstelle des Passworts eingeben.

Konfiguration der Dienste

Im /etc/raddb/radiusd.conf ändert sich nur der Benutzer und die Gruppe, unter der freeradius, da der Dienst radiusd in der Lage sein muss, Dateien in allen Unterverzeichnissen zu lesen /home/.

user = root
group = root

Damit Gruppen in den Einstellungen verwendet werden können Fortigate, muss man Vendor Specific Attributeübergeben. Dazu erstelle ich im Verzeichnis raddb/policy.d eine Datei mit folgendem Inhalt:

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 := "Willkommen Admin"
                }
        }
    else {
        update reply {
        &Reply-Message := "Nicht autorisiert für vpn"
            }
        reject
        }
}

Nach der Installation freeradius-ldap wird im Verzeichnis raddb/mods-available eine Datei erstellt ldap.

Es muss ein symbolischer Link im Verzeichnis raddb/mods-enabled.

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

Ich bringe ihren Inhalt in folgender Form:

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

In den Dateien raddb/sites-enabled/default und raddb/sites-enabled/inner-tunnel im Abschnitt authorize füge den Namen der Richtlinie hinzu, die verwendet wird — group_authorization. Ein wichtiger Punkt — der Name der Richtlinie wird nicht durch den Dateinamen im Verzeichnis policy.d, sondern durch die Direktive innerhalb der Datei vor den geschweiften Klammern definiert.
Im Abschnitt authenticate müssen in diesen Dateien die Zeile pam.

In der Datei clients.conf geben Sie die Parameter an, mit denen verbunden wird Fortigate:

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

Konfiguration des Moduls 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

Standardvarianten der Implementierung der freeradius c Google-Authentifikator sehen die Eingabe von Anmeldedaten durch den Benutzer im Format vor: Benutzername/Passwort+OTP.

Angesichts der Anzahl an Flüchen, die niedergehen könnten, wenn die Standardkombination verwendet wird, freeradius c Google Authenticator, wurde beschlossen, die Konfiguration des Moduls pam so zu gestalten, dass nur das Token überprüft wird. Google Authenticator.

Bei der Anmeldung des Benutzers geschieht Folgendes:

  • Freeradius überprüft, ob der Benutzer in der Domäne und in einer bestimmten Gruppe vorhanden ist, und bei Erfolg wird das OTP-Token überprüft.

Alles schien recht erfolgreich zu sein, bis ich mir dachte: „Wie soll ich das OTP für über 300 Benutzer registrieren?“

Der Benutzer muss sich auf dem Server anmelden mit freeradius und unter seinem Benutzerkonto die Anwendung Google authenticator, die einen QR-Code für die Anwendung für den Benutzer generiert, starten. Hierbei hilft shellinabox in Kombination mit .bash_profile.

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

Die Konfigurationsdatei des Daemons befindet sich in /etc/sysconfig/shellinabox.
Ich gebe dort den Port 443 an und kann mein Zertifikat angeben.

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

Der Benutzer muss nur noch den Link aufrufen, die Domänenanmeldeinformationen eingeben und den QR-Code für die Anwendung erhalten.

Der Algorithmus ist wie folgt:

  • Der Benutzer meldet sich über den Browser am Computer an.
  • Es wird überprüft, ob der Benutzer ein Domänenbenutzer ist. Wenn nicht, werden keine Maßnahmen ergriffen.
  • Wenn der Benutzer domänenspezifisch ist, wird die Zugehörigkeit zur Administratorgruppe überprüft.
  • Wenn es kein Administrator ist, wird überprüft, ob Google Authenticator konfiguriert ist. Wenn nicht, wird ein QR-Code generiert und der Benutzer wird abgemeldet.
  • Wenn es kein Administrator ist und Google Authenticator konfiguriert ist, erfolgt einfach die Abmeldung.
  • Wenn es ein Administrator ist, erfolgt erneut die Überprüfung von Google Authenticator. Wenn es nicht konfiguriert ist, wird ein QR-Code generiert.

Die gesamte Logik wird mit Hilfe von /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

Fortigate-Konfiguration:

  • Erstellen Radius-Server

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Wir erstellen die benötigten Gruppen, falls eine Zugangsbeschränkung nach Gruppen erforderlich ist. Der Gruppenname muss Fortigate der Gruppe entsprechen, die in Vendor Specific Attribute Fortinet-Group-Name.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Wir bearbeiten die notwendigen SSL-Portale.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Wir fügen Gruppen zu Richtlinien hinzu.

    Freeradius + Google Authenticator + LDAP + Fortigate

Vorteile dieser Lösung:

  • Es gibt die Möglichkeit der OTP-Authentifizierung auf Fortigate Open-Source-Lösung.
  • Der Benutzer muss beim Anschluss über VPN kein Domänenpasswort eingeben, was den Verbindungsprozess etwas vereinfacht. Ein 6-stelliger Code ist einfacher einzugeben als der, der durch die Sicherheitsrichtlinien vorgesehen ist. Infolgedessen wird die Anzahl der Tickets verringert, deren Thema lautet: „Kann mich nicht mit VPN verbinden“.

P.S. Es ist geplant, diese Lösung auf eine vollständige Zwei-Faktor-Authentifizierung mit Challenge-Response zu erweitern.

Update:

Wie versprochen, habe ich es auf die Variante mit Challenge-Response ausgeweitet.
Also:
In der Datei /etc/raddb/sites-enabled/default Sektion authorize folgendermaßen aus:

authorize {
    filter_username
    preprocess
    auth_log
    chap
    mschap
    suffix
    eap {
        ok = return
    }
    files
    -sql
    #-ldap
    expiration
    logintime
    if (!State) {
        if (&User-Password) {
            # Wenn !State und User-Password (PAP), dann zwingen Sie LDAP:
            update control {
                Ldap-UserDN := "%{User-Name}"
                Auth-Type := LDAP
            }
        }
        else {
            reject
        }
    }
    else {
        # Wenn State, dann Proxy-Anfrage:
        group_authorization
    }
pap
}

Abschnitt authenticate hat jetzt folgendes Aussehen:

authenticate {
        Auth-Type PAP {
                pap
        }
        Auth-Type CHAP {
                chap
        }
        Auth-Type MS-CHAP {
                mschap
        }
        mschap
        digest
        # Versuch der Authentifizierung mit einem direkten LDAP-Bind:
        Auth-Type LDAP {
        ldap
        if (ok) {
            update reply {
                # Erstellen Sie ein zufälliges Statusattribut:
                State := "%{randstr:aaaaaaaaaaaaaaaa}"
                Reply-Message := "Bitte OTP eingeben"
                }
            # Rückgabe von Access-Challenge:
            challenge
            }
        }
        pam
        eap
}

Jetzt erfolgt die Überprüfung des Benutzers nach folgendem Algorithmus:

  • Der Benutzer gibt die Domänenanmeldeinformationen im VPN-Client ein.
  • Freeradius überprüft die Gültigkeit des Kontos und des Passworts.
  • Wenn das Passwort korrekt ist, wird eine Anfrage für das Token gesendet.
  • Es erfolgt die Überprüfung des Tokens.
  • Profit.)

Quelle: habr.com

60GB SSD 8Gb DDR4