Que se passe-t-il si l'authentification à deux facteurs est à la fois souhaitable et épineuse, mais qu'il n'y a pas d'argent pour les jetons matériels et qu'en général, ils proposent de rester de bonne humeur.
Cette solution n'est pas quelque chose de super original, mais plutôt un mélange de différentes solutions trouvées sur Internet.
Donc donné
Nom de domaine active Directory.
Les utilisateurs de domaine travaillant via un VPN, comme beaucoup aujourd'hui.
Agit comme une passerelle VPN Fortigate.
L'enregistrement du mot de passe du client VPN est interdit par la politique de sécurité.
Politique Fortinet par rapport à vos propres jetons, vous ne pouvez pas l'appeler moins qu'un zhlob - il y a jusqu'à 10 jetons gratuits, le reste - à un prix très non casher. Je n'ai pas considéré RSASecureID, Duo et autres, car je veux l'open source.
Conditions préalables: hôte *rien avec établi freeradius, ssd - entré dans le domaine, les utilisateurs du domaine peuvent facilement s'y authentifier.
Forfaits supplémentaires : Shellinabox, figue, freeradius-ldap, Police de caractère rebelle.tlf du référentiel
Dans mon exemple - CentOS 7.8.
La logique de travail est censée être la suivante : lors de la connexion à un VPN, l'utilisateur doit saisir un identifiant de domaine et un OTP au lieu d'un mot de passe.
Configuration des services
В /etc/raddb/radiusd.conf seuls l'utilisateur et le groupe au nom desquels démarre freeradius, puisque le service radié devrait pouvoir lire les fichiers dans tous les sous-répertoires /maison/.
user = root
group = root
Pour pouvoir utiliser des groupes dans les paramètres Fortigate, doit être transmis Attribut spécifique au fournisseur. 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 := "Welcome Admin"
}
}
else {
update reply {
&Reply-Message := "Not authorized for vpn"
}
reject
}
}
Après l'installation rayon libre-ldap dans le répertoire raddb/mods-disponible le fichier est créé ldap.
Besoin de créer un lien symbolique vers le répertoire raddb/mods activé.
ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldap
J'apporte son contenu à ce formulaire :
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/par défaut и raddb/sites-enabled/tunnel-intérieur dans la section autoriser J'ajoute le nom de la politique à utiliser - group_authorization. Un point important - le nom de la stratégie n'est pas déterminé par le nom du fichier dans le répertoire politique.d, mais par une directive à l'intérieur du fichier avant les accolades.
Dans la section authentifier dans les mêmes fichiers, vous devez décommenter la ligne pam.
En fichier clients.conf prescrire 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
}
Paramétrage des modules 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
Options de mise en œuvre du groupe par défaut freeradius с google authentificateur demander à l'utilisateur d'entrer des informations d'identification au format : Identifiant Mot de passe+OTP.
En imaginant le nombre de malédictions qui tomberont sur la tête, dans le cas d'utilisation du bundle par défaut freeradius с Authentificateur Google, il a été décidé d'utiliser la configuration du module pam afin que seul le jeton puisse être vérifié Authentificateur Google.
Lorsqu'un utilisateur se connecte, voici ce qui se passe :
- Freeradius vérifie si l'utilisateur est dans le domaine et dans un certain groupe et, en cas de succès, vérifie le jeton OTP.
Tout semblait assez bien jusqu'au moment où j'ai pensé "Comment puis-je enregistrer OTP pour plus de 300 utilisateurs?"
L'utilisateur doit se connecter au serveur avec freeradius et sous votre compte et lancez l'application Authentificateur Google, qui générera un code QR pour l'application pour l'utilisateur. C'est là que l'aide entre en jeu. Shellinabox en combinaison avec .bash_profile.
[root@freeradius ~]# yum install -y shellinabox
Le fichier de configuration du démon se trouve à /etc/sysconfig/shellinabox.
J'y spécifie le port 443 et vous pouvez spécifier votre certificat.
[root@freeradius ~]#systemctl enable --now shellinaboxd
L'utilisateur n'a qu'à suivre le lien, saisir les crédits du domaine et recevoir un code QR pour l'application.
L'algorithme est le suivant:
- L'utilisateur se connecte à la machine via un navigateur.
- Indique si l'utilisateur du domaine est coché. Si ce n'est pas le cas, aucune mesure n'est prise.
- Si l'utilisateur est un utilisateur de domaine, l'appartenance au groupe Administrateurs est vérifiée.
- S'il ne s'agit pas d'un administrateur, il vérifie si Google Authenticator est configuré. Si ce n'est pas le cas, un code QR et une déconnexion de l'utilisateur sont générés.
- Si vous n'êtes pas un administrateur et que Google Authenticator est configuré, déconnectez-vous simplement.
- Si administrateur, vérifiez à nouveau Google Authenticator. S'il n'est pas configuré, un code QR est généré.
Toute la logique est faite en utilisant /etc/skel/.bash_profile.
chat /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éer Rayon-serveur
- Nous créons les groupes nécessaires, si nécessaire, contrôle d'accès par groupes. Nom du groupe sur Fortigate doit correspondre au groupe transmis Attribut spécifique au fournisseur Nom du groupe Fortinet.
- Modification du nécessaire SSL-portails.
- Ajout de groupes aux stratégies.
Les avantages de cette solution :
- Il est possible de s'authentifier par OTP sur Fortigate solution open-source.
- L'utilisateur n'entre pas de mot de passe de domaine lors de la connexion via VPN, ce qui simplifie quelque peu le processus de connexion. Le mot de passe à 6 chiffres est plus facile à saisir que celui fourni par la politique de sécurité. Du coup, le nombre de tickets avec pour objet : « Je n'arrive pas à me connecter au VPN » diminue.
PS Nous prévoyons de mettre à niveau cette solution vers une authentification à deux facteurs à part entière avec défi-réponse.
Mettre à jour:
Comme promis, je l'ai ajusté à l'option défi-réponse.
Donc:
En fichier /etc/raddb/sites-enabled/default section autoriser est comme suit:
authorize {
filter_username
preprocess
auth_log
chap
mschap
suffix
eap {
ok = return
}
files
-sql
#-ldap
expiration
logintime
if (!State) {
if (&User-Password) {
# If !State and User-Password (PAP), then force LDAP:
update control {
Ldap-UserDN := "%{User-Name}"
Auth-Type := LDAP
}
}
else {
reject
}
}
else {
# If State, then proxy request:
group_authorization
}
pap
}
section authentifier ressemble maintenant à ceci :
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
mschap
digest
# Attempt authentication with a direct LDAP bind:
Auth-Type LDAP {
ldap
if (ok) {
update reply {
# Create a random State attribute:
State := "%{randstr:aaaaaaaaaaaaaaaa}"
Reply-Message := "Please enter OTP"
}
# Return Access-Challenge:
challenge
}
}
pam
eap
}
Désormais, la vérification de l'utilisateur s'effectue selon l'algorithme suivant :
- L'utilisateur entre les crédits 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.
- Le jeton est en cours de vérification.
- profit).
Source: habr.com