Notes pour l'installation sécurisée de ELABFTW selon les consignes du CNRS
Contexte
Tout d'abord consulter la documentation officielle pour l'installation d'ELABFTW à cette adresse https://doc.elabftw.net/install.html
- adresse publique: 1XX.XXX.XXX.XXX, cle.xyz.u-bordeaux.fr
- reverse proxy: TRAEFIK (ou NGINX) avec certificat SSL
- frontend ELABFTW: xyz.front.lab
- mysql avec TLS : xyz.mysql.lab
Installation
Sur le frontend ELABFTW (xyz.front.lab)
Sur cette machine il n'y aura que le frontend ELABFTW qui est configuré dans le fichier docker-compose.yml
. Télécharger la dernière version (actuellement la 4.8.6) proposée par Nicolas Carpi sur le site d'elabftw et l'adapter selon ses besoins.
Télécharger le fichier docker-compose.yml
curl -so docker-compose.yml "https://get.elabftw.net/?config"
L'avantage de cette version est qu'elle est complète et à jour. Par contre, cette version contient des conteneurs pour elabftw et mysql. Il faudra donc l'adapter pour ne garder que la partie services/web.
Autrement on peut utiliser la version ci-dessous:
version: '3'
# our first container is nginx + php-fpm + elabftw
services:
web:
image: elabftw/elabimg:4.8.6
restart: always
container_name: elabftw_cnrs
security_opt:
- no-new-privileges:true
cap_drop:
- SYS_ADMIN
- AUDIT_WRITE
- MKNOD
- SYS_CHROOT
- SETFCAP
- NET_RAW
- SYS_PTRACE
environment:
- DB_HOST=xyz.mysql.lab
- DB_PORT=3306
- DB_NAME=elabftw
- DB_USER=elabftw
- DB_PASSWORD=ZZZxxxxxxxxxxxxxxxxooOMoX
- DB_CERT_PATH=/elabftw/mysql-cert/server-cert.pem
- PHP_TIMEZONE=Europe/Paris
- TZ=Europe/Paris
- SECRET_KEY=UUUxxxxxxxxxxxxxxxx931b400a4a031a1925b1
- SITE_URL=https://cle.xyz.u-bordeaux.fr
- SERVER_NAME=cle.xyz.u-bordeaux.fr
- DISABLE_HTTPS=false
- ENABLE_LETSENCRYPT=false
ports:
- '443:443'
volumes:
- ./elabftw/web:/elabftw/uploads
- ./certs:/elabftw/mysql-cert
networks:
- elabftw-net
Cette version est prévue pour fonctionner avec un serveur mysql en TLS. Le certificat du serveur est géré par le reverse proxy TRAEFIK
Deux volumes persitants sont utilisés pour le conteneur
- un pour les fichiers qui seront télécharger dans elabFTW
elabftw/web
- un pour le certificat du serveur mysql:
certs
On lance elabFTW avec la commande suivante:
docker-compose up -d
il faut ensuite installer le serveur mysql comme indiqué dans le chapître ci-dessous puis on lance l'initialisation de la base de données avec la commande suivante:
docker exec elabftw_cnrs bin/init db:install
_ _ _____ _______ __
___| | __ _| |__ | ___|_ _\ \ / /
/ _ \ | / _| | '_ \| |_ | | \ \ /\ / /
| __/ |__| (_| | |_) | _| | | \ V V /
\___|_____\__,_|_.__/|_| |_| \_/\_/
Welcome to the install of eLabFTW!
This program will install the MySQL structure.
Before proceeding, make sure you have an empty MySQL database for eLabFTW with a user+password to access it.
→ Initializing MySQL database...
✓ Installation successful! You can now start using your eLabFTW instance.
→ Register your Sysadmin account here: cle.rmsb.u-bordeaux.fr/register.php
→ Subscribe to the low volume newsletter to stay informed about new releases: http://eepurl.com/bTjcMj
Sur le serveur mySQL (raisin-cle-4-umr5107.lab)
On installe le serveur mysql avec ssl et docker
Le plus simple est de repartir du docker-compose.yml téléchargé précédement et l'adapter à ses besoins. Ci-dessous celui que j'utilise:
version: '3.8'
services:
mysql:
container_name: mysql_cnrs_ssl
image: mysql:8.0
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: elabftw
MYSQL_USER: elabftw
MYSQL_PASSWORD: ZZZxxxxxxxxooOMoX
MYSQL_ROOT_PASSWORD: VVVxxxxxOVYu3Svs
volumes:
- ./mysql:/var/lib/mysql
- ./certs:/etc/certs/
command: [ "mysqld",
"--character-set-server=utf8mb4",
"--collation-server=utf8mb4_unicode_ci",
"--bind-address=0.0.0.0",
"--require_secure_transport=ON",
"--ssl-ca=/etc/certs/ca-cert.pem",
"--ssl-cert=/etc/certs/server-cert.pem",
"--ssl-key=/etc/certs/server-key.pem",
"--default_authentication_plugin=mysql_native_password" ]
restart: always
Deux volumes persistants sont utilisés pour le conteneur:
- un pour les fichiers de mysql :
./mysql
- un pour les certificats utilisés par le serveur mysql :
./certs
Avant le lancer le conteneur docker de mysql il faut générer les certificats.
Source configuration mysql avec ssl : https://techsparx.com/software-development/docker/damp/mysql-ssl-connection.html
Ce mettre dans le répertoire ./certs
Commandes utilisées, on peut se servir du script gencert.sh
qui reprend toutes les commandes ci-dessus:
- Créer la clé du CA:
openssl genrsa 2048 > ca-key.pem
- Créer le certificat avec la clé précédente:
openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem
avec un exemple de sortie
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:Aquitaine
Locality Name (eg, city) []:Bordeaux
Organization Name (eg, company) [Internet Widgits Pty Ltd]:CNRS
Organizational Unit Name (eg, section) []:NOM_DE_SON_LABO
Common Name (e.g. server FQDN or YOUR name) []:xyz.mysql.lab
Email Address []:
il est important de mettre pour le Common Name ou CN le nom du serveur mysql qui est utilisé pour la configuration d'elabFTW pour que cela fonctionne. Dans cet exemple c'est xyz.mysql.lab
A ce stade on a 2 fichiers :
- ca-cert.pem – Fichier de certificat Certificate Authority (CA).
- ca-key.pem – Fichier de clé Certificate Authority (CA).
On utilise ces 2 clés pour générer les certificats serveur et client.
- Pour le serveur, on crée la clé et le certificat :
openssl req -newkey rsa:2048 -days 365000 -nodes -keyout server-key.pem -out server-req.pem
Utiliser le même Common Name que ci-dessus
On convertit la clé en RSA:
openssl rsa -in server-key.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
Signature ok
subject=C = FR, ST = Aquitaine, L = Bordeaux, O = CNRS, OU = RMSB, CN = xyz.mysql.lab
Getting CA Private Key
On a donc 2 fichiers :
- server-cert.pem – Fichier certificat SSL du serveur mySQL
- server-key.pem – Fichier de clé SSL pour le serveur mySQL
On génère le certificat pour le client de la même manière :
ATTENTION Pour le client utiliser le COMMON NAME (CN) du serveur eLabFTW (zozo.dmz.fr)
openssl req -newkey rsa:2048 -days 365000 -nodes -keyout client-key.pem -out client-req.pem
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
On vérifie les certificats :
openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK
on peut avoir cette erreur:
C = FR, ST = Aquitaine, L = Bordeaux, O = CNRS, OU = CRMSB, CN = xyz.mysql.lab
error 18 at 0 depth lookup: self signed certificate
error server-cert.pem: verification failed
client-cert.pem: OK
C'est parce que nous avons utilisé le même CN pour le ca-cert.pem
et le server-cert.pem
. Cela fonctionne quand même (TODO: trouver unmoyen d'éviter l'erreur)
TIPS: Il faut que le fichier
server-key.pem
ai l'uid: 999 pour que le serveur se lance avec ssl.
sudo chown 999 certs/server-key.pem
On peut vérifier que la liason entre elabftw et le serveur mysql fonctionne correctement avec la commande suivante:
docker exec -ti elabftw_cnrs php bin/console db:check
Si cela retourne:
Database check
==============
Current version: 111
Required version: 111
No upgrade required.
Tout est OK, par contre si on a:
In Db.php line 52:
SQLSTATE[HY000] [2002] (trying to connect via (null))
In Db.php line 52:
PDO::__construct(): Peer certificate CN=`server-cert' did not match expected CN=`xyz.mysql.lab'
Le problème est du à un certificat avec le mauvais Common Name
In Db.php line 52:
SQLSTATE[HY000] [2002] (trying to connect via (null))
In Db.php line 52:
PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages:
error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed
db:check
Ce n'est pas le même certificat entre le serveur mysql et elabftw
Sur le reverse proxy
Traefik est utilisé Traefik mais il possible d'utiliser également Nginx Nginx.
Voici le fichier pour rediriger vers le serveur:
elabftw_cle_rmsb.yml
http:
routers:
elabftw_cnrs:
tls: {}
entryPoints: ["secure", "insecure"]
service: "service-cle"
priority: 50
rule: "Host(`cle.xyz.u-bordeaux.fr`)"
services:
service-cle:
loadBalancer:
servers:
- url: "https://1XX.XXX.XXX.XXX:9444/"
Sur mon parefeu toutes les requêtes sur les ports 80 (http) et 443 (https) sont redirigés vers TRAEFIK qui ensuite fait le tri des requêtes et dans ce cas si l'URL contient cle.xyz.u-bordeaux.fr
elle est redirigée vers le serveur elabftw
https://1XX.XXX.XXX.XXX:9444.
Pour configurer le certificat du serveur il faut ajouter dans le fichier de configuration de TRAEFIK
traefik.yml
tls:
certificates:
- certFile: /etc/ssl/my_certs/xyzzzz.fr.all.cert
keyFile: /etc/ssl/my_certs/xyzzzz.cnrs.fr.key
stores:
- default
- certFile: /etc/ssl/my_certs/cle.xyz.u-bordeaux.fr.cert
keyFile: /etc/ssl/my_certs/cle.xyz.u-bordeaux.fr.key
stores:
- default
stores:
default:
defaultCertificate:
certFile: /etc/ssl/my_certs/2022-2023/www.rcle.xyz.u-bordeaux.fr.all.2022.cert
keyFile: /etc/ssl/my_certs/2022-2023/www.cle.xyz.u-bordeaux.fr.2022.key
Document généré avec:
pandoc -s -o installation_elabftw_cnrs.pdf -f "gfm"
--template /usr/share/pandoc/data/templates/eisvogel.latex
--listings --number-section -V subparagraph --toc
--dpi=300 -Vlang=fr-FR
--pdf-engine=xelatex header-elabftw.yml installation_elabftw_cnrs.md