guest@6admin.io:~$

MySQL : perte des identifiants

Le scénario: un serveur que vous n’avez pas touché depuis six mois, un MySQL dont personne ne se souvient du mot de passe root et un client qui demande pourquoi son site ne se connecte plus à la base. Le mot de passe root est perdu et il n’y a pas de fichier de config qui le traîne quelque part.

La procédure

# 1. Arrêter MySQL
/etc/init.d/mysql stop

# 2. Démarrer sans les tables de privilèges
mysqld_safe --skip-grant-tables --skip-networking &

# 3. Se connecter sans mot de passe
mysql -u root mysql

# 4. Changer le mot de passe root
UPDATE user SET Password=PASSWORD('nouveaumdp') WHERE User='root';
FLUSH PRIVILEGES;
EXIT;

# 5. Tuer mysqld_safe et redémarrer proprement
killall mysqld_safe mysqld
/etc/init.d/mysql start

Le flag --skip-grant-tables désactive TOUTE authentification: n’importe qui peut se connecter en n’importe qui. Le flag --skip-networking empêche les connexions TCP externes pendant la fenêtre de récupération (seul le socket local fonctionne). Les deux ensemble sont la procédure sûre.

La vérification

mysql -u root -p'nouveaumdp' -e "SELECT User, Host FROM mysql.user;"

Si ça répond, le root est récupéré. Il reste à vérifier les autres utilisateurs (ils n’ont pas été touchés par la procédure, seuls le root a été modifié).

Root récupéré

La procédure nécessite un accès shell au serveur. Si vous n’avez pas d’accès shell, vous n’avez pas de récupération MySQL, vous avez une réinstallation. C’est pour ça que le mot de passe root MySQL doit être stocké dans un gestionnaire de secrets ou à défaut dans un fichier root-only (chmod 600) sur le serveur lui-même.

Le --skip-networking est essentiel: sans lui, la fenêtre de récupération (où tout le monde est root sans mot de passe) est ouverte au réseau. Le kernel ne le dira pas, le MySQL non plus et l’attaquant qui scanne le port 3306 pendant les 30 secondes de la fenêtre a le root.

[edit: 2026] La procédure n’a pas changé depuis 2008. MariaDB l’a copiée telle quelle. Le nom de la colonne Password est devenu authentication_string dans MySQL 5.7+, mais le principe du --skip-grant-tables reste le même et reste aussi dangereux sans --skip-networking.

[edit: 2026] L’implémentation Ansible de tout ceci: le rôle mariadb .