Mise en place d'un double facteur pour de l'authentification à des services VPN ou page d'administration comme Fortigate. Permettant de renforcer l'identification des administrateurs lors de la connexion et contré les usurpations des comptes.
Un radius est un composant systeme permettant d'unifier les différentes méthodes d'authentifications existant au sein d'un SI en une seule méthode d'authentification. Cela permet, par exemple d'authentifier des utilisateurs présent dans un annuaire ldap depuis un switch par exemple. Qui dans la plus part des cas ne supporte pas ce type d'authentification plus complexe. Cela permet authentification et permettre d'avoir un annuaire centraliser avec des groupes dynamiques pour autoriser ou non la connexion à l'équipement en fonction des droits des utilisateurs.
L'avantage est de se pré-occuper uniquement que l'équipement cible support une authentification radius et le systeme radius va permettre de conventir cette authentification standardiser, vers d'autres protocoles tel que LDAP, Authentification local radius, Base de données mysql, d'autres serveurs Radius.
La double authentification est un mécanisme qui permet d'augementer la sécurité des comptes utilisateurs/administrateurs en augementant drastiquement l'identification de l'utilisateurs. Elle permet d'augmenter le taux de probabilité d'une bonne identification de l'utilisateurs et qu'il ne s'agit pas d'une personne essayant d'usurper un compte d'une autre personne. La double authentification, est une méthode suplémentaire de protection, en cas de comprimission d'un compte utilisateur pour réduire les risques d'intrusion pour ralentir l'attaquant.
Un compte utilisateur sans ce mécanisme en cas de compromition de ses identifiants(via phising ou brute force par exemple ou encore social engineering), pourrais être utilisé par n'importe qui et le SI serait alors exposé à une personne qui ne devrait pas y avoir accés.
Si cette méthode est mise en place, en cas de compromition des identifiants de l'utilisateurs il reste cette sécurité suplémentaire permettant de demande à l'utilisateur une information que seule elle poséde.
Cette méthode de double facteur dans notre cas, est une méthode de double facteur de possésion que seul l'utilisateur en question poséde. En général, il s'agit soit d'un code de 4-8 chiffres ou alors d'une application avec une méthode d'autorisation de connexion via une notification en mode push sur le smartphone de l'utilisateur au moment de la connexion.
Cette méthode n'est donc pas un systeme de remplacement au mot de passe, mais plus comme une méthode suplémentaire. Dans notre exemple, c'est un code qui sera utilisé avec une seed qui est généré pour chaques utilisateurs. Cette seed est une suite de caractére plus ou moins long sur la quelle, une opération mathématique est effectué via un algorithme qui va effectuer une opération avec une clé basé sur l'heure.
Un calcul de seed par rapport à une clé basé sur l'heure permet de s'affranchir d'un systeme connecté à internet ou tous autres systeme de communication. Cela permet d'avoir un systeme de génération de mot de passe totalement hors réseau comme par exmeple sur un boitier double facteur sous force de badge ou la taille du clé USB.
Dans mon cas, le systeme va utiliser FreeRadius qui est un service Radius opensource présent sur toutes les distributions Linux.
Pour la partie génération des tokens côté serveurs, ce sera la librairies de google authenticator.
Côté téléphone, pour l'application ce sera également google authenticator. Cela fonctionne aussi avec Authenticator de Microsoft.
Il est necessaire d'avoir un équipement supportant les authentifications radius et un serveur pour heberger le service FreeRadius.
Il existe deux méthode pour implémenter la double authentification dans freeRadius.
La méthode avec Challange, est une méthode d'authentification en deux temps.
Une 1er authentification est faites via un couple login et mot de passe. Par une tentative du serveur radius vers un annuaire LDAP sans alterations des informations saisie dans le champ de connexion et celui envoyer à l'annuaire LDAP.
Selon la réponse de l'annuaire, si il est positive une requete demandé par le radius est envoyé à l'utilisateur lui demande de saisir sont token.
Si le token est correct, l'utilisateurs sera autoriser à se connecter au service souhaité.
Exemple d'une saisie: (Mot de passe de toto est "MoTdEpAsSe" et sont token est 123456)
Cette méthode comporte tous de meme une limitation, il n'est pas possible via certains services type openvpn d'effectuer une authentification de type Challange. Il est necessaire dans ce cas de se rabattre sur une solution "sans challange".
Créer un schéma de communication
La méthode sans Challange, est une méthode d'authentification en un seul temps.
Contrairement au challange, une seule requete est envoyé vers le radius. Le token sera saisie par l'utilisateur dans le champ mot de passe à la fin du mot de passe de l'utilisateur.
Exemple d'une saisie: (Mot de passe de toto est "MoTdEpAsSe" et sont token est 123456)
Cette méthode obligera le serveur radius à altérer les informations saisie par l'utilisateur, en décompossant le mot de passe de l'utilisateur et sont token. Qui par la suite va envoyer les informations au radius et les identifiants sont correcte, alors le token est verifié et utilisateur sera autoriser à se connecter ou non directement via la meme requete.
Créer un schéma de communication
Il existe des contraintes de sécurité entre l'authentification AD et la façon dont est envoyer les crédentials entre le client et le serveur :
Ces deux méthodes comportes leurs lot d'avantages et incovénints.
Sans Challange | Avec Challange | |
---|---|---|
Support par tous les clients Radius | ||
Compéhension simple par les utilisateurs | ||
Risque d'erreurs des utilisateurs lors de la connexion | ||
Identification en cas d'erreur de saisie du mot de passe | ||
Saisie d'un 2eme mot de passe | ||
Nombre d'echanges vers le serveur radius | 1 | 2 |
Configuration de l'adresse IP du serveur Radius, qui doit être fixe pour facilité les communications vers ce serveur.
nano /etc/network/interfaces
allow-hotplug ens192
iface ens192 inet static
address X.X.X.X/XX
gateway X.X.X.X
dns-nameservers X.X.X.X X.X.X.X
dns-search X.X.X.X
Modification du fichier resolv pour inclus le nom complet du serveur necessaire pour l'intégration dans le domain et au bon fonctionnement du service Radius.
nano /etc/hosts
X.X.X.X Radius-01.freshome.lan Radius-01
Installation des services freeradius et des autres services necessaire pour communiquer vers le serveur Active directory pour l'authentification des utilisateurs.
apt install freeradius freeradius-ldap samba krb5-config krb5-user winbind libpam-winbind libnss-winbind libpam-google-authenticator
Modification du fichier suivant, pour rajouter winbind pour mettre une authentification possible des utilisateurs sur le systeme linux pour l'ouverture de sessions ou encore les informations lié à leurs permissions ou leurs appartenaces à leurs groupes.
nano /etc/nsswitch.conf
passwd: compat winbind
group: compat winbind
shadow: compat
Configuration du service Samba, pour joindre le serveur radius au domaine pour authentifier les utilisateurs via le mecanisme d'authentification active directory.
nano /etc/samba/smb.conf
[global]
security = ads
realm = FRESHOME.LAN
workgroup = FRESHOME
idmap uid = 10000-20000
idmap gid = 10000-20000
winbind enum users = yes
winbind enum groups = yes
template homedir = /home/%D/%U
template shell = /bin/bash
client use spnego = yes
client ntlmv2 auth = yes
encrypt passwords = yes
winbind use default domain = yes
restrict anonymous = 2
kerberos method = secrets and keytab
winbind refresh tickets = true
Redémarrage du service Samba pour appliquer les modifications.
systemctl restart smbd.service
Configuration du service kerberos pour jonction au domaine.
nano /etc/krb5.conf
[libdefaults]
default_realm = FRESHOME.LAN
dns_lookup_realm = true
dns_lookup_kdc = true
[realms]
[...]
FRESHOME.LAN = {
kdc = freshome.lan
admin_server = freshome.lan
}
[domain_realm]
[...]
.freshome.lan = FRESHOME.LAN
freshome.lan = FRESHOME.LAN
Création du ticket Kerberos de l'utilisateur administrateur.
kinit administrateur
###ADDING <img kinit>
Verification que le ticket kerberos est bien généré et présent sur la machine.
klist
###ADDING <img klist>
Création du fichier keytab pour joindre le domaine.
net ads keytab create -U administrateur
Jonction du serveur Radius au domain.
net ads join -U administrateur
###ADDING <img join ad>
Redémarrage du service winbind pour prise en compte de la jonction au domaine.
systemctl restart winbind.service
Création de l'espace environnement des utilisateurs du domaine, pour le stocakage de leurs tokens
mkdir /home/FRESHOME
chmod 755 /home/FRESHOME
Configuration de la librairie google authenticator pour être utilisé par freeradius.
nano /etc/pam.d/radiusd
#@include common-auth
#@include common-account
#@include common-password
#@include common-session
auth requisite pam_google_authenticator.so forward_pass
account required pam_permit.so
Déplacement dans le dossier des modules de Freeradius.
cd /etc/freeradius/3.0/mods-enabled/
Création des liens symboliques de LDAP et PAM pour activer les modules.
ln -s ../mods-available/ldap ldap
ln -s ../mods-available/pam pam
###ADDING Attributes configurations
Mise en place conditions de connexion des utilisateurs avec un attribue
nano /etc/freeradius/3.0/policy.d/fortigate
group_authorization {
if (&LDAP-Group[*] == "GRP_VPN_Administrateurs") {
update reply {
&Fortinet-Group-Name = "vpn_admins"
}
update control {
&Auth-Type := PAM
&Reply-Message := "Connected"
}
} elsif (&LDAP-Group[*] == "GRP_VPN_Users"){
update reply {
&Fortinet-Group-Name = "vpn_users"
}
update control {
&Auth-Type := PAM
&Reply-Message := "Connected"
}
} else {
update reply {
&Reply-Message := "Not authorized"
}
reject
}
}
Déclaration de la procédure de connexion. Utilisation du LDAP en premier lieu. Et en second temps effectuer une demande d'OTP à l'utilsateur via l'envoie d'une requete challange à l'utilisateur. Et pour finir envoie vers PAM pour la verification token.
nano /etc/freeradius/3.0/sites-enabled/default
[...]
authorize {
[...]
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
}
[...]
authenticate {
[...]
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
}
}
#
# Pluggable Authentication Modules.
pam
Déclaration des différents clients, pouvents se connecter au Radius pour authentifier des utilisateurs.
nano /etc/freeradius/3.0/clients.conf
client FW-VPN {
ipaddr = X.X.X.X
secret = .............
}
Forcer l'authentification NTLM, pour un client spécifique.
nano /etc/freeradius/3.0/users
DEFAULT Auth-Type = ntlm_auth, NAS-Identifier == "FW-VPN"
Modification de la connexion pour supprimer le préfix non necessaire
nano /etc/freeradius/3.0/proxy.conf
realm FRESHOME.LAN {
strip
}
realm DEFAULT {
strip
}
Configuration de la liaison LDAP, pour verification de l'appartenance de l'utilisateur à un groupe spécifique.
nano /etc/freeradius/3.0/mods-enabled/ldap
ldap {
server = 'ldap.freshome.lan'
identity = 'CN=Freeradius Service,OU=Comptes_services,DC=freshome,DC=lan'
password = ...........
base_dn = 'dc=freshome,dc=lan'
sasl {
}
update {
control:Password-With-Header += 'userPassword'
control: += 'radiusControlAttribute'
request: += 'radiusRequestAttribute'
reply: += 'radiusReplyAttribute'
}
user_dn = "LDAP-UserDn"
user {
base_dn = "${..base_dn}"
filter = "(sAMAccountname=%{%{Stripped-User-Name}:-%{User-Name}})"
sasl {
}
}
group {
base_dn = "${..base_dn}"
filter = '(objectClass=posixGroup)'
membership_filter = "(|(member=%{control:Ldap-UserDn})(memberUid=%{%{Stripped-User-Name}:-%{User-Name}}))"
membership_attribute = 'memberOf'
}
}
Ajout des droits d'execution sur le script.
chmod +x /etc/skel/.bash_profile
Ajout des droits pour permettre aux utilisateurs de lire et d'executer le code.
chown 777 /etc/skel/.bash_profile
Script de génération automatique d'un QR-Code. L'utilisateur dois se connecter directement via un terminal SSH pour initaliser sont token. Une confirmation de code lui sera demandé.
nano /etc/skel/.bash_profile
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
if [[ -z $(id $USER | grep "vpn") || -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
PATH=$HOME/bin
export PATH
else
PATH=PATH=$PATH:$HOME/.local/bin:$HOME/bin
export PATH
fi
if [[ -n $(id $USER | grep "utilisateurs du domaine") ]]
then
if [[ ! -e $HOME/.google_authenticator ]]
then
if [[ -n $(id $USER | grep "vpn") ]]
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 "vpn") ]]
then
logout
fi
fi
else
echo "You don't need to set up a Google Authenticator"