Chapitre 515 minIntermédiaire
MariaDB sur Debian 13 : installer, sécuriser et créer les comptes
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- installer MariaDB et expliquer l'authentification de root par socket ;
- sécuriser une installation neuve ;
- créer la base et le compte limité d'une application ;
- ouvrir un accès réseau chiffré et restreint à une adresse ;
- sauvegarder, restaurer et dépanner une connexion.
3 exercices corrigés
MariaDB est un système de gestion de bases de données relationnelles (SGBD) libre, issu de MySQL et compatible avec lui : c'est le SGBD que Debian installe quand une application demande « MySQL ». GLPI, Zabbix, Nextcloud ou WordPress y rangent leurs données. Ce chapitre installe MariaDB 11.8 sur Debian 13, sécurise le compte root, crée la base et le compte d'une application selon le principe du moindre privilège, ouvre un accès réseau chiffré pour un outil de tableaux de bord, puis montre comment sauvegarder et dépanner.
Installer MariaDB 11.8
Sur srv-glpi, qui accueillera la base de GLPI :
sudo apt install mariadb-server
systemctl status mariadb --no-pager
mariadb --version
# mariadb from 11.8.x-MariaDB, client 15.2 for debian-linux-gnu (x86_64) …
MariaDB 11.8 est une version maintenue à long terme (LTS) par la fondation MariaDB. Les commandes portent le nom mariadb (mariadb, mariadb-dump, mariadb-admin) ; les anciens noms en mysql ne sont plus que des alias de compatibilité, à ne plus utiliser dans tes scripts. Le langage SQL et les commandes CREATE USER ou GRANT sont ceux du cours SQL, écrit pour MySQL : un encadré y signale les rares différences avec MariaDB.
| Chemin | Rôle |
|---|---|
/etc/mysql/mariadb.conf.d/50-server.cnf | Configuration du serveur : adresse d'écoute (bind-address = 127.0.0.1) |
/etc/mysql/mariadb.conf.d/ | Les fichiers sont lus par ordre alphabétique ; un fichier 60-… que tu ajoutes l'emporte sur 50-server.cnf |
/var/lib/mysql/ | Les données (un dossier par base), propriété du compte système mysql |
/run/mysqld/mysqld.sock | Le socket Unix des connexions locales |
journalctl -u mariadb | Le journal d'erreurs du serveur |
Par défaut, Debian fait écouter MariaDB sur 127.0.0.1 seulement, port TCP 3306 : la base n'est joignable que depuis la machine elle-même. C'est le bon réglage tant qu'aucune autre machine n'en a besoin.
ss -tlnp | grep 3306
# LISTEN 0 80 127.0.0.1:3306 0.0.0.0:* users:(("mariadbd",pid=1027,fd=21))
Se connecter en root sans mot de passe
sudo mariadb
Aucun mot de passe n'est demandé, et c'est voulu. Sous Debian, le compte root@localhost de MariaDB utilise l'authentification par socket Unix (unix_socket) : MariaDB demande au système quel utilisateur Linux est à l'autre bout du socket, et n'accepte root que si c'est le root du système. Personne ne peut donc se connecter en root à la base sans être déjà administrateur du serveur, et il n'existe aucun mot de passe de root à voler, à oublier ou à écrire dans un script.
SELECT User, Host, plugin FROM mysql.user;
+-------------+-----------+-----------------------+
| User | Host | plugin |
+-------------+-----------+-----------------------+
| mariadb.sys | localhost | mysql_native_password |
| root | localhost | mysql_native_password |
| mysql | localhost | mysql_native_password |
+-------------+-----------+-----------------------+
La colonne plugin de la vue mysql.user est trompeuse : interroge plutôt SHOW GRANTS FOR 'root'@'localhost';, qui affiche IDENTIFIED VIA mysql_native_password USING 'invalid' OR unix_socket. Le mot de passe invalid ne correspond à aucun mot de passe possible : seule l'authentification par socket fonctionne. Le compte mysql@localhost a le même fonctionnement, pour le compte système mysql ; mariadb.sys est un compte interne verrouillé.
Sécuriser l'installation
Le script mariadb-secure-installation passe en revue les réglages dangereux d'une installation neuve :
sudo mariadb-secure-installation
| Question | Réponse | Pourquoi |
|---|---|---|
Enter current password for root (enter for none) | Entrée | root n'a pas de mot de passe utilisable |
Switch to unix_socket authentication | n | C'est déjà le cas sous Debian (le script l'indique : you already have your root account protected) |
Change the root password? | n | Garder l'authentification par socket seule |
Remove anonymous users? | Y | Un compte sans nom permettrait à n'importe qui de se connecter |
Disallow root login remotely? | Y | root ne doit jamais se connecter par le réseau |
Remove test database and access to it? | Y | La base test est accessible à tous les comptes |
Reload privilege tables now? | Y | Appliquer tout de suite |
Sur une Debian neuve, plusieurs de ces points sont déjà réglés ; le script ne fait alors rien de plus. Lance-le quand même : c'est un geste qu'on attend de toi en recette, et il te protège si quelqu'un a modifié les comptes avant toi.
Créer la base et le compte d'une application
Chaque application a sa base et son compte, qui n'a de droits que sur cette base. Pour GLPI :
-- sudo mariadb
CREATE DATABASE glpi CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'glpi'@'localhost' IDENTIFIED BY 'Mot-De-Passe-Long-Et-Unique';
GRANT ALL PRIVILEGES ON glpi.* TO 'glpi'@'localhost';
-- GLPI lit les fuseaux horaires dans la base système
GRANT SELECT ON mysql.time_zone_name TO 'glpi'@'localhost';
utf8mb4 est le vrai UTF-8 de MariaDB : il stocke tous les caractères, émojis compris, contrairement à l'ancien utf8. Le compte est déclaré @'localhost' : il ne peut se connecter que depuis la machine, par le socket. GRANT ALL PRIVILEGES ON glpi.* lui donne tous les droits sur la base glpi seulement, dont la création et la modification de tables, dont GLPI a besoin pour s'installer et se mettre à jour. Il n'a aucun droit sur les autres bases, ni sur la gestion des comptes (GRANT OPTION), ni sur les fichiers du serveur (FILE).
Vérifie :
mariadb -u glpi -p -e "SHOW GRANTS;"
Le mot de passe du compte applicatif se génère, il ne s'invente pas :
openssl rand -base64 24
Il est écrit une seule fois, dans le fichier de configuration de l'application, lisible seulement par le compte qui l'exécute, et rangé dans le gestionnaire de mots de passe de l'équipe.
Donner le moins de droits possible
ALL PRIVILEGES sur sa base convient à une application qui gère elle-même son schéma. Pour les autres usages, on donne seulement ce qu'il faut :
| Usage | Droits | Exemple |
|---|---|---|
| Application qui gère son schéma (installation, mises à jour) | ALL PRIVILEGES ON base.* | GLPI, Zabbix |
| Application dont le schéma est créé par l'administrateur | SELECT, INSERT, UPDATE, DELETE ON base.* | Une application métier développée en interne |
| Lecture pour des tableaux de bord | SELECT sur les seules tables ou vues utiles | Grafana qui lit les statistiques des tickets |
| Sauvegarde logique | SELECT, SHOW VIEW, TRIGGER, LOCK TABLES, EVENT sur les bases sauvegardées | Un compte de sauvegarde (ou root par socket, en local) |
Ouvrir un accès réseau, chiffré et restreint
L'équipe veut afficher dans Grafana, sur srv-journaux (192.168.10.180), le nombre de tickets ouverts par catégorie, lu directement dans la base de GLPI. Trois choses changent : MariaDB doit écouter sur le réseau, un compte doit exister pour cette adresse, et la connexion doit être chiffrée.
1. L'adresse d'écoute. Crée /etc/mysql/mariadb.conf.d/60-sorbier.cnf plutôt que de modifier le fichier de Debian, que les mises à jour peuvent remplacer :
[mariadbd]
bind-address = 192.168.10.184
require_secure_transport = ON
require_secure_transport refuse toute connexion TCP qui n'est pas chiffrée en TLS ; les connexions locales par le socket restent possibles. Depuis la version 11.4, MariaDB active TLS sans configuration : s'il n'a pas de certificat, il en génère un autosigné au démarrage, et le client vérifie par défaut le certificat du serveur, à l'aide du mot de passe du compte (pour les méthodes d'authentification qui le permettent, comme mysql_native_password ou ed25519). Pour un service en production, installe plutôt un certificat signé par l'autorité interne (ssl_cert, ssl_key, ssl_ca dans la même section), obtenu comme au chapitre 6.
sudo systemctl restart mariadb
ss -tlnp | grep 3306
# LISTEN 0 80 192.168.10.184:3306 0.0.0.0:* users:(("mariadbd",…))
2. Le compte, lié à l'adresse du client, avec les seuls droits utiles.
CREATE USER 'grafana_lecture'@'192.168.10.180'
IDENTIFIED BY 'Autre-Mot-De-Passe-Long' REQUIRE SSL;
GRANT SELECT ON glpi.glpi_tickets TO 'grafana_lecture'@'192.168.10.180';
GRANT SELECT ON glpi.glpi_itilcategories TO 'grafana_lecture'@'192.168.10.180';
GRANT SELECT ON glpi.glpi_entities TO 'grafana_lecture'@'192.168.10.180';
Le compte ne peut se connecter que depuis srv-journaux, en TLS, et ne lit que trois tables. Il ne voit pas la table glpi_users, qui contient les empreintes des mots de passe des comptes locaux de GLPI. Un GRANT SELECT ON glpi.* aurait été plus simple, et beaucoup trop large.
3. Le pare-feu local n'accepte le port 3306 que de cette adresse (le pare-feu nftables est configuré au chapitre 13) :
ip saddr 192.168.10.180 tcp dport 3306 accept
Le test, depuis srv-journaux :
mariadb -h srv-glpi.ad.sorbier.example -u grafana_lecture -p glpi \
-e "SELECT COUNT(*) FROM glpi_tickets WHERE status < 5;"
mariadb -h srv-glpi.ad.sorbier.example -u grafana_lecture -p -e "\s" | grep -i ssl
# SSL: Cipher in use is TLS_AES_256_GCM_SHA384
Les deux serveurs sont dans le même VLAN : ce flux ne traverse pas le pare-feu pfSense, et le filtrage local de srv-glpi est la seule barrière entre eux. Ne l'oublie pas.
Sauvegarder et restaurer une base
mariadb-dump produit une sauvegarde logique : un fichier SQL qui recrée les tables et leurs données. Pour une base InnoDB comme celle de GLPI, l'option --single-transaction prend une image cohérente de la base sans bloquer l'application.
sudo mariadb-dump --single-transaction --routines --triggers --events glpi \
| gzip > /var/backups/glpi-$(date +%F).sql.gz
La restauration se fait dans une base vide :
sudo mariadb -e "CREATE DATABASE glpi_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
gunzip -c /var/backups/glpi-2026-10-21.sql.gz | sudo mariadb glpi_test
Restaurer dans une base de test, et non dans la base de production, permet de vérifier la sauvegarde sans rien risquer : une sauvegarde qu'on n'a jamais restaurée n'est qu'un espoir. Pour une grosse base, mariadb-backup fait une sauvegarde physique (une copie des fichiers de données, cohérente), plus rapide à restaurer. La planification, la rétention, la copie hors du serveur et le test de restauration sont l'objet du cours Sauvegarde, PCA et PRA ; le chapitre 9 envoie ces fichiers sur un partage NFS.
Dépanner une connexion
| Message | Cause | Correction |
|---|---|---|
Access denied for user 'glpi'@'localhost' (using password: YES) | Mauvais mot de passe, ou le compte n'existe pas pour cet hôte | Vérifier avec SELECT User, Host FROM mysql.user; ; changer le mot de passe avec ALTER USER |
Can't connect to server on 'srv-glpi.ad.sorbier.example' (111) | Rien n'écoute sur cette adresse : bind-address est resté à 127.0.0.1 | Fichier 60-sorbier.cnf, puis systemctl restart mariadb et ss -tlnp |
| Délai dépassé, sans réponse | Un pare-feu bloque le port 3306 | nft list ruleset sur le serveur, règles du pare-feu central |
Host '192.168.10.180' is not allowed to connect to this MariaDB server | Le serveur répond, mais aucun compte ne correspond à l'adresse du client | Créer le compte pour cette adresse ; ne jamais « corriger » avec '%' |
Connections using insecure transport are prohibited while --require_secure_transport=ON | Le client a désactivé TLS | Retirer l'option --skip-ssl ou --disable-ssl du client |
Too many connections | L'application ouvre plus de connexions que max_connections (151 par défaut) | Chercher la fuite de connexions dans l'application ; augmenter la limite en dernier recours |
sudo mariadb-admin status
# Uptime: 86400 Threads: 3 Questions: 51234 Slow queries: 0 Opens: 312 …
sudo mariadb -e "SHOW PROCESSLIST;"
Exercices
Exercice 1 sur 3 Les comptes de Zabbix Réussi À revoir
L'équipe installe Zabbix sur srv-journaux avec sa base MariaDB locale, et veut aussi qu'un script de rapport, lancé sur le poste d'administration 192.168.10.209, puisse lire la table hosts de cette base. Écris les instructions SQL pour créer la base zabbix et les deux comptes, et précise les réglages du serveur MariaDB nécessaires pour le second.
Voir la réponseMasquer la réponse de l'exercice 1
CREATE DATABASE zabbix CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
CREATE USER 'zabbix'@'localhost' IDENTIFIED BY 'Mot-De-Passe-Genere-1';
GRANT ALL PRIVILEGES ON zabbix.* TO 'zabbix'@'localhost';
CREATE USER 'rapport'@'192.168.10.209' IDENTIFIED BY 'Mot-De-Passe-Genere-2' REQUIRE SSL;
GRANT SELECT ON zabbix.hosts TO 'rapport'@'192.168.10.209';
Le serveur Zabbix se connecte en local : son compte est lié à localhost et a tous les droits sur sa base, qu'il crée et met à jour. Le compte de rapport est lié à l'adresse du poste d'administration, chiffré, et limité à SELECT sur une table. Côté serveur : bind-address = 192.168.10.180 (et require_secure_transport = ON) dans un fichier 60-….cnf, un redémarrage de MariaDB, une règle du pare-feu local qui n'accepte le port 3306 que de 192.168.10.209, et la règle correspondante sur le pare-feu pfSense, puisque ce flux va du VLAN 99 au VLAN 20. La documentation de Zabbix demande l'interclassement utf8mb4_bin, sensible à la casse.
Tu avais trouvé ?
Exercice 2 sur 3 Trois erreurs de connexion Réussi À revoir
Depuis srv-journaux, la commande mariadb -h srv-glpi.ad.sorbier.example -u grafana_lecture -p donne successivement trois messages, après chaque correction. Pour chacun, donne la cause et la correction.
ERROR 2002 (HY000): Can't connect to server on 'srv-glpi.ad.sorbier.example' (111)ERROR 1130 (HY000): Host '192.168.10.180' is not allowed to connect to this MariaDB serverERROR 1045 (28000): Access denied for user 'grafana_lecture'@'192.168.10.180' (using password: YES)
Voir la réponseMasquer la réponse de l'exercice 2
- Connexion refusée (code 111) : la machine répond, mais rien n'écoute sur
192.168.10.184:3306. MariaDB écoute encore sur127.0.0.1. Correction :bind-address = 192.168.10.184dans60-sorbier.cnf, redémarrage, vérification avecss -tlnp. - Le serveur répond, mais aucun compte n'existe pour cette adresse. Le compte a peut-être été créé pour
localhostou pour une autre adresse. Correction :CREATE USER 'grafana_lecture'@'192.168.10.180' …(ouRENAME USERsi l'hôte était faux). - Le compte existe pour cette adresse, mais le mot de passe est faux. Correction :
ALTER USER 'grafana_lecture'@'192.168.10.180' IDENTIFIED BY '…';puis mettre le même mot de passe dans la source de données de Grafana.
L'ordre des messages suit le chemin de la connexion : le réseau et l'écoute, puis l'hôte du compte, puis le mot de passe.
Tu avais trouvé ?
Exercice 3 sur 3 Restaurer sans casser Réussi À revoir
Un technicien a supprimé par erreur une catégorie de tickets dans GLPI ce matin. La sauvegarde de la nuit est /var/backups/glpi-2026-10-21.sql.gz. Pourquoi ne faut-il pas la restaurer directement dans la base glpi ? Décris la démarche.
Voir la réponseMasquer la réponse de l'exercice 3
Restaurer la sauvegarde de la nuit dans glpi écraserait tout le travail de la journée : tickets créés, suivis, interventions. Une erreur sur une ligne ne justifie pas de perdre des heures de données.
Démarche : restaurer la sauvegarde dans une base temporaire (CREATE DATABASE glpi_restau … puis gunzip -c … | sudo mariadb glpi_restau), retrouver la ligne supprimée (SELECT * FROM glpi_restau.glpi_itilcategories WHERE …), puis la recréer dans la base de production, de préférence depuis l'interface de GLPI ou avec un INSERT … SELECT vérifié, enfin supprimer la base temporaire. On note l'incident et on se demande s'il faut retirer ce droit de suppression au profil du technicien.
Tu avais trouvé ?