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 .
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/ldapIch 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 shellinaboxdDer 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

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

- Wir bearbeiten die notwendigen SSL-Portale.

- Wir fügen Gruppen zu Richtlinien hinzu.

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




