Notes pour l'installation sécurisée de eLaBFTW (modèle recommandé)
Contexte
Tout d'abord consulter la documentation officielle pour l'installation d'ELABFTW à cette adresse https://doc.elabftw.net/install.html
Le modèle recommandé est d'effectuer une installation sécurisée avec les composants suivants:
- 1 adresse publique: 1XX.XXX.XXX.XXX, cle.xyz.u-bordeaux.fr
- 1 machine virtuelle avec le frontend eLabFTW: xyz.front.lab
- 1 machine virtuelle avec MySQL avec TLS : xyz.mysql.lab
- 1 machine virtuelle avec un reverse proxy: TRAEFIK (ou NGINX ou Apache) et avec certificat SSL
- des volumes persistants sous /opt/elabftw (pour cert, web et mysql)
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 5.0.3) proposée par le développeur Nicolas Carpi sur le site de 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 Docker pour eLabFTW et MySQL. Il faudra donc adapter et diviser le fichier docker-compose.yml
:
- pour la machine virtuelle et VM eLabFTW ne garder que la partie services/web ;
- pour la machine virtuelle et VM MySQL ne garder que la partie services/MySQL ;
on peut utiliser la partie services/web dans la version ci-dessous:
version: '3'
# our first container is nginx + php-fpm + elabftw
services:
web:
image: elabftw/elabimg:5.0.3
restart: always
container_name: elabftw
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=/mysql-cert/server-cert.pem
- PHP_TIMEZONE=Europe/Paris
- TZ=Europe/Paris
- SECRET_KEY=UUUxxxxxxxxxxxxxxxx931b400a4a031a1925b1
- SITE_URL=https://cle.xyz.u-bordeaux.fr (ou adresse IP du service elabftw)
- SERVER_NAME=cle.xyz.u-bordeaux.fr (ou adresse IP du service elabftw)
- DISABLE_HTTPS=false
- ENABLE_LETSENCRYPT=false
ports:
- '443:443'
volumes:
- /opt/elabftw/web:/elabftw/uploads
- /opt/elabftw/cert:/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
/opt/elabftw/web
- un pour le certificat du serveur mysql:
/opt/elabftw/cert
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 (xyz.mysql.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'
services:
mysql:
container_name: mysql
image: mysql:8.0
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: elabftw
MYSQL_USER: elabftw
MYSQL_PASSWORD: ZZZxxxxxxxxooOMoX
MYSQL_ROOT_PASSWORD: VVVxxxxxOVYu3Svs
volumes:
- /opt/elabftw/mysql:/var/lib/mysql
- /opt/elabftw/cert:/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 :
/opt/elabftw/mysql
- un pour les certificats utilisés par le serveur mysql :
/opt/elabftw/cert
ATTENTION, avant de lancer le conteneur docker mysql il faut générer les certificats.
Source configuration mysql avec ssl : https://techsparx.com/software-development/docker/damp/mysql-ssl-connection.html
Se mettre dans le répertoire /opt/elabftw/cert
afin de générer la CA, le certificat serveur et le certificat client.
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 (xyz.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
, mais cela n'empêche pas le fonctionnment.
TIPS: Il faut que le fichier
server-key.pem
ai l'uid: 999 pour que le serveur se lance avec ssl.
sudo chown 999 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 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