Meilleures pratiques pour le renforcement des configurations de sécurité du serveur MySQL
MySQL est une pierre angulaire pour d'innombrables applications, alimentant tout, des petits blogs aux énormes systèmes d'entreprise. Sa popularité, bien qu'un témoignage de sa robustesse et de sa flexibilité, en fait également une cible fréquente pour les acteurs malveillants. Un serveur MySQL mal configuré ou non renforcé peut constituer une vulnérabilité importante, exposant des données sensibles et offrant une passerelle d'accès non autorisé à l'ensemble de votre infrastructure. La protection de votre déploiement MySQL n'est pas une tâche unique, mais un engagement continu nécessitant vigilance et respect des meilleures pratiques de sécurité.
Cet article fournit un guide complet sur les conseils de configuration essentiels et les mesures de renforcement de la sécurité. Nous aborderons diverses couches de sécurité, de la gestion des utilisateurs et de la protection du réseau aux ajustements des fichiers de configuration et aux considérations relatives au système d'exploitation. En mettant en œuvre ces recommandations, vous pouvez considérablement réduire la surface d'attaque de votre serveur MySQL et construire un environnement de base de données plus résilient contre les vulnérabilités courantes et les tentatives d'accès non autorisé.
1. Gestion des utilisateurs et des accès : Le principe du moindre privilège
Une gestion efficace des utilisateurs est fondamentale pour la sécurité de MySQL. Il est primordial d'accorder aux utilisateurs uniquement les autorisations dont ils ont absolument besoin.
Créer des utilisateurs spécifiques pour des applications spécifiques
Évitez d'utiliser l'utilisateur root pour les connexions d'applications. Créez plutôt des utilisateurs dédiés avec des autorisations granulaires.
CREATE USER 'mon_utilisateur_app'@'localhost' IDENTIFIED BY 'MotDePasseFort123!';
GRANT SELECT, INSERT, UPDATE, DELETE ON `votre_base_de_donnees`.* TO 'mon_utilisateur_app'@'localhost';
FLUSH PRIVILEGES;
Imposer des mots de passe forts
Des mots de passe forts et uniques sont votre première ligne de défense. Utilisez le plugin de validation de mot de passe intégré de MySQL si disponible.
- Complexité : Mélangez majuscules, minuscules, chiffres et symboles.
- Longueur : Visez au moins 12 à 16 caractères.
- Unicité : Ne réutilisez jamais les mots de passe.
- Rotation : Mettez en place une politique de changement régulier des mots de passe.
Vous pouvez activer le composant validate_password (MySQL 8.0+) ou le plugin (MySQL 5.7+) :
INSTALL COMPONENT 'file://component_validate_password';
-- OU pour les anciennes versions
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
-- Configurer la politique de force (par exemple, MEDIUM pour 8+ caractères, majuscules/minuscules, chiffres, spéciaux)
SET GLOBAL validate_password.policy = MEDIUM;
SET GLOBAL validate_password.length = 12;
Supprimer les utilisateurs par défaut et inutilisés
MySQL est livré avec des utilisateurs par défaut (par exemple, root@localhost). Bien que root@localhost soit nécessaire, assurez-vous qu'il possède un mot de passe fort. Critiquement, supprimez ou sécurisez d'autres utilisateurs par défaut comme mysql.session, mysql.sys, et l'utilisateur anonyme s'ils ne sont pas explicitement nécessaires et correctement configurés.
-- Pour identifier les utilisateurs anonymes :
SELECT user, host FROM mysql.user WHERE user = '';
-- Pour supprimer un utilisateur anonyme (s'il est trouvé) :
DROP USER ''@'localhost';
-- Pour supprimer les bases de données de test (si elles existent) :
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%';
FLUSH PRIVILEGES;
Restreindre l'accès hôte
Limitez les comptes utilisateurs à ne se connecter qu'à partir d'adresses IP ou de noms d'hôtes spécifiques. Évitez d'utiliser % comme caractère générique pour l'hôte, sauf si absolument nécessaire et couplé à d'autres contrôles de sécurité solides.
-- L'utilisateur ne peut se connecter que depuis localhost
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'UnAutreMotDePasseFort!';
-- L'utilisateur ne peut se connecter que depuis une adresse IP spécifique
CREATE USER 'utilisateur_sauvegarde'@'192.168.1.100' IDENTIFIED BY 'MotDePasseSauvegarde!';
Soyez prudent avec GRANT OPTION
La clause WITH GRANT OPTION permet à un utilisateur d'accorder ses propres privilèges à d'autres utilisateurs. Cela peut constituer un risque de sécurité important s'il est accordé à des utilisateurs non fiables. Utilisez-le avec parcimonie et uniquement pour les comptes administratifs qui nécessitent réellement cette capacité.
-- Un utilisateur ayant la capacité d'accorder des privilèges (à utiliser avec une extrême prudence)
GRANT ALL PRIVILEGES ON *.* TO 'superadmin'@'localhost' IDENTIFIED BY 'MotDePasseSuperAdmin!' WITH GRANT OPTION;
2. Sécurité réseau : Isolation de votre base de données
Les contrôles au niveau du réseau sont essentiels pour empêcher l'accès externe non autorisé à votre serveur MySQL.
Configurer les pare-feux
Autorisez les connexions au port par défaut de MySQL (3306) uniquement à partir d'adresses IP ou de réseaux de confiance. Bloquez toutes les autres connexions entrantes vers ce port.
Exemple (UFW sur Linux) :
sudo ufw enable
sudo ufw allow from 192.168.1.0/24 to any port 3306
sudo ufw deny 3306
sudo ufw status
Exemple (CentOS/RHEL avec firewalld) :
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept'
sudo firewall-cmd --permanent --remove-port=3306/tcp --zone=public # S'assurer qu'il n'est pas ouvert globalement
sudo firewall-cmd --reload
Sécuriser les connexions avec SSL/TLS
Chiffrez tout le trafic entre les clients et le serveur MySQL à l'aide de SSL/TLS pour empêcher l'écoute clandestine et les attaques de type Man-in-the-Middle (MitM). Ceci est particulièrement crucial pour les connexions sur des réseaux non fiables.
Pour activer SSL/TLS, vous devez généralement générer des certificats et des clés SSL, puis configurer votre my.cnf :
# my.cnf
[mysqld]
ssl_ca=/etc/mysql/certs/ca.pem
ssl_cert=/etc/mysql/certs/server-cert.pem
ssl_key=/etc/mysql/certs/server-key.pem
Les clients doivent ensuite être configurés pour se connecter à l'aide de SSL/TLS, souvent avec REQUIRE SSL dans l'instruction GRANT de l'utilisateur :
CREATE USER 'utilisateur_ssl'@'%' IDENTIFIED BY 'MotDePasseUtilisateurSSL!';
GRANT SELECT ON `votre_base_de_donnees`.* TO 'utilisateur_ssl'@'%' REQUIRE SSL;
FLUSH PRIVILEGES;
Lier à des adresses IP spécifiques
Par défaut, MySQL peut écouter sur toutes les interfaces réseau disponibles (0.0.0.0). Limitez-le à écouter uniquement sur les interfaces qui doivent accepter les connexions (par exemple, localhost pour les applications locales, ou une IP de réseau privé pour les connexions internes).
# my.cnf
[mysqld]
bind-address = 127.0.0.1 # Pour les connexions locales uniquement
# OU
bind-address = 192.168.1.10 # Pour une IP interne spécifique
Astuce : Si votre application et votre serveur MySQL se trouvent sur la même machine,
bind-address = 127.0.0.1(localhost) est l'option la plus sûre, car elle empêche toute connexion externe.
3. Durcissement du fichier de configuration (my.cnf / my.ini)
Le fichier de configuration de MySQL (my.cnf sous Linux, my.ini sous Windows) offre de nombreux paramètres pour améliorer la sécurité.
Désactiver les fonctionnalités inutilisées
Minimisez la surface d'attaque en désactivant les fonctionnalités non requises pour votre déploiement.
local_infile = 0: Empêche les clients de demander au serveur de charger des données à partir de fichiers arbitraires sur l'hôte du serveur. C'est un vecteur courant d'exfiltration de données.
ini [mysqld] local_infile = 0skip-networking: Si votre base de données n'est accessible que par des applications sur le même serveur, désactivez complètement le réseau. Cela force toutes les connexions à utiliser le socket Unix ou les pipes nommés.
ini [mysqld] skip-networkingsymbolic-links = 0: Empêche l'utilisation de liens symboliques pour les tables de base de données, qui peuvent être exploités pour accéder à des fichiers en dehors du répertoire de données MySQL.
ini [mysqld] symbolic-links = 0secure_file_priv: Restreint les répertoires à partir desquels les fichiers peuvent être lus et écrits par des fonctions telles queLOAD DATA INFILEetSELECT ... INTO OUTFILE.
```ini
[mysqld]
secure_file_priv = "/var/lib/mysql-files" # Définir sur un répertoire spécifique et restreint
# OU
# secure_file_priv = "