CyberSDF

Reprenez la main sur votre numérique

Access denied for user ‘root’@’localhost’ : le socket, pas le mot de passe

une machine de bureau ouverte posee sur un etabli, cables ranges, tournevis pose a plat

La commande mariadb -u root renvoie ERROR 1698 (28000): Access denied for user 'root'@'localhost' sur une installation neuve de MariaDB 10.11, celle des paquets mariadb-server 1:10.11.18-0+deb12u1 sous Debian 12 et 1:10.11.13-0ubuntu0.24.04.1 sous Ubuntu 24.04. Le compte root@localhost ne possède aucun mot de passe à saisir : depuis MariaDB 10.4, il est créé avec le plugin unix_socket, qui authentifie l’utilisateur Unix propriétaire du processus connecté au socket /run/mysqld/mysqld.sock. sudo mariadb ouvre la session que mariadb -u root refuse.

Sommaire
  1. 1. Le compte root@localhost s’authentifie par le socket Unix, jamais par un mot de passe
  2. 2. SHOW CREATE USER affiche unix_socket OR mysql_native_password USING ‘invalid’
  3. 3. Un compte nominatif à mot de passe remplace root pour les scripts et les applications
  4. 4. Ajouter un mot de passe à root passe par IDENTIFIED VIA unix_socket OR mysql_native_password
  5. auth_socket n’est pas un plugin MariaDB : ERROR 1524 (HY000): Plugin ‘auth_socket’ is not loaded
  6. 1698 quand aucun mot de passe n’est envoyé, 1045 quand il y en a un
  7. Le socket Unix ne traverse pas le réseau : -h 127.0.0.1 échoue même sous sudo
  8. Le partage est net : le socket pour l’humain, un compte nominatif pour les programmes

1. Le compte root@localhost s’authentifie par le socket Unix, jamais par un mot de passe

Le plugin unix_socket lit l’identité du processus avec l’appel système getsockopt et l’option SO_PEERCRED, récupère son uid, puis accepte le compte MariaDB qui porte le nom de l’utilisateur système correspondant. Seul le compte Unix root peut donc ouvrir root@localhost, et il n’a rien à taper. Toute autre session échoue, même avec le bon mot de passe, car le plugin ignore la chaîne d’authentification.

mariadb -u root
sudo mariadb

La seconde ligne change d’utilisateur avant de lancer le client : le socket présente alors l’uid 0 et l’authentification aboutit. Le service se surveille comme n’importe quelle unité systemd, avec systemctl status mariadb et ses journaux, détaillés dans services et journaux systemd.

Ce que vous devez voir : l’échec ERROR 1698 (28000): Access denied for user 'root'@'localhost' en premier, puis Welcome to the MariaDB monitor. suivi de l’invite MariaDB [(none)]> après sudo mariadb.

2. SHOW CREATE USER affiche unix_socket OR mysql_native_password USING ‘invalid’

Depuis MariaDB 10.4, un même compte peut cumuler plusieurs méthodes d’authentification. Le compte root@localhost créé à l’installation reçoit unix_socket en premier et mysql_native_password en second, ce dernier portant la chaîne ‘invalid’ à la place d’un hachage de mot de passe, ce qui le neutralise sans le supprimer.

sudo mariadb
SHOW CREATE USER 'root'@'localhost'\G
SHOW PLUGINS;

L’emplacement du socket n’est pas une valeur invisible : le paquet mariadb-common installe /etc/mysql/mariadb.cnf, dont la section [client-server] contient la ligne socket = /run/mysqld/mysqld.sock, aux côtés de /etc/mysql/mariadb.conf.d/ où vit le fichier 50-server.cnf. Ces chemins font partie des repères de l’administration d’un serveur Debian. Le script mariadb-secure-installation, livré par le paquet mariadb-client, s’appuie sur la même sortie : il cherche le mot unix_socket dans le résultat de SHOW CREATE USER root@localhost pour savoir si le compte est déjà protégé.

Ce que vous devez voir : la ligne CREATE USER `root`@`localhost` IDENTIFIED VIA unix_socket OR mysql_native_password USING 'invalid', puis unix_socket en statut ACTIVE dans SHOW PLUGINS.

3. Un compte nominatif à mot de passe remplace root pour les scripts et les applications

Les outils qui ne tournent pas sous l’utilisateur Unix root ne peuvent pas emprunter unix_socket : une tâche cron lancée sous un autre compte, une application PHP servie par www-data ou un client lancé depuis votre session graphique échouent tous de la même façon. La réponse durable consiste à créer un compte nominatif, avec un mot de passe, plutôt qu’à donner un mot de passe à root.

sudo mariadb
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'unMotDePasseLongEtUnique';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION;

Ce compte se connecte par mot de passe, par le socket comme par la boucle locale TCP, et il survit à un changement de politique sur le compte Unix root. Les sauvegardes se lancent ensuite avec mariadb-dump -u admin -p.

Ce que vous devez voir : deux réponses Query OK, 0 rows affected, puis l’invite du moniteur après mariadb -u admin -p et la saisie du mot de passe.

4. Ajouter un mot de passe à root passe par IDENTIFIED VIA unix_socket OR mysql_native_password

Un outil de sauvegarde ou de supervision peut exiger un mot de passe sur le compte root lui-même. La clause OR inscrit les deux méthodes dans le même compte. Depuis MariaDB 10.4.13, une méthode absente de la clause IDENTIFIED VIA est retirée du compte, ce qui explique la majorité des accès perdus après un changement de mot de passe.

sudo mariadb
ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD('unMotDePasseLongEtUnique');
FLUSH PRIVILEGES;

Écrire plutôt ALTER USER 'root'@'localhost' IDENTIFIED BY 'unMotDePasseLongEtUnique'; produit l’effet inverse : la clause ne cite que mysql_native_password, unix_socket quitte le compte, et sudo mariadb échoue à son tour sur ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO). La réparation passe par la connexion devenue valide, mariadb -u root -p, puis par la clause OR.

Ce que vous devez voir : après la commande, SHOW CREATE USER 'root'@'localhost'\G affiche IDENTIFIED VIA unix_socket OR mysql_native_password USING '*..., et les deux entrées fonctionnent : sudo mariadb sans mot de passe, mariadb -u root -p avec.

auth_socket n’est pas un plugin MariaDB : ERROR 1524 (HY000): Plugin ‘auth_socket’ is not loaded

Les procédures écrites pour MySQL 5.7 et MySQL 8.0 nomment un plugin auth_socket, et cette différence de nom suffit à casser la commande. MariaDB ne connaît que unix_socket, alors que le fichier livré par Debian s’appelle auth_socket.so et que INSTALL SONAME 'auth_socket' charge bien le plugin unix_socket. La commande recopiée depuis un tutoriel MySQL produit le message suivant.

ERROR 1524 (HY000): Plugin 'auth_socket' is not loaded
sudo mariadb
ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket;
SHOW CREATE USER 'root'@'localhost'\G

Ce que vous devez voir : l’erreur 1524 disparaît dès que le nom unix_socket est employé, et le compte conserve la clause attendue.

1698 quand aucun mot de passe n’est envoyé, 1045 quand il y en a un

Deux codes se ressemblent et n’ont pas la même cause. ERROR 1698 (28000) est ER_ACCESS_DENIED_NO_PASSWORD_ERROR, le refus sans mot de passe, et il ne porte jamais de suffixe. Le message 1045 est le refus générique et précise toujours si un mot de passe a été transmis, par exemple (using password: NO). Chercher un mot de passe perdu devant un 1698 fait donc perdre du temps : aucune chaîne n’a été envoyée, et aucune chaîne saisie ne sera lue par unix_socket.

ERROR 1698 (28000): Access denied for user 'root'@'localhost'
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

Ce que vous devez voir : un message sans parenthèses finales relève du premier cas, un suffixe entre parenthèses annonce l’autre.

Le socket Unix ne traverse pas le réseau : -h 127.0.0.1 échoue même sous sudo

unix_socket ne fonctionne que sur une connexion arrivée par le fichier de socket. Une connexion TCP, même depuis la machine elle-même, ne présente aucune identité de socket à lire, et le compte root@localhost reste fermé. Un fichier d’options qui imposerait protocol=tcp casse donc le sudo mariadb qui fonctionnait la veille.

mariadb -h 127.0.0.1 -u root
sudo mariadb --protocol=socket

Ce que vous devez voir : le second appel ouvre le moniteur alors que le premier renvoie un refus d’accès, ce qui départage un problème d’authentification d’un problème de transport.

Le partage est net : le socket pour l’humain, un compte nominatif pour les programmes

Faut-il garder sudo mariadb ou créer un compte à mot de passe ?

Les deux, pour des usages différents : sudo mariadb pour l’administration interactive, un compte nominatif pour les sauvegardes, les scripts et les applications. Le socket évite qu’un mot de passe traîne dans un fichier, le compte nominatif évite de faire tourner un service sous root. Une base qui ne garde qu’une seule des deux voies finit par bloquer, soit sur une tâche cron, soit sur un mot de passe oublié.

Comment donner un mot de passe à root sans perdre l’accès sudo ?

Une seule commande, exécutée dans une session ouverte par sudo mariadb : ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD('unMotDePasseLongEtUnique'); La clause OR est indispensable, puisqu’une méthode non citée est retirée du compte depuis MariaDB 10.4.13. Vérifiez ensuite avec SHOW CREATE USER ‘root’@’localhost’\G : les deux méthodes doivent apparaître.

Que se passe-t-il si on exécute ALTER USER root@localhost IDENTIFIED BY ‘…’ ?

La méthode unix_socket quitte le compte et sudo mariadb échoue sur ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: NO). L’accès n’est pas perdu : mariadb -u root -p fonctionne avec le mot de passe qui vient d’être enregistré, et la clause OR rétablit ensuite l’entrée par socket. Les scripts qui comptaient sur une connexion sans mot de passe se réparent en plaçant ce mot de passe dans un groupe [client] du fichier /root/.my.cnf.

Pourquoi une application PHP ou une tâche cron ne se connecte-t-elle pas en root ?

unix_socket authentifie le propriétaire du processus connecté, pas le seul nom du compte : www-data ou l’utilisateur d’une tâche cron ne peuvent jamais passer pour root, même si un mot de passe leur est fourni. Créez un compte dédié avec CREATE USER ‘app’@’localhost’ IDENTIFIED BY ‘…’, puis accordez-lui uniquement la base concernée par un GRANT sur celle-ci. C’est la seule configuration qui résiste à un durcissement du compte root.

Faut-il démarrer le serveur en –skip-grant-tables pour retrouver l’accès ?

L’option ne touche pas aux données, elle ouvre le serveur sans contrôler les privilèges, ce qui suffit à rouvrir une session mais laisse la base ouverte à qui se connecte pendant l’opération. Depuis MariaDB 10.4, l’ordre des étapes a changé : il faut exécuter FLUSH PRIVILEGES pour sortir du mode –skip-grant-tables avant de pouvoir modifier une méthode d’authentification, puis SET PASSWORD FOR root@localhost. À réserver aux cas où ni sudo mariadb ni un compte nominatif ne répondent.

Le passage à MariaDB 11.8 sous Debian 13 change-t-il la règle ?

Non : unix_socket reste installé par défaut et attribué à root@localhost, et le refus 1698 se produit à l’identique. Debian 13 livre mariadb-server 1:11.8.6-0+deb13u1, Debian 12 livre 1:10.11.18-0+deb12u1, Ubuntu 24.04 livre 1:10.11.13-0ubuntu0.24.04.1. Les commandes SHOW CREATE USER et ALTER USER gardent la même syntaxe d’une version à l’autre.

Quelles réponses donner à mariadb-secure-installation sur une installation neuve ?

Lancé avec sudo, le script demande d’abord Enter current password for root (enter for none):, où la touche Entrée suffit tant que root n’a pas de mot de passe. Il lit ensuite SHOW CREATE USER root@localhost, détecte unix_socket et affiche You already have your root account protected, so you can safely answer ‘n’ devant Switch to unix_socket authentication [Y/n]. La seule question qui modifie réellement le compte est Change the root password? : répondre n laisse sudo mariadb comme unique entrée, ce qui suffit dans la plupart des cas.

Sources : documentation du plugin unix_socket, authentification depuis MariaDB 10.4, ALTER USER, erreur 1698, erreur 1524, différences des paquets Debian et Ubuntu, script mariadb-secure-installation de la branche 10.11, contenu des paquets Debian 12, mariadb-server dans Ubuntu 24.04.