Sécuriser les mots de passe jdbc du server.xml d’un Tomcat

Par défaut, les dataSources déclarées dans Tomcat affichent le mot de passe jdbc en clair dans conf/server.xml.

Dans pas mal d’entreprises, le répertoire de tomcat est accessible en lecture à de nombreuses personnes. C’est très pratique pour diagnostiquer, mais pose un problème de sécurité en exposant ce mot de passe.

Voici quelques pistes d’amélioration que j’ai investiguées, en essayant de trouver un équilibre entre les besoins des développeurs et ceux de l’exploitation (oui, ça ressemble à de la démarche devops ;-) ).

Les besoins des dev et des ops

Pour les développeurs, avoir un accès (en lecture seule) sur tout ce qui est installé est vraiment précieux en termes de diagnostic. Cela peut même permettre de faire un copier/coller d’une instance Tomcat de production, pour pouvoir reproduire certains problèmes difficiles.

Pour l’exploitation (ops), il ne faut pas mettre en péril la sécurité du SI (en exposant des mots de passe) pour du « confort » de diagnostic. Et il ne faut pas trop compliquer les procédures d’installation/mise à jour (même si elles sont automatisées, dans le meilleur des cas).

Limiter l’accès au fichier server.xml

C’est la solution la plus évidente, et celle préconisée par Tomcat (Cf https://wiki.apache.org/tomcat/FAQ/Password). Il s’agit simplement de restreindre les droits en lecture sur ce fichier, ou (d’une manière ou d’une autre) le rendre inaccessible au plus grand nombre.

Hélas, je trouve cette solution trop contraignante :

  • Le fichier server.xml contient bien d’autres informations que ce mot de passe. Notamment les différents ports d’écoute, le dimensionnement des pools de connexion etc. On perd donc la visibilité sur tout ça, ce qui est gênant en diagnostic
  • On ne peut pas facilement (en tant que développeur) copier/coller le tomcat complet (sans avoir des messages d’erreur)
  • En tant qu’ops, ce paramétrage de droits fin est une contrainte, surtout s’il faut le refaire à chaque mise à jour

Mettre le mot de passe dans une variable d’environnement

C’est supporté en standard par Tomcat (cf https://tomcat.apache.org/tomcat-7.0-doc/config/index.html), et fonctionnerait bien. Il faudrait (bien sûr) que l’affectation de ces variables soit faite en-dehors des répertoires accessibles à tout le monde.

Mais surtout, dans notre cas, on affiche souvent (en diagnostic) l’ensemble de ces variables d’environnement, ce qui exposerait le mot de passe. Ces variables sont également accessibles en JMX.

Chiffrer le mot de passe

Chiffrer le mot de passe est ce que proposent spontanément la plupart des interlocuteurs. Ce n’est pas extrêmement compliqué à mettre en place. Cf http://blog.alexis-hassler.com/2014/10/tomcat-chiffrer-les-mots-de-passe.html

Oui mais la clé de chiffrement est en dur dans le code… Donc en ayant accès aux .jar, on peut la retrouver.

Alors j’ai codé une classe similaire qui externalise la clé de chiffrement dans un .properties (à placer dans un répertoire inaccessible).

J’étais tout fier, ça fonctionnait bien.

Oui, mais, dans ce cas, pourquoi s’embêter à faire du chiffrement ? Quitte à mettre des choses secrètes dans un fichier non accessible, autant y mettre directement le mot de passe, non ? (cela éviterait les étapes de chiffrement/déchiffrement : à l’exécution, mais surtout à l’installation pour les ops)

Externaliser le mot de passe via XML Entities

En lisant de plus près https://wiki.apache.org/tomcat/FAQ/Password, ils proposent justement d’utiliser les XML Entities pour faire ça. Exemple :

et avec un fichier confjdbc.xml qui contient :

Ca marche bien, mais j’aimerais pouvoir n’externaliser QUE le mot de passe. Pour que les développeurs aient toujours accès aux autres paramétrages de la datasource (taille du pool de connexion etc). Et apparemment ce n’est pas possible de cette manière.

Externaliser le mot de passe via Properties Replacement

En partant de la dernière suggestion de https://wiki.apache.org/tomcat/FAQ/Password (décidément, je n’ai rien inventé…), on peut utiliser des « Properties Replacement » dans le serveur XML (variables du type ${variable}).

Par défaut, les valeurs sont lues dans conf/catalina.properties, mais on peut modifier cela pour les faire lire dans un fichier externalisé (ce n’est apparemment valable qu’à partir de la version 7 de Tomcat)

En créant un classe implémentant PropertySource, on peut faire lire les propriétés où on veut. Ce que j’ai codé, c’est de les lire dans un fichier externalisé, dont l’emplacement est aussi spécifié dans conf/catalina.properties.

Dans conf/server.xml, on met :

On crée un fichier externalproperties.properties :

Et on indique l’emplacement de ce fichier dans conf/catalina.properties :

Dans le répertoire lib de Tomcat, il faut placer le jar tomcat-tools-x.x.jar (à télécharger sur https://github.com/mossroy/tomcat-tools/releases). Le code source est sur GitHub : https://github.com/mossroy/tomcat-tools (petit projet Maven avec son test unitaire).

 

Au final, c’est cette méthode qui a été retenue, mais le choix dépend évidemment du contexte.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *