Installer LinOTP2 sur Rocky 8
This post is also available in English : Installing LinOTP2 on Rocky 8.
Bonjour,
Aujourd’hui nous allons installer la dernière version de LinOTP2 depuis les sources sur un serveur Rocky Linux 8 dans un virtualenv Python 2. Nous allons configurer un serveur LinOTP basique pour des tokens TOTP (ceux que vous utilisez dans Google Authenticator) et configurer FreeRADIUS pour valider ce second facteur.
Installation de LinOTP
Au moment de l’écriture de ce tutoriel, les développeurs de LinOTP ne fournissent pas de RPM pour Rocky 8. Vous êtes limités à CentOS 7 ou des packages obsolètes sur pypi (dernière mise à jour il y a 2 ans). Nous allons donc installer LinOTP depuis la dernière version disponible sur git (actuellement la 2.12.3).
Vous devez commencer par installer python2, le package de développement pour OpenSSL, swig et gcc depuis le dépôt Rocky. Les 3 derniers packages sont nécessaires pour installer le package Python m2crypto depuis pip un peu plus loin dans ce tutoriel :
dnf install epel-release
dnf install python2 python2-wheel python2-virtualenv git openssl-devel swig gcc openldap-devel libsodium
Créez ensuite un virtualenv dans /srv et activez-le :
cd /srv/
virtualenv-2 linotp
cd /srv/linotp
. bin/activate
Installez les dépendances Python nécessaires depuis pypi :
pip install pillow pillow-pil m2crypto
Clonez le dépôt GitHub de LinOTP :
git clone https://github.com/LinOTP/LinOTP
Vous devez maintenant trouver la dernière version stable. Chaque version a un tag associé qui commence par release/ :
cd LinOTP
STABLE_VERSION=$(git tag | grep release/2 | cut -d/ -f2 | sort --version-sort | tail -1)
git checkout release/$STABLE_VERSION
Assurez-vous d’être dans le virtualenv activé pour les prochaines commandes.
Pour installer LinOTP et LinOTPAdminCli dans votre virtualenv vous seriez tentés de lancer setup.py install
mais cela ne fonctionnerait pas car les dépendances seraient alors téléchargées
dans leur dernière version au lieu de leur dernière version compatible avec Python 2. Je n’ai pas trouvé d’astuce pour forcer la compatibilité avec Python 2 lors de l’utilisation de setup.py install
.
Le contournement consiste à créer un package wheel que vous installerez ensuite à l’aide de pip qui téléchargera alors les bonnes versions des dépendances :
cd /srv/linotp/LinOTP/linotpd/src/
python2 setup.py bdist_wheel
pip install dist/LinOTP-${STABLE_VERSION}-py2-none-any.whl
cd /srv/linotp/LinOTP/adminclient/LinOTPAdminClientCLI/src
python2 setup.py bdist_wheel
pip install dist/LinOTPAdminClientCLI-${STABLE_VERSION}-py2-none-any.whl
LinOTP est maintenant installé dans votre virtualenv mais vous devez encore réaliser quelques étapes supplémentaires pour terminer l’installation. Créez un répertoire de configuration, copiez-y le fichier linotp.ini d’exemple et générez le secret qui sera utilisé pour chiffrer les secrets dans la base de données :
useradd -d /srv/linotp -r -s /sbin/nologin linotp
mkdir -pv /etc/linotp2/data
mkdir -pv /var/log/linotp/
cp /srv/linotp/etc/linotp2/linotp.ini.example /etc/linotp2/linotp.ini
linotp-create-enckey -f /etc/linotp2/linotp.ini
chown linotp:linotp -R /etc/linotp2
chown linotp:linotp -R /var/log/linotp
C’est terminé pour l’installation et la configuration de base.
MariaDB
LinOTP utilise l’ORM SQL Alchemy pour accéder à sa base de données. Cela vous permet de choisir votre base de données préférée parmi celles supportées. Dans ce tutoriel vous allez utiliser MariaDB.
Installez le package MariaDB :
dnf install mariadb-server
Activez et démarrez le service :
systemctl enable --now mariadb
Sécurisez l’installation (suppression de la base de test et création d’un mot de passe pour l’utilisteur root) :
mysql_secure_installation
Créez la base LinOTP et un utilisateur associé :
mysql -p
CREATE DATABASE linotp;
GRANT ALL PRIVILEGES ON linotp.* TO linotp@localhost IDENTIFIED BY 'PASSWORD';
Installez le package pymysql dans votre virtualenv pour que SQL Alchemy puisse se connecter à votre base :
pip install pymysql
Maintenant configurez l’accès à la base données dans le fichier de configuration. Modifiez /etc/linotp2/linotp.ini
avec votre éditeur préféré.
Remplacez la ligne suivante avec les paramètres de votre base de données (si vous avez choisi un nom de base ou un login différent modifiez la configuration) :
sqlalchemy.url = mysql+pymysql://linotp:PASSWORD@localhost/linotp
Initialisation et test de LinOTP
LinOTP est installé, votre base de données est prête, vous pouvez maintenant créer la structure de la base avec la commande suivante :
su linotp -s /bin/bash -c "paster setup-app /etc/linotp2/linotp.ini"
Vous pouvez vérifier que tout fonctionne correctement avec :
su linotp -s /bin/bash -c "paster serve /etc/linotp2/linotp.ini"
La page d’administration de LinOTP doit être accessible à l’adresse http://localhost:5001/manage/
Configurer Apache
Dans un environnement de production vous ne devez pas utiliser le serveur HTTP intégré à LinOTP. Comme vous l’avez constaté la page d’administration est ouverte à tout le monde sans authentification. Vous devez configurer un virtualhost Apache qui utilise WSGI pour servir l’application LinOTP, vous devez également y configurer l’authentification.
Commencez par installer httpd et son package de développement. Vous allez utiliser ce dernier pour compiler le module Apache mod_wsgi à l’aide de pip :
dnf install httpd httpd-devel mod_ssl
pip install mod_wsgi
Créer un lien symbolique vers mod_wsgi dans le répertoire qui contient les modules Apache :
ln -s /srv/linotp/lib/python2.7/site-packages/mod_wsgi/server/mod_wsgi-py27.so /etc/httpd/modules/
Ajouter la configuration pour charger le module WSGI :
cat > /etc/httpd/conf.modules.d/99-wsgi.conf <<EOF
LoadModule wsgi_module modules/mod_wsgi-py27.so
EOF
Remplacer le contenu du fichier /etc/httpd/conf.d/ssl.conf
par une configuration qui autorise seulement les connexions TLS >= 1.2 :
# Generated from https://ssl-config.mozilla.org/#server=apache&version=2.4.37&config=modern&openssl=1.1.1k&hsts=false&ocsp=false&guideline=5.6
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
Apache va utiliser un script python WSGI pour charger l’application, copiez le dans /etc/linotp2/
et copiez le fichier de configuration du virtualhost Apache dans le répertoire de configuration :
cp /srv/linotp/etc/linotp2/linotpapp.wsgi /etc/linotp2/
cp /srv/linotp/LinOTP/linotpd/src/config/apache2.4-example/linotp2.conf /etc/httpd/conf.d/
Modifiez le fichier linotp2.conf pour remplacer Include /etc/linotp2/apache-servername.conf
par ServerName VOTRE.DOMAINE
Sur la ligne suivante ajoutez la directive python-home
en la faisant pointer vers le répertoire du virtualenv (/srv/linotp
) :
WSGIDaemonProcess linotp processes=1 threads=15 display-name=%{GROUP} user=linotp python-home=/srv/linotp
Securisez l’accès à l’interface web par une authentification gérée par Apache. Dans le fichier linotp2.conf, une authentification Digest basée sur un fichier est utilisée :
AuthType Digest
AuthName "LinOTP2 admin area"
AuthDigestProvider file
AuthUserFile /etc/linotp2/admins
Require valid-user
Changer le chemin vers les certificats :
SSLCertificateFile /etc/linotp2/linotpserver.pem
SSLCertificateKeyFile /etc/linotp2/linotpserver.key
Ajoutez un compte admin dans /etc/linotp2/admins
:
htdigest -c /etc/linotp2/admins admin
Générez un certificat auto-signé (ou utilisez un certificat valide pour le domaine configuré) :
openssl req -subj '/CN=172.24.12.168' -new -newkey rsa:2048 -sha256 -days 3650 -nodes -x509 -keyout /etc/linotp2/linotpserver.key -out /etc/linotp2/linotpserver.pem
Modifiez l’emplacement des logs :
ErrorLog logs/error_log
CustomLog logs/ssl_accessa_log LinOTP2
Enfin, démarrez le service Apache :
systemctl enable --now httpd
Configuration RADIUS
Un usage classique des tokens OTP est l’ajout d’un second facteur d’authentification à l’aide du protocole RADIUS. De nombreux logiciels et composants matériels supportent l’authentification RADIUS (concentrateurs VPN, switchs, Citrix Netscaler, …). LinOTP fourni un module PERL qui peut être utilisé par FreeRADIUS pour appeler le service d’authentification de LinOTP.
Commencez par installer FreeRADIUS et les packages PERL nécessaires :
dnf install freeradius-perl cpan
cpan install LWP Config::File LWP::Protocol::https
Téléchargez le module PERL LinOTP depuis GitHub et enregistrez-le dans votre répertoire d’installation :
curl https://raw.githubusercontent.com/LinOTP/linotp-auth-freeradius-perl/master/radius_linotp.pm -o /srv/linotp/share/linotp/radius-linotp.pm
Configurez le module dans FreeRADIUS :
cat >/etc/raddb/mods-enabled/perl-linotp <<EOF
perl linotp {
filename = /srv/linotp/share/linotp/radius-linotp.pm
perl_flags = "-T"
}
EOF
Supprimez les sites FreeRADIUS par défaut :
rm /etc/raddb/sites-enabled/*
Créez un site LinOTP avec la configuration minimum :
cat >/etc/raddb/sites-enabled/linotp <<EOF
server linotp {
listen {
type = auth
ipaddr = *
# 0 means "use /etc/services for the proper port"
port = 0
}
authorize {
filter_username
preprocess
suffix
update control {
Auth-Type := PAP
}
}
authenticate {
Auth-Type PAP {
linotp
}
}
}
EOF
Vous pouvez utiliser la commande radius -X
pour vérifier que le service démarrer et fonctionne, une fois que c’est bon démarrez le service avec systemctl enable --now radiusd
Test rapide
Maintenant que tout est configuré et démarré vous pouvez réaliser un test rapide.
Créez un user ID resolver basé sur le fichier (Flat file) /etc/passwd pour que vous puissiez créer un token pour un utilisateur local. Créez ensuite un realm qui utilise votre user ID resolver. Vous pouvez maintenant vous rendre sur l’onglet Utilisateurs et créer un token TOTP (time-based OTP) pour l’utilisateur root. Scannez les QRCode à l’aide de l’application (Google Authenticator par exemple) et essayez-le avec la commande radtest (package freeradius-utils) :
radtest root VOTRE_TOKEN_TOTP 127.0.0.1 1
Vous devez obtenir une réponse Access Granted, si ce n’est pas le cas vous pouvez arrêter le service FreeRADIUS, utiliser radius -X
et regarder le log situé dans /var/log/linotp/linotp.log
.
Mise à jour
Les mises à jour peuvent être réalisées en récupérant la dernière version depuis le dépôt git (git pull) et en générant un nouveau package wheel à l’aide des commandes pip que vous avez utilisées.
Ensuite vous devez mettre à jour les packages dans votre virtualenv en utilisant pip install --upgrade /chemin/vers/nouvelle_version.whl
.
Lisez la note de version afin de vérifier qu’il n’y a pas d’autres actions manuelles à effectuer avant ou après la mise à jour.