Guacamole sur un plateau (4/5) : on sécurise la base de données
La recette est bientôt terminée !
On avance sur l’installation de Guacamole et on touche au but. Maintenant que le serveur et le client sont installés, on passe à la sécurisation de la base de données. Dans le dernier épisode, on s’occupera de passer à deux facteurs pour l’authentification. Hé oui, la sécurité, c'est très important et pas à prendre à la légère.
Le 14 décembre 2023 à 19h41
6 min
Internet
Internet
Notre dossier sur Guacamole :
- Guacamole sur un plateau (1/5) : on monte un bastion sécurisé
- Guacamole sur un plateau (2/5) : Apache Tomcat et Let’s Encrypt
- Guacamole sur un plateau (3/5) : on écrase nos avocats (serveur et client)
- Guacamole sur un plateau (4/5) : on sécurise la base de données
Sécurisons la connexion à la base de données
Si vous lancez tel quel, vous aurez un beau message d’erreur dans /var/log/tomcat9/catalina.out du genre :
[2023-10-19 20:38:32] [info] 20:38:32.407 [https-openssl-apr-8443-exec-8] ERROR o.a.g.rest.RESTExceptionMapper - Unexpected internal error:
[2023-10-19 20:38:32] [info] ### Error querying database. Cause: java.sql.SQLNonTransientConnectionException: Could not connect to address=(host=localhost)(port=3306)(type=master) : (conn=31) Trying to connect with ssl, but ssl not enabled in the server
[2023-10-19 20:38:32] [info] ### The error may exist in org/apache/guacamole/auth/jdbc/user/UserMapper.xml
[2023-10-19 20:38:32] [info] ### The error may involve org.apache.guacamole.auth.jdbc.user.UserMapper.selectOne
[2023-10-19 20:38:32] [info] ### The error occurred while executing a query
[2023-10-19 20:38:32] [info] ### Cause: java.sql.SQLNonTransientConnectionException: Could not connect to address=(host=localhost)(port=3306)(type=master) : (conn=31) Trying to connect with ssl, but ssl not enabled in the server
Nous voulons une connexion TLS (SSL pour les nostalgiques) entre le serveur Tomcat et MariaDB. Or, par défaut, rien n’est chiffré. Si on va dans mysql, on voit :
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'have_ssl';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| have_ssl | DISABLED |
+---------------+----------+
1 row in set (0.002 sec)
Regardons la documentation Secure Connections Overview - MariaDB Knowledge Base.
Nous commençons par créer un certificat valide assez longtemps (on n’a pas besoin de changer tous les trois mois comme le certificat d’un site web exposé sur internet). Pas la peine de taper dans le grand luxe, un certificat autosigné conviendra très bien. Comme la communication va dans les deux sens, il en faut un pour le serveur, un pour le client.
On commence par se créer sa propre autorité de certification locale. La première étape est de créer une clé privée suffisamment robuste. Notez bien la passphrase pour cette clé privée, elle vous sera utile juste après.
root@r:~# cd /etc/mysql/certificates/ (à créer)
root@r:~# openssl genpkey -algorithm RSA -out ca-key.pem -aes256
On crée ensuite "l’autorité" à qui on fera les différentes demandes, en lui donnant une durée de vie de 2 ans (730 jours). Vous pouvez mettre ce que vous voulez dans les champs qui vous seront proposés à la saisie, cela n’a pas d’importance, à part pour le FQDN où je conseille de mettre le véritable hostname. Ça sera plus important pour les autres certificats servant à la sécurisation de la connexion SQL.
root@r:~# openssl req -x509 -new -nodes -key ca-key.pem -sha256 -out ca-cert.pem -days 730
On crée d’abord deux clés privées, une pour le serveur, une pour le client :
root@r:~# openssl ecparam -genkey -name secp384r1 -out client-key.pem
root@r:~# openssl ecparam -genkey -name secp384r1 -out server-key.pem
On fait deux demandes de certificats à notre autorité locale. Une précaution à prendre pour le paramètre hostname (ou FQDN) : mettez bien localhost, car sinon vous aurez une erreur lors de l’établissement de la connexion ! Évitez de mettre en mot de passe ici, il faudrait alors le renseigner à chaque lancement. Dans une infrastructure critique, on mettrait un secret stocké avec précaution (ailleurs, de préférence).
root@r:~# openssl req -new -key server-key.pem -out server-csr.pem
root@r:~# openssl req -new -key client-key.pem -out client-csr.pem
Et enfin on « émet » les certificats à l’aide de notre CA maison.
root@r:~# openssl x509 -req -in client-csr.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 730 -extensions v3_ca
root@r:~# openssl x509 -req -in server-csr.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 730 -extensions v3_ca
Et voilà !
On ajoute cela dans le fichier principal de configuration de la base de données, /etc/mysql/mariadb.cnf
[mariadb]
tls_version = TLSv1.2,TLSv1.3
ssl_cert =/etc/mysql/certificates/server-cert.pem
ssl_key =/etc/mysql/certificates/server-key.pem
ssl_ca =/etc/mysql/certificates/ca-cert.pem
[client-mariadb]
tls_version = TLSv1.2,TLSv1.3
ssl_cert =/etc/mysql/certificates/client-cert.pem
ssl_key =/etc/mysql/certificates/client-key.pem
ssl_ca =/etc/mysql/certificates/ca-cert.pem
Il faut ajuster les permissions pour le certificat serveur :
chmod og+x /etc/letsencrypt/live /etc/letsencrypt/archive
chown -R root:tomcat /etc/letsencrypt/live/[domaine] /etc/letsencrypt/archive/[domaine]
chmod +s /etc/letsencrypt/live/[domaine] /etc/letsencrypt/archive/[domaine]
Et comme Java fait bien les choses, il va vérifier que l’autorité de certification utilisée est connue par le système (ou plus précisément par le contexte Java qui est distinct de celui du système). Notre CA étant autosignée, elle ne figure donc pas dans la liste des autorités de confiance, et il faut que nous l’ajoutions.
Il faut l’ajouter dans le keystore (= fichier de certificats) utilisé pour ces autorités de certification.
root@r:~# keytool -cacerts -importcert -file ca-cert.pem
Un mot de passe vous sera demandé. Après de longues recherches sur internet, on trouve qu’il s’agit de changeit. Ça n’est pas une blague : il faut vraiment taper c-h-a-n-g-e-i-t (les 8 lettres) !
Arrivés à ce point, redémarrez mysql, et votre connexion sera chiffrée.
root@r:~# systemctl restart mysql
root@r:~# mysql
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'have_ssl';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| have_ssl | YES |
+---------------+----------+
1 row in set (0.002 sec)
Passons au client web
Vous aurez ensuite la chance de pouvoir admirer la mire d’authentification Guacamole, avec le numéro de version tout en bas. L’utilisateur par défaut est guacadmin:guacadmin, qu'il faut changer dès la première connexion.
Pour modifier le mot de passe par défaut, il faut aller dans “Préférences”. Attention : n’allez pas dans “Utilisateurs” (l’écran peut être trompeur).
Guacamole sur un plateau (4/5) : on sécurise la base de données
-
Sécurisons la connexion à la base de données
-
Passons au client web
Commentaires (9)
Vous devez être abonné pour pouvoir commenter.
Déjà abonné ? Se connecter
Abonnez-vousLe 14/12/2023 à 21h44
Je pense que le problème, c'est que le certificat est créé via l'utilisateur root. openssl, lors de la création des clés, génère un fichier avec des droits 600, c'est à dire que seul son propriétaire à les droits de lecture et d'écriture dessus (et encore heureux !).
Ici, les certificats sont générés en tant que root, mais les certificats serveurs sont utilisés par MariaDB. Et généralement (ça va dépendre des distributions) le serveur de base de données utilise un utilisateur / groupe qui lui est propre (mysql souvent).
Il faut donc soit changer le propriétaire du fichier, soit changer le groupe du fichier, et donner les droits appropriés. Ici, un truc comme ceci me parait beaucoup plus adapté :
chown root:mysql /etc/mysql/certificates/server-key.pem
chmod 640 /etc/mysql/certificates/server-key.pem
Le fichier server-key.pem reste la propriété de root, mais appartient au group mysql. On donne ensuite des droits en lecture / écriture pour le propriétaire, et de lecture pour le groupe.
Le 15/12/2023 à 10h52
Il y a le même soucis dans l’article précédent sur le certificat généré pour guacamole lui-même, qui devrait être en lecture pour l’utilisateur tomcat uniquement.
Modifié le 15/12/2023 à 13h29
Mais oui, en tout cas, c'est important de bien sécuriser les clés. C'est d'autant plus important que l'idée des articles est de monter un bastion sécurisé !
Une clé privée (ou une clé de chiffrement symétrique) se doit de n'être accessible que par le minimum de monde. Et surtout pas exécutable :aie:
Le 15/12/2023 à 15h18
root@r:/etc# chown -R tomcat /etc/letsencrypt/archive /etc/letsencrypt/live
Pour le droit exécutable, certbot himself les laisse... Je ne sais pas pourquoi, d'ailleurs.
Modifié le 15/12/2023 à 15h55
À priori, ceci devrait être suffisant:
chmod og+x /etc/letsencrypt/live /etc/letsencrypt/archive
chown -R root:tomcat /etc/letsencrypt/live/[domaine] /etc/letsencrypt/archive/[domaine]
chmod +s /etc/letsencrypt/live/[domaine] /etc/letsencrypt/archive/[domaine]
Le soucis est que contrairement à un apache en configuration standard, tomcat ne doit pas avoir les droits root au lancement et ensuite changer d’utilisateur, mais être directement lancé sous l’utilisateur tomcat. Du coup, impossible pour lui d’accéder au dossier de clés letsencrypt sans qu’on lui en donne explicitement la permission. Ici, on s’assure de ne le faire que pour le domaine qu’il gère.
Le 15/12/2023 à 15h16
Le 15/12/2023 à 21h04
Le 16/12/2023 à 15h04
C'est pas une heure pour répondre ça !! 😂😂
Mais gg à tous.
Le 15/12/2023 à 10h19