Mysql est la base de données Open Source la plus répandue. Cet article vous présente les techniques de base pour sécuriser votre serveur Mysql.
Au lieu du classique login/password, Mysql gère un triplet login/password/source pour authentifier les utilisateurs. Ainsi, un utilisateur peut posséder un mot de passe différent selon son adresse de connection. Lors de son installation, Mysql crée deux comptes administrateurs de login root qui peuvent se connecter depuis localhost ou depuis le nom renvoyé par hostname. Ces comptes sont sans mot de passe. On a donc :
Host | User | Password |
localhost | root | |
christophe.global-secure.fr | root |
[kmaster@p500 kmaster]$ mysql -u root mysql Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 to server version: 3.23.49 Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>Changeons le mot de passe sur le compte root ou plus exactement définissons le :
mysql> SET PASSWORD FOR root@localhost=PASSWORD('new_password'); Query OK, 0 rows affected (0.00 sec) mysql> mysql> exit ByeLe second compte administrateur est lui aussi sans mot de passe et local: il permet une connexion réseau depuis le serveur vers lui-même. Comme il est inutile, supprimons le après s'être reconnecté :
[kmaster@p500 kmaster]$ mysql -u root mysql -p Enter password: Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 to server version: 3.23.49 Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> DELETE FROM user WHERE Host='christophe.global-secure.fr' AND User='root'; Query OK, 1 row affected (0.00 sec)Il faut noter que si on veut que l'administrateur puisse se connecter à distance, il faut que le
Host
du compte indique le nom
ou l'adresse IP de son poste client ou bien le caractère %
pour qu'il puisse se connecter depuis n'importe où.
Des connexions anonymes sont possibles, et des comptes sans mots de
passe existent encore. Il nous faut donc les supprimer de sorte que
seuls les utilisateurs dûment authentifiés puissent se connecter :
mysql> DELETE FROM user WHERE Password=''; Query OK, 2 rows affected (0.00 sec)Mysql a créé une base de test, elle nous est inutile :
mysql> DROP DATABASE test; Query OK, 0 rows affected (0.00 sec)Par défaut, la base test et toutes les bases commençant par "test_" si elles existent sont accessibles à toute personne connectée :
mysql> DELETE FROM db WHERE db='test' OR db='test\_%'; Query OK, 2 rows affected (0.00 sec)Quand Mysql démarre, le contenu des tables de privilèges est chargé en mémoire. Seules les modifications effectuées avec
GRANT
, REVOKE
ou SET PASSWORD
sont prises en compte immédiatement. Les autres
changement comme par exemple un INSERT
ou un UPDATE
nécessite de recharger les tables de privilèges.
Activons donc les modifications :
mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)
Un utilisateur peut avoir des privilèges s'appliquant à la totalité du système de base de données ou bien des privilèges sur certaines bases ou tables de la base. Seuls les comptes administrateurs doivent avoir des droits sur la totalité de la base. De manière générale, ces comptes doivent être réservés aux tâches d'administration :: création/suppression d'utilisateurs, de bases.
Pour créer un compte utilisateur pipo, pouvant se connecter de n'importe où, avec le droit d'effectuer diverses commandes sur la base pipodb (Utiliser CREATE DATABASE pipo pour créer la base), il suffit d'utiliser la commande GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,ALTER,DROP ON pipodb.* TO pipo@"%" IDENTIFIED BY "pwd";
Dans la mesure du possible, je conseille d'utiliser trois comptes par projet : un avec le droit SELECT pour les opérations de lecture, un autre avec les droits supplémentaires INSERT, UPDATE, DELETE pour réaliser les opérations d'écriture, et un dernier ayant aussi les privilèges CREATE, ALTER, DROP pour intervenir sur la structure des tables.
A l'aide de la commande SHOW DATABASES, un utilisateur obtient la liste de toutes les bases de données du serveur.
mysql -u pipo -p Enter password: mysql> show databases; +----------+ | Database | +----------+ | mysql | | pipodb | +----------+
Si on est parano, il est possible de désactiver cette commande, mais il est plus raisonnable de n'autoriser à lister que les bases sur lequel l'utilisateur a des droits. Dans le fichier /etc/my.cnf, section mysqld, ajouter safe-show-database.
mysql -u pipo -p Enter password: mysql> show databases; +----------+ | Database | +----------+ | pipodb | +----------+
Le nombre de connexions est limité par le paramètre max_connections. Par exemple, pour limiter à 100 connexions simultanées, ajouter dans /etc/my.cnf la ligne set-variable = max_connections=100. Pour éviter qu'un utilisateur accapare toutes les connexions, limitons le nombre de connexions par utilisateur: set-variable = max_user_connections =50. Remarque, les paramètres (taille du cache pour les tris par exemple) de mysqld pour augmenter ses performances se spécifient de la même manière
Pour limiter les connexions à une interface, utiliser le paramètre bind-address :
netstat -tlnp Connexions Internet actives (seulement serveurs) Proto Recv-Q Send-Q Adresse locale Adresse distante Etat PID/Program name tcp 0 0 192.168.1.33:3306 0.0.0.0:* LISTEN 2459/mysqld
Mais si aucune connexion depuis le réseau n'est requise, autant supprimer la couche de réseau avec --skip-networking.
Du coté des programmes, il y a généralement peu de chose à modifier pour ne pas utiliser le réseau. En C, le paramètre host de mysql_real_connect doit être remplacé par NULL ou localhost. En PHP, le paramètre host de mysql_connect doit être à vide. En Perl, au lieu de spécifier la source de données (DSN) sous la forme dbi:DriverName:database_name@hostname:port, on omet le nom d'hôte et le port.Pour ceux qui ont besoin de communiquer via le réseau, les communications peuvent être protégées par du SSL. Se reporter à la documentation très complète de Mysql.
Mysql peut fonctionner dans un environnement chrooté, c'est-à-dire déporté dans une partie de l'arborescence. Comme Mysql fonctionne en tant qu'utilisateur, même en cas de faille de sécurité importante, le pirate ne peut pas accéder à la totalité du disque. Il reste cantonné à la nouvelle racine ainsi définie.
Cette configuration demande un peu de travail. Voici les différentes étapes pour chrooter Mysql dans le répertoire /services/chrooted-mysql/.
On commence par créer l'arborescence :
mkdir -p /services/chrooted-mysql/var/lib/ cd /services/chrooted-mysql mkdir -p var/run etc tmp chmod 1777 tmp
puis on y déplace les bases de données :
grep "mysql:" /etc/passwd > etc/passwd mv /var/lib/mysql var/lib/ ln -s /services/chrooted-mysql/var/lib/mysql/ /var/lib/mysql mv /var/run/mysqld var/run ln -s /services/chrooted-mysql/var/run/mysqld/ /var/run/mysqld
Enfin, on ajoute les librairies dont a besoin Mysql pour fonctionner :
ldd /usr/libexec/mysqld libdl.so.2 => /lib/libdl.so.2 (0x4002c000) libpthread.so.0 => /lib/i686/libpthread.so.0 (0x40030000) libz.so.1 => /usr/lib/libz.so.1 (0x40044000) libcrypt.so.1 => /lib/libcrypt.so.1 (0x40052000) libnsl.so.1 => /lib/libnsl.so.1 (0x4007f000) libm.so.6 => /lib/i686/libm.so.6 (0x40094000) libc.so.6 => /lib/i686/libc.so.6 (0x42000000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) mkdir -p lib/i686 usr/lib cp /lib/libdl.so.2 /lib/libcrypt.so.1 /lib/libnsl.so.1 /lib/ld-linux.so.2 lib cp /lib/i686/libpthread.so.0 /lib/i686/libm.so.6 lib/i686/
Il faut aussi rajouter les librairies de résolution de nom :
cp /lib/libnss_compat.so.2 /lib/libnss_files.so.2 lib/
Et voila, il ne reste plus qu'à spécifier la nouvelle racine dans le fichier /etc/my.cnf: chroot=/services/chrooted-mysql.
En cas de perte du mot de passe administrateur, relancer mysqld avec l'option --skip-grant-tables. Aucun mot de passe n'est alors nécessaire, et aucune vérification des droits n'est active. Il ne vous reste plus qu'à changer le mot de passe ou restaurer les paramètres défectueux.
J'espère vous avoir donner un bon aperçu des mécanismes de sécurité de Mysql. Sachez que ce serveur de base de données comporte plus d'une centaine de paramètres qui permettent de l'adapter aux besoins d'une grande variété d'applications. Un bon paramétrage permet d'augmenter de manière étonnante ses performances.