Stormshield, filiale de Airbus CyberSecurity et fusion d’Arkoon et Netasq, propose les produits Network Security, pare-feux de nouvelle génération embarquant une plétore de fonctionnalités : IDS/IPS, filtrage HTTP/HTTPS, déchiffrement SSL/TLS, analyse profonde des packets (Deep Packet Inspection), passerelle VPN IPSec et SSL (OpenVPN)…
Ces produits ont acquis une certaine maturité depuis la dernière version 4 du firmware. Plus rapides, plus ergonomiques, ces derniers sont une solution de choix pour les entreprises, correspondants aux besoins des TPE jusqu’à ceux des grandes entreprises, grâce un firmware unique, des fonctionnalités unifiées et des modèles répondant à toutes les tailles de systèmes d’informations.
Travaillant avec ce matériel depuis les modèles proposés par Netasq, j’ai pu mettre en place une trentaine d’entre eux, des modèles allant du SN160 jusqu’au SN910. Ceci m’a permis d’acquérir une certaine maîtrise du produit (la certification CSNE aidant) et d’avoir un recul critique sur les appliances proposées par Stormshield.
L’une des puissances du produit est de proposer une passerelle VPN SSL basée sur OpenVPN, clé en main, permettant en quelques minutes de déployer des accès distants sécurisés à des clients mobiles. Connecté à un annuaire Active Directory, la solution est facile d’utilisation pour des utilisateurs nomades, qui n’ont qu’à renseigner leurs identifiants de domaine pour établir un tunnel sécurisé avec la passerelle.
Mais à l’heure d’un télétravail de plus en plus fréquent et de la recrudescence des attaques, ces accès nomades sont une porte d’entrée négligée et difficilement protégeables avec la solution de base. L’une des solutions et de mettre en place une authentification multi-facteurs, basée par exemple sur un mot de passe à usage unique (OTP). Je vous propose dans cet article de voir comment mettre en place une authentification multi-facteurs pour vos nomades utilisant du VPN SSL. La solution proposée ici fonctionne également pour du VPN IPSEC basé sur un couple certificat/XAUTH.

LinOTP et FreeRADIUS, des solutions libres et gratuites
Les pare-feux Stormshield proposent les méthodes d’authentification suivantes :
- LDAP
- Certificat
- RADIUS
- Kerberos
- Authentification transparente (SPNEGO)
- Authentification unique (SSO)
Généralement, lors du paramétrage de la passerelle VPN SSL, c’est l’authentification LDAP qui sera utilisée pour authentifier et identifier les nomades. Cependant, il est tout à fait possible d’utiliser la méthode RADIUS pour authentifier ces derniers. Grâce à cette fonctionnalité de notre pare-feu, nous allons pouvoir utiliser la solution libre de l’éditeur allemand Key Identity, LinOTP, qui peut fonctionner avec un serveur RADIUS. J’utiliserai ici le projet FreeRADIUS, implémentation libre du protocole RADIUS normalisé par l’IETF en 2000 via la RFC2865.
Au niveau du fonctionnement, nous aurons ceci :

- Le client OpenVPN envoie la demande d’authentification avec le couple <username> et <password><OTP> au service d’authentification du pare-feu
- Le pare-feu fait une requête au serveur FreeRadius, via une requête standard RADIUS, lui demandant de valider la demande d’authentification.
- Le serveur FreeRADIUS, via un script Perl, fait une requête REST sur l’API de LinOTP
- Le serveur LinOTP, sépare le couple <password><OTP> et valide le One Time Password. Si ce dernier est correct, il transmet la demande d’authentification LDAP du couple <username> et <password> au contrôleur de domaine.
- Si l’authentification LDAP est correcte, le contrôleur de domaine répond positivement au serveur LinOTP
- Le serveur LinOTP répond positivement au serveur FreeRADIUS via une réponse en tant qu’objet JSON
- Le serveur FreeRADIUS, après avoir vérifié la réponse JSON, répond positivement au pare-feu
- Le pare-feu autorise le client OpenVPN à établir un tunnel VPN SSL.
Au niveau des pré-requis, nous aurons besoin :
- Debian/Ubuntu ou RHEL/CentOS 7. Je traiterai dans cet article l’installation sur RHEL 7.9, dernière version de RHEL 7.
- Une base de données (MySQL, MariaDB, PostGreSQL) pour stocker les tokens. J’utiliserai ici MariaDB
- FreeRADIUS, pour s’interfacer entre le pare-feu et LinOTP
- Une appliance Stormshield, physique ou virtuelle
- Un serveur de domaine Active Directory
Il est tout à fait possible de séparer chaque service sur un serveur distinct (base de données, LinOTP, FreeRADIUS). C’est à votre convenance, il faudra seulement modifier les adresses utilisées par les différents services. Pour ma part, j’utilise un serveur déjà existant dédiée aux bases de données, où sera localisée la base de données des tokents. LinOTP et FreeRADIUS, seront eux, sur un autre serveur.
Malheureusement, je n’ai pas pu faire fonctionner l’authentification à double facteur avec le client VPN SSL officiel de Stormshield. Ce dernier utilise deux phase : l’authentification sur le portail pour récupérer la configuration OpenVPN et la configuration OpenVPN en elle même. Cependant, l’authentification à double facteur fonctionne parfaitement avec le client OpenVPN officiel, que ce soit la version 2.5 ou 3. Vous n’aurez qu’à déployer la configuration .openvpn sur vos nomades.
I. Installation et configuration de LinOTP
Une fois votre serveur fraîchement installé, et à jour, nous allons installer et paramétrer la base de données hébergeant les tokens de LinOTP. Peu importe que votre base de données soit déportée ou sur le même serveur. Attention, si vous êtes sur RHEL, assurez-vous que votre système soit enregistré et abonné.
I.1. Installation et paramétrage de la base de données
Commençons par installer MariaDB via les dépôts officiels :
sudo yum install mariadb-server
Lançons ensuite le script automatisé d’initialisation du SGBD, de manière interactive :
sudo mysql_secure_installation
Je vous conseille de paramétrer MariaDB comme ci-dessous :
Set root password? [Y/n] y
New password: <password>
Re-enter new password: <password>
Remove anonymous users? [Y/n]: Y
Disallow root login remotely? [Y/n]: Y
Remove test database and access to it? [Y/n]: Y
Reload privilege tables now? [Y/n]: Y
Assurez de vous de mettre un mot de passe assez complexe, de retirer les utilisateurs anonymes, de désactiver l’authentification du compte root à distance, de supprimer la base de données de test, et enfin de rechargé la table des privilèges.
Une fois MariaDB installé et initialisé, créons la base de données le compte d’accès à la base pour LinOTP :
mysql -u root -p
Un conseil, ne renseignez jamais vos mots de passe directement dans la ligne de commande de connexion à la base, ils se retrouveraient dans l’historiqued de commande. Vous ne savez pas qui peut être amené à opérer sur le serveur 😉
CREATE DATABASE <nom_de_la_base> ;
CREATE USER ‘<nom_user>’@’<IP_USER>’ IDENTIFIED BY ‘<mdp_user>’ ;
GRANT ALL PRIVILEGES ON <nom_de_la_base>.* TO ‘<nom_utilisateur>’@’<IP_de_l’utilisateur>’ IDENTIFIED BY ‘<mdp_user>’ ;
FLUSH PRIVILEGES ;
quit ;
Si votre serveur de base de données est déporté sur un autre serveur, ouvrez le port TCP/3306 sur le pare-feu système. N’hésitez pas à n’ouvrir l’accès que pour votre serveur LinOTP si ce dernier est le seul à se connecter à la base de données. De manière générale, je vous conseille de n’ouvrir que le strict nécessaire sur vos pare-feux.
firewall-cmd --new-zone=mariadb-access --permanent
firewall-cmd --reload
firewall-cmd --zone=special --add-source=<adresse ip de LinOTP>/32
firewall-cmd --zone=special --add-port=3306/tcp
Grâce à la création d’une zone spécifique, en cas de création d’une nouvelle base de données sur MariaDB pour un autre service, vous n’aurez qu’à rajouter l’adresse IP supplémentaire dans cette zone.
Cependant, vous pouvez également ouvrir de manière plus large grâce à la commande suivante :
firewall-cmd --add-port=3306/tcp --permanent
firewall-cmd --reload
I.2 Installation de LinOTP
Nous allons tout d’abord rajouter un dépôt pour Yum :
sudo yum localinstall http://linotp.org/rpm/el7/linotp/x86_64/Packages/LinOTP_repos-1.1-1.el7.x86_64.rpm
Pensez à vérifier qu’une nouvelle version n’est pas présente sur http://linotp.org/rpm/el7/linotp/x86_64/Packages/
On active les packages supplémentaires EPEL (Extra Packages for Enterprise Linux) :
sudo yum install epel-release
Enfin, on installe LinOTP et le client MariaDB :
sudo yum install LinOTP LinOTP_mariadb
Une fois LinOTP installé, il faut indiquer à LinOTP comment se connecter à la base de données. Pour cela, on modifie le fichier /etc/linotp2/linotp.ini
et on modifie le paramètre sqlalchemy.url
, normalement situé à la ligne 170 du fichier :
sqlalchemy.url = mysql://<user>:<Password>@<@IP_BDD>/<nom_de_la_base>
Je vous conseille de tester avant l’utilitaire CLI de MariaDB de vous connecter à la base de données, ça vous évitera de perdre du temps en cas d’erreur 🙂
I.3 Installation de l’interface web de LinOTP
Nous avons installé précédemment le coeur de LinOTP, mais il existe également un service web servant pour l’administration de LinOTP et pour le selfservice des utilisateurs. Le paquet LinOTP_apache HTTPD et des fichiers de configurations pré-générés. Pour l’installer :
sudo yum install LinOTP_apache
On active ensuite le démarrage du service HTTPD au démarrage du serveur :
systemctl enable httpd.service
On génère les clés de chiffrement permettant de chiffrer la base de données précédemment crée sur le serveur MariaDB, grâce au script suivant :
/etc/linotp2/linotp-create-enckey -f /etc/linotp2/linotp.ini
On fixe les permissions et la propriété des fichiers de configurations pour le compte de service linotp
:
/etc/linotp2/linotp-fix-access-rights -f /etc/linotp2/linotp.ini -u linotp
On ouvre le port TCP/443 pour notre service web :
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd--reload
I.3. Configuration de l’interface web
Un fichier de configuration est fourni par défaut, faisons une copie de la configuration initiale et utilisons celle donnée avec le paquet :
mkdir /etc/httpd/conf.d.old
mv /etc/httpd/conf.d/* /etc/httpd/conf.d.old
cp /etc/httpd/conf.d.old/ssl_linotp.conf.template /etc/httpd/conf.d/ssl_linotp.conf
Modifions dès à présent le mot de passe du compte administrateur de base, via le fichier :
vim /etc/linotp2/admins
Enfin, démarrons le serveur web :
systemctl start httpd.service
Attention, de base, LinOTP utilise un certificat auto-signé pour chiffrer les connexions TLS. Je vous recommande bien sûr de générer un certificat signé par une autorité de certification. Rien de bien compliqué, il suffit d’indiquer au fichier de configuration /etc/httpd/conf.d/ssl_linotp.conf
quel certificat utiliser.
L’interface d’administration est accessible via l’url : https://<LinOTP_IP>/manage/
Il est possible d’utiliser un groupe d’utilisateurs du domaine Active Directory pour administrer LinOTP. Pratique si vous souhaitez déléguer l’accès à une équipe d’administrateurs systèmes. Pour cela, il faut modifier la configuration d’Apache. Vous pouvez passer à l’étape I.4 si cela ne vous intèresse pas.
Paramétrage d’un groupe d’utilisateurs AD/LDAP pour administrer LinOTP
Installer le module mod_ldap
d’Apache :
sudo yum install mod_ldap
Modifier le VirtualHost afin d’utiliser l’authentification LDAP :
sudo vim /etc/httpd/conf.d/ssl_linotp.conf
Le AuthLDAPURL doit être sous cette forme:
ldap://@IP(ou nom)/<BaseDN>?sAMAccountName?sub?(objectClass=user)” NONE.
Aidez-vous de ce que vous avez renseigné pour le UserIdResolver de LinOTP
Pour le AuthLDAPBindDN, saisissez ce que vous aviez mis pour le UserIdResolver de LinOTP entre parenthèses
Pour le AuthLDAPBindPassword, c’est le mot de passe du compte entre parenthèses
Pour Require ldap-group, mettez le chemin du groupe ldap que vous souhaitez autoriser à la connexion
I.4. Connexion de LinOTP à l’Active Directory
Nous allons ici connecter LinOTP à notre Active Directory. Assurez vous d’avoir un compte dédié à ce bind. Je vous rappelle qu’un compte non privilégie suffit et qu’il n’est en aucun cas nécessaire d’utiliser un compte ayant des droits d’administration sur le domaine.
Dans un environnement de production, générez une chaîne de charactères aléatoire pour le nom du compte et générez un mot de passe fort. Evitez de remplir le champ description de l’objet. Conservez ces informations dans un gestionnaire de mot de passe sûr. Moins d’infos vous laissez à un potentiel attaquant, mieux votre AD se portera. Pour finir, limitez la connection du compte au contrôleur de domaine. Ceci évitera la réutilisation du compte sur d’autres machines de votre réseau.
Nous allons créer un UserIdResolver, où nous allons pouvoir renseigner notre annuaire. Aller dans « Configuration LinOTP » ou « LinOTP Configuration » selon la langue de votre interface, puis dans « UserIdResolvers ».

Créer un « LDAP Resolver », et compléter le resolveur selon votre environnement. Si vous avez plusieurs contrôleurs de domaine, mettez les, cela vous assurera une redondance.

Vérifier que les attributs du schéma soient adaptés pour Active Directory. Cliquer sur « Preset Active Directory » pour les forcer.
Je vous conseille de filtrer sur un groupe préalablement créé, pour limiter l’import des utilisateurs dans LinOTP. Vous pouvez adapter le filtre suivant, sur le champ « Searchfilter » :
(&(Objectclass=user)(objectCategory=person)(memberOf=CN=LinOTP Users,OU=Users groups,DC=LAB,DC=INFO-SEC,DC=FR)))
Une fois notre résolveur créé, on le configure pour un domaine. Pour cela, aller dans « Configuration LinOTP » ou « LinOTP Configuration » puis dans « Domaines » ou « Realms ». Créer ensuite un nom de domaine et configurer le pour utiliser le résolveur précédemment créé.
I.5 Configuration du self service
Le Self-Service permet à des utilisateurs de générer et supprimer eux-mêmes leur token sans passer par la console de management, elle peut être personnalisée pour des groupes d’utilisateurs, ici nous allons configurer le Self-Service pour que les utilisateurs puissent générer eux-mêmes des tokens compatible avec Google-Authentificator – FreeOTP basé sur le temps (renouvellement toutes les 30sec)
Pour cela il va falloir créer une directive que l’on va appliquer sur le résolveur créé précédemment. Aller dans le menu Directives puis en créer une :
II. Paramétrage de FreeRADIUS
II.1. Paramétrage de base
Pour commencer, installer les paquets suivants :
sudo yum install freeradius freeradius-perl perl-Config-IniFiles perl-Try-Tiny perl-LWP-Protocol-https
Faire un backup du dossier /etc/raddb/ :
sudo cp -a /etc/raddb /etc/raddb.old
/
Modifier alors le fichier /etc/raddb/clients.conf, pour rajouter un client, avec les élèments suivants :
Client <nom_du_client> {
ipaddr = <IPduClient>
secret = <presharedkey>
}
Soit par exemple :
Client sn310 {
ipaddr = 172.16.1.254
secret = QWfQLtEggxJQAtpANVjd
}
Veiller à choisir un secret fort pour protéger correctement les échanges entre le client (Stormshield) et le serveur Radius.
On vérifie que le fichier /etc/raddb/users contient la directive suivante :
DEFAULT Auth-type := perl
Si ce n’est pas le cas, supprimer le contenu éventuel et renseigner la directive ci-dessus.
II.2. Liaison à LinOTP
Le plugin officiel fourni par LinOTP ne fonctionne pas pour RHEL/CentOS 7. Il faut donc récupérer une version modifiée et proposée par Mark VANDEBOS sur son GitHub :
wget https://github.com/mark-vandenbos/linotp-freeradius3-centos7/archive/master.zip
unzip master.zip
Copier le plugin à l’emplacement dédié :
cp linotp-freeradius3-centos7-master/linotp-perl.pm /etc/raddb/mods-config/perl/radius_linotp.pm
III. Configuration du pare-feu Stormshield
Je vais assumer ici que votre passerelle VPN (SSL ou IPSEC) est déjà en place et que votre appliance est connectée à votre Active Directory. Si ce n’est pas le cas, je vous renvoie vers les guides techniques pas à pas de Stormshield :
VPN SSL -> https://documentation.stormshield.eu/SNS/v4/fr/Content/SSL_VPN_tunnels/100-Introduction.htm
III.1. Paramétrage de la méthode d’authentification Radius
Premièrement, nous allons paramétrer une nouvelle méthode d’authentification, notre serveur FreeRADIUS. Pour cela, aller « Configuration »/ »Users »/ »Authentication » ou « Configuration »/ »Utilisateurs »/ »Authentification » en français.

Dans « Available methods » ou « Méthodes disponibles » en français, ajouter une nouvelle méthode, et choissisez « Radius ».

Configurer le serveur Radius avec l’adresse IP de notre serveur FreeRADIUS et la clé de chiffrement pré-partagée. Laissez le port par défaut.
Rendez-vous ensuite dans l’onglet « Authentication policy » ou « Politiques d’authentification », et rajouter une règle standard avec les élèments suivants :
- User or group : « Any user or group@<votre domaine> » soit par exemple « Any user or [email protected] »
- Ajouter en source l’interface sslvpn.
- Puis pour finir, supprimer la méthode par défaut et ajouter la méthode RADIUS.
Vous devriez avoir une règle comme celle ci-dessous :

Vous pouvez également rajouter comme source votre interface WAN, si vous voulez que votre portail captif utilise également LinOTP.
III.2. Empêcher le tunnel de se fermer après 3600 secondes (1 heure)
Et voilà ! Tout est configuré, testons à présent tout cela 🙂
IV. Test de la connexion VPN
Comme expliqué plus haut, je n’ai pas réussi à faire fonctionner la connexion VPN avec l’authentification à double facteurs avec le client VPN SSL officiel de Stormshield. Néanmoins, cela fonctionne parfaitement avec OpenVPN (version 2.5 et version 3).
Attention, sur OpenVPN en version 3, vous devez absolument activer la compression dans les paramètres genéraux d’OpenVPN. En effet, sans ce paramètre, la connexion s’établira mais vous rencontrerez des problèmes pour communiquer avec vos réseaux distants. (Cf. KB de Stormshield).
N’hésites pas à me faire des retours pour tout problème rencontré ou erreur se trouvant dans l’article.
Bel article, bien détaillé et bien expliqué! Merci
Pour information, la version 3.0 du client Stormshield est sortie il y a peu et permet de saisir un OTP (cf. https://documentation.stormshield.eu/SNS/v3/fr/Content/Release_Notes_SSL_VPN_Client/3.0.0-Features.htm)
Bonjour,
Merci pour le retour !
Oui effectivement j’ai vu la release note de la dernière version du client Stormshield mais je n’ai encore eu le temps d’essayer. Je mettrais à jour l’article en conséquence.
Bonjour,
Merci pour cet excellent tuto.
Pour les accros de Debian, on lira, en complément d’installation
https://medium.com/@katerynamok/linotp-installation-and-usage-1addc11b3c74
car il existe de nombreuses différences pour l’installation de FreeRadius.
NB: il faut la version « Buster » et non la dernière sur laquelle les paquets n’ont pas encore été portés
Bonjour,
Merci pour votre retour et pour le lien.
De mon côté je suis accro à CentOS/RHEL mais effectivement ça vaut le coup de proposer également Debian comme distribution !
Hello,
Merci pour cet article bien détaillé.
J’aimerais bien mettre en place OTP mais via le client VPN-SSL Stormshield.
Par contre aucune docs de leur côté expliquant le fonctionnement…
Rien non plus depuis l’interface de management donc ce n’est pas encore supporté nativement même dans les derniers firmwares.
Bonjour,
Merci pour votre commentaire !
Normalement la version 3.0.0 du client VPN-SSL gère l’authentification OTP : https://documentation.stormshield.eu/SNS/v3/fr/Content/Release_Notes_SSL_VPN_Client/3.0.0-Features.htm
Et depuis la 4.5.1 (attention version non stable), les pares-feux embarquent l’authentification OTP : https://documentation.stormshield.eu/SNS/v4/fr/Content/Release_Notes_SNS/4.5.1-Features.htm
Je n’ai pas essayé de faire fonctionner le nouveau client VPN-SSL Stormshield avec la solution présentée dans cet article. Je doute que cela fonctionne cependant.
Bonnes recherches !
merci pour votre tuto.
Pour ce qui est du client, après plusieurs essais, il m’a fallu me connecter juste avec «id/mot de passe» pour mettre à jour la conf, ce qui a permit de me connecter avec le token OTP