From bc57514c0d23e1be9af32d777096779c2a274be5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9drix?= <cedric@abonnel.fr>
Date: Sun, 23 Mar 2025 17:27:49 +0100
Subject: [PATCH] create scripts 'mdns' and 'set_root_password' edit for secure
 create_db.sh

---
 scripts/common/common_utils.sh               |   2 +-
 scripts/common/setup_mdns.sh                 | 133 +++++++++++
 scripts/server-mariadb/check_mysql_secure.sh | 220 +++++++++++++++++++
 scripts/server-mariadb/create_db.sh          |   6 +
 scripts/server-mariadb/set_root_password.sh  | 112 ++++++++++
 5 files changed, 472 insertions(+), 1 deletion(-)
 create mode 100644 scripts/common/setup_mdns.sh
 create mode 100644 scripts/server-mariadb/check_mysql_secure.sh
 create mode 100644 scripts/server-mariadb/set_root_password.sh

diff --git a/scripts/common/common_utils.sh b/scripts/common/common_utils.sh
index 4fde7a2..3f561b2 100644
--- a/scripts/common/common_utils.sh
+++ b/scripts/common/common_utils.sh
@@ -10,7 +10,7 @@ check_root() {
 }
 
 generate_token() {
-    tr -dc 'A-Za-z0-9@#%+=_-' < /dev/urandom | head -c "${1:-32}"
+    tr -dc 'A-Za-z0-9' < /dev/urandom | head -c "${1:-32}"
     echo
 }
 
diff --git a/scripts/common/setup_mdns.sh b/scripts/common/setup_mdns.sh
new file mode 100644
index 0000000..f2bd8a1
--- /dev/null
+++ b/scripts/common/setup_mdns.sh
@@ -0,0 +1,133 @@
+#!/bin/bash
+# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
+
+# Importer les fonctions communes
+source "$(dirname "$0")/../common/common_utils.sh"
+
+# Vérifier si le script est exécuté en root
+check_root
+
+set -e
+
+echo "=== Détection des interfaces réseau actives ==="
+INTERFACES=$(ip -o link show | awk -F': ' '{print $2}' | grep -Ev 'lo|docker|veth|br|vmnet|virbr')
+echo "Interfaces détectées : $INTERFACES"
+ALLOWED_INTERFACES=$(echo "$INTERFACES" | paste -sd "," -)
+
+echo "=== Installation d'Avahi (mDNS) et des dépendances ==="
+apt update
+apt install -y avahi-daemon avahi-utils libnss-mdns nscd systemd-resolved
+
+echo "=== Vérification de la présence de libnss_mdns.so.2 ==="
+if [[ ! -f /lib/x86_64-linux-gnu/libnss_mdns.so.2 ]]; then
+    echo "❌ libnss_mdns.so.2 manquante, tentative de réinstallation"
+    apt install --reinstall -y libnss-mdns
+fi
+
+echo "=== Configuration de /etc/nsswitch.conf ==="
+if grep -q '^hosts:' /etc/nsswitch.conf; then
+    sed -i 's/^hosts:.*/hosts: files mdns4 dns/' /etc/nsswitch.conf
+else
+    echo "hosts: files mdns4 dns" >> /etc/nsswitch.conf
+fi
+grep hosts /etc/nsswitch.conf
+
+echo "=== Redémarrage des caches DNS si présents ==="
+systemctl restart nscd || echo "nscd non utilisé"
+systemctl restart systemd-resolved || echo "systemd-resolved non utilisé"
+
+echo "=== Vérification d'un éventuel service sur le port 80 ==="
+if ss -tuln | grep -q ':80 '; then
+    echo "❌ Un service écoute déjà sur le port 80. Abandon de la publication HTTP de test."
+    PUBLISH_HTTP=false
+else
+    PUBLISH_HTTP=true
+fi
+
+echo "=== Sauvegarde de la conf avahi ==="
+cp /etc/avahi/avahi-daemon.conf /etc/avahi/avahi-daemon.conf.bak.$(date +%F-%H%M)
+
+echo "=== Génération de la configuration avahi-daemon.conf ==="
+cat > /etc/avahi/avahi-daemon.conf <<EOF
+[server]
+host-name=$(hostname)
+use-ipv4=yes
+use-ipv6=no
+allow-interfaces=$ALLOWED_INTERFACES
+ratelimit-interval-usec=1000000
+ratelimit-burst=10
+
+[wide-area]
+enable-wide-area=no
+
+[publish]
+publish-addresses=yes
+publish-hinfo=yes
+publish-workstation=yes
+publish-domain=yes
+
+[reflector]
+enable-reflector=no
+
+[rlimits]
+rlimit-as=0
+rlimit-core=0
+rlimit-data=4194304
+rlimit-fsize=0
+rlimit-nofile=300
+rlimit-stack=4194304
+EOF
+
+if $PUBLISH_HTTP; then
+    echo "=== Publication temporaire d'un service HTTP de test ==="
+    mkdir -p /etc/avahi/services
+    cat > /etc/avahi/services/test-http.service <<EOF
+<?xml version="1.0" standalone='no'?>
+<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
+<service-group>
+  <name replace-wildcards="yes">Test HTTP on %h</name>
+  <service>
+    <type>_http._tcp</type>
+    <port>80</port>
+  </service>
+</service-group>
+EOF
+fi
+
+echo "=== Activation et redémarrage du service Avahi ==="
+systemctl enable avahi-daemon
+systemctl restart avahi-daemon
+
+echo "=== Vérification du statut du service ==="
+systemctl status avahi-daemon --no-pager || { echo "❌ Avahi ne fonctionne pas."; exit 1; }
+
+echo "=== Vérification du multicast sur l'interface ==="
+ip a | grep MULTICAST || echo "⚠️ Aucune interface multicast détectée"
+
+echo "=== Vérification de l'écoute sur le port UDP 5353 ==="
+ss -uln | grep 5353 || echo "⚠️ Aucun service écoutant sur UDP/5353"
+
+echo "=== Test de la résolution mDNS avec getent (NSS) ==="
+LOCAL_HOST="$(hostname).local"
+if getent hosts "$LOCAL_HOST"; then
+    echo "✅ Résolution mDNS de $LOCAL_HOST réussie via getent"
+else
+    echo "❌ La résolution mDNS de $LOCAL_HOST a échoué via getent"
+    exit 1
+fi
+
+echo "=== Scan des services mDNS disponibles ==="
+avahi-browse -a -t || echo "⚠️ Aucun service mDNS visible (normal si peu de services publiés)"
+
+echo "✅ mDNS opérationnel sur : $ALLOWED_INTERFACES"
+echo "$INTERFACES" > /var/log/mdns_interfaces.log
+echo "Interfaces enregistrées dans /var/log/mdns_interfaces.log"
+
+if $PUBLISH_HTTP; then
+    echo "=== Suppression du service HTTP de test ==="
+    rm -f /etc/avahi/services/test-http.service
+    systemctl restart avahi-daemon
+    echo "✅ Service HTTP de test retiré proprement"
+fi
+
+echo "✅ Script terminé avec succès"
\ No newline at end of file
diff --git a/scripts/server-mariadb/check_mysql_secure.sh b/scripts/server-mariadb/check_mysql_secure.sh
new file mode 100644
index 0000000..30a387b
--- /dev/null
+++ b/scripts/server-mariadb/check_mysql_secure.sh
@@ -0,0 +1,220 @@
+#!/bin/bash
+# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
+
+# Importer les fonctions communes
+source "$(dirname "$0")/../common/common_utils.sh"
+
+# Vérifier si le script est exécuté en root
+check_root
+
+set -euo pipefail
+
+echo "=== Audit Sécurité MariaDB sur $(hostname) ($(date)) ==="
+
+CONFIG_FILE="/etc/mysql/mariadb.conf.d/50-server.cnf"
+ISSUES_FOUND=0
+RESTART_REQUIRED=0
+
+# Vérifier la présence de la commande mysql
+if ! command -v mysql >/dev/null 2>&1; then
+    echo "❌ La commande 'mysql' est introuvable. Veuillez l'installer."
+    exit 1
+fi
+
+get_password_from_cnf() {
+    local file=$1
+    sed -n '/\[client\]/,/^\[/p' "$file" | grep -m1 'password' | sed -E 's/^[ \t]*password[ \t]*=[ \t]*//'
+}
+
+if [[ -f /etc/mysql/debian.cnf ]]; then
+    DB_USER=$(grep -A5 '\[client\]' /etc/mysql/debian.cnf | grep -m1 'user' | awk -F= '{gsub(/ /,"",$2); print $2}')
+    DB_ROOT_PASSWORD=$(get_password_from_cnf "/etc/mysql/debian.cnf" || echo "")
+    DB_ROOT_PASSWORD=$(echo "$DB_ROOT_PASSWORD" | tr -d '\r\n')
+else
+    DB_USER="root"
+    read -rp "🔐 Entrez le mot de passe root pour MariaDB : " -s DB_ROOT_PASSWORD
+    echo
+fi
+
+TEMP_CNF=$(mktemp)
+chmod 600 "$TEMP_CNF"
+cat > "$TEMP_CNF" <<EOF
+[client]
+user=$DB_USER
+password=$DB_ROOT_PASSWORD
+EOF
+
+MYSQL_CMD="mysql --defaults-extra-file=$TEMP_CNF"
+
+echo "🔎 Test de connexion..."
+if ! $MYSQL_CMD -e "SELECT 1;" >/dev/null 2>&1; then
+    echo "❌ Échec de connexion ($DB_USER)"
+    exit 1
+fi
+echo "✅ Connexion $DB_USER réussie"
+
+echo
+
+check_permissions() {
+    echo "Vérification des permissions systèmes..."
+    if [[ $(stat -c "%U %G" /var/lib/mysql) != "mysql mysql" ]]; then
+        echo "❌ /var/lib/mysql n'appartient pas à mysql:mysql"
+        ISSUE=1
+    else
+        echo "✔️ Permissions /var/lib/mysql OK"
+    fi
+
+    if [[ $(stat -c "%U %G" $CONFIG_FILE) != "root root" ]]; then
+        echo "❌ $CONFIG_FILE n'appartient pas à root:root"
+        ISSUE=1
+    else
+        echo "✔️ Permissions du fichier de conf OK"
+    fi
+    echo
+}
+
+check_storage_engines() {
+    echo "🛠 Vérification des moteurs de stockage..."
+    ENABLED=$($MYSQL_CMD -e "SHOW ENGINES;" | awk '$2 ~ /YES|DEFAULT/ {print $1}')
+    for ENGINE in ARCHIVE BLACKHOLE FEDERATED; do
+        if grep -q "$ENGINE" <<< "$ENABLED"; then
+            echo "❌ $ENGINE actif"
+            read -rp "Désactiver $ENGINE (ajout dans disabled_storage_engines) ? (y/n) " choice
+            if [[ $choice == "y" ]]; then
+                if ! grep -q "disabled_storage_engines" "$CONFIG_FILE"; then
+                    echo "disabled_storage_engines=$ENGINE" >> "$CONFIG_FILE"
+                else
+                    sed -i "/^disabled_storage_engines/s/$/,$ENGINE/" "$CONFIG_FILE"
+                fi
+                RESTART_REQUIRED=1
+                ISSUES_FOUND=1
+                echo "✔️ $ENGINE désactivé (redémarrage requis)"
+            fi
+        else
+            echo "✔️ $ENGINE non actif"
+        fi
+    done
+    echo
+}
+
+check_bind() {
+    echo "🌐 Vérification du bind-address..."
+    BIND_ADDRESS=$(grep -E "^bind-address" "$CONFIG_FILE" | cut -d= -f2 | tr -d ' ')
+    if [[ "$BIND_ADDRESS" != "127.0.0.1" ]]; then
+        echo "❌ MariaDB écoute sur $BIND_ADDRESS"
+        read -rp "Forcer 127.0.0.1 ? (y/n) " choice
+        if [[ $choice == "y" ]]; then
+            sed -i 's/^bind-address.*/bind-address = 127.0.0.1/' "$CONFIG_FILE"
+            RESTART_REQUIRED=1
+            echo "✔️ bind-address corrigé"
+        fi
+    else
+        echo "✔️ bind-address sécurisé"
+    fi
+    echo
+}
+
+check_anonymous_users() {
+    echo "👤 Vérification des utilisateurs anonymes..."
+    if [[ $($MYSQL_CMD -N -e "SELECT COUNT(*) FROM mysql.user WHERE User='';") -gt 0 ]]; then
+        echo "❌ Utilisateurs anonymes trouvés"
+        read -rp "Supprimer ? (y/n) " choice
+        [[ $choice == "y" ]] && $MYSQL_CMD -e "DELETE FROM mysql.user WHERE User=''; FLUSH PRIVILEGES;" && echo "✔️ Anonymes supprimés"
+    else
+        echo "✔️ Aucun utilisateur anonyme"
+    fi
+    echo
+}
+
+check_remote_root() {
+    echo "🔑 Vérification des accès root distants..."
+    if [[ $($MYSQL_CMD -N -e "SELECT COUNT(*) FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');") -gt 0 ]]; then
+        echo "❌ Accès root distant détecté"
+        read -rp "Supprimer ces accès ? (y/n) " choice
+        [[ $choice == "y" ]] && $MYSQL_CMD -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); FLUSH PRIVILEGES;" && echo "✔️ Accès root externe supprimé"
+    else
+        echo "✔️ Aucun accès root distant"
+    fi
+    echo
+}
+
+check_test_db() {
+    echo "🧪 Vérification de la base 'test'..."
+    if $MYSQL_CMD -e "SHOW DATABASES LIKE 'test';" | grep -q "test"; then
+        echo "❌ Base 'test' présente"
+        read -rp "Supprimer ? (y/n) " choice
+        [[ $choice == "y" ]] && $MYSQL_CMD -e "DROP DATABASE test;" && echo "✔️ Base test supprimée"
+    else
+        echo "✔️ Base 'test' absente"
+    fi
+    echo
+}
+
+check_file_priv() {
+    echo "📂 Vérification des FILE PRIV..."
+    USERS=$($MYSQL_CMD -N -e "SELECT CONCAT(User, '@', Host) FROM mysql.user WHERE File_priv='Y';")
+    if [[ -n "$USERS" ]]; then
+        echo "❌ Utilisateurs avec FILE PRIV détectés:"
+        echo "$USERS"
+        read -rp "Retirer le droit FILE ? (y/n) " choice
+        if [[ $choice == "y" ]]; then
+            while read -r user; do
+                $MYSQL_CMD -e "REVOKE FILE ON *.* FROM '$user';"
+            done <<< "$USERS"
+            $MYSQL_CMD -e "FLUSH PRIVILEGES;"
+            echo "✔️ FILE révoqué"
+        fi
+    else
+        echo "✔️ Aucun droit FILE abusif"
+    fi
+    echo
+}
+
+check_slow_log() {
+    echo "🐌 Vérification du slow query log..."
+    ACTIVE=$($MYSQL_CMD -N -e "SHOW VARIABLES LIKE 'slow_query_log';" | awk '{print $2}')
+    if [[ "$ACTIVE" != "ON" ]]; then
+        echo "⚠️ Slow query log désactivé"
+        read -rp "Activer dans la conf ? (y/n) " choice
+        if [[ $choice == "y" ]]; then
+            cat >> "$CONFIG_FILE" <<EOL
+
+slow_query_log = 1
+slow_query_log_file = /var/log/mysql/mariadb-slow.log
+long_query_time = 2
+EOL
+            touch /var/log/mysql/mariadb-slow.log
+            chown mysql:mysql /var/log/mysql/mariadb-slow.log
+            RESTART_REQUIRED=1
+            echo "✔️ Slow query log activé"
+        fi
+    else
+        echo "✔️ Slow query log actif"
+    fi
+    echo
+}
+
+echo "===> Démarrage de l'audit..."
+echo
+
+# Lancer les contrôles
+check_permissions
+check_storage_engines
+check_bind
+check_anonymous_users
+check_remote_root
+check_test_db
+check_file_priv
+check_slow_log
+
+if [[ $RESTART_REQUIRED -eq 1 ]]; then
+    echo "♻️ Redémarrage de MariaDB requis"
+    systemctl restart mariadb
+    echo
+fi
+
+if [[ $ISSUES_FOUND -eq 1 ]]; then
+    echo "⚠️ Audit terminé avec des recommandations ou actions effectuées."
+else
+    echo "✅ Audit terminé - Aucun problème majeur détecté."
+fi
diff --git a/scripts/server-mariadb/create_db.sh b/scripts/server-mariadb/create_db.sh
index c4f7bc8..2dd871b 100644
--- a/scripts/server-mariadb/create_db.sh
+++ b/scripts/server-mariadb/create_db.sh
@@ -69,6 +69,12 @@ if ! mysql --defaults-extra-file="$TEMP_CNF" -e "SELECT 1;" 2>/dev/null; then
 fi
 echo "✅ Connexion root réussie."
 
+# Définir la variable MYSQL_CMD pour le reste du script
+MYSQL_CMD="mysql --defaults-extra-file=$TEMP_CNF"
+
+# N'oublie pas de prévoir un nettoyage à la fin :
+trap 'rm -f "$TEMP_CNF"' EXIT
+
 echo "=== Création d'une nouvelle base de données MariaDB ==="
 
 # Lecture du nom de la base de données
diff --git a/scripts/server-mariadb/set_root_password.sh b/scripts/server-mariadb/set_root_password.sh
new file mode 100644
index 0000000..dee0519
--- /dev/null
+++ b/scripts/server-mariadb/set_root_password.sh
@@ -0,0 +1,112 @@
+#!/bin/bash
+# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
+
+# Importer les fonctions communes
+source "$(dirname "$0")/../common/common_utils.sh"
+
+# Vérifier si le script est exécuté en root
+check_root
+
+# Variables
+NEW_PASS=$(generate_token 20)
+DB_SERVICE="mariadb"  # Adapter si besoin
+MYSQL_SOCK="/var/run/mysqld/mysqld.sock"
+CNF_FILES=("/etc/mysql/debian.cnf" "/root/.my.cnf")
+MYSQLD_SAFE_LOG="/tmp/mysqld_safe.log"
+
+echo "[+] Nouveau mot de passe root généré."
+
+# Arrêt du service MySQL/MariaDB
+echo "[+] Arrêt du service $DB_SERVICE..."
+systemctl stop "$DB_SERVICE"
+
+echo "[+] Attente de l'arrêt complet du service..."
+while systemctl is-active --quiet "$DB_SERVICE"; do
+    sleep 1
+done
+echo "[+] Service arrêté."
+
+# Nettoyage des éventuels sockets ou PID bloquants
+echo "[+] Nettoyage des sockets et PID..."
+rm -f /var/run/mysqld/mysqld.pid /var/run/mysqld/mysqld.sock
+
+# Démarrage en mode sans échec
+echo "[+] Démarrage de MySQL en mode sans échec..."
+mysqld_safe --skip-grant-tables --skip-networking > "$MYSQLD_SAFE_LOG" 2>&1 &
+SAFE_PID=$!
+
+# Attente que mysqld_safe soit vraiment prêt
+echo "[+] Attente de la disponibilité de mysqld_safe..."
+for i in {1..10}; do
+    if mysqladmin ping --socket="$MYSQL_SOCK" >/dev/null 2>&1; then
+        echo "[+] mysqld_safe est prêt."
+        break
+    fi
+    sleep 1
+done
+
+if ! mysqladmin ping --socket="$MYSQL_SOCK" >/dev/null 2>&1; then
+    echo "[❌] Échec du démarrage de mysqld_safe. Voir $MYSQLD_SAFE_LOG"
+    kill -9 $SAFE_PID 2>/dev/null
+    exit 1
+fi
+
+# Réinitialisation du mot de passe root
+echo "[+] Réinitialisation du mot de passe root..."
+mysql --socket="$MYSQL_SOCK" <<EOF
+FLUSH PRIVILEGES;
+ALTER USER 'root'@'localhost' IDENTIFIED BY '$NEW_PASS';
+FLUSH PRIVILEGES;
+EOF
+
+# Nettoyage complet du mode sans échec
+echo "[+] Arrêt complet du mode sans échec et des processus MySQL/MariaDB..."
+kill -9 $SAFE_PID
+killall -9 mysqld_safe mariadbd mysqld || true
+sleep 5
+
+# Redémarrage du service
+echo "[+] Redémarrage du service $DB_SERVICE..."
+systemctl start "$DB_SERVICE"
+
+# Vérification du bon démarrage
+echo "[+] Attente du démarrage complet de MariaDB..."
+for i in {1..10}; do
+    if systemctl is-active --quiet "$DB_SERVICE"; then
+        echo "[+] MariaDB est démarré."
+        break
+    fi
+    sleep 1
+done
+
+if ! systemctl is-active --quiet "$DB_SERVICE"; then
+    echo "[❌] MariaDB ne démarre pas. Voir journalctl -xeu $DB_SERVICE"
+    systemctl status "$DB_SERVICE"
+    exit 1
+fi
+
+# Test de connexion avec le nouveau mot de passe
+echo "[+] Test de connexion réel avec le nouveau mot de passe root..."
+if mysql -uroot -p"$NEW_PASS" -e "SELECT 'Connexion réussie' AS Status;" >/dev/null 2>&1; then
+    echo "[✔] Connexion root réussie."
+
+    # Mise à jour des fichiers .cnf si user = root
+    for file in "${CNF_FILES[@]}"; do
+        if [[ -f "$file" ]]; then
+            if grep -q "^\s*user\s*=\s*root" "$file"; then
+                echo "[+] Mise à jour du fichier $file (user=root détecté)."
+                sed -i -E "s/(password\s*=\s*).*/\1$NEW_PASS/" "$file"
+            else
+                echo "[!] Pas de user=root dans $file, aucune modification."
+            fi
+        fi
+    done
+
+    echo "---------------------------------------------"
+    echo "[✔] Mot de passe root MySQL/MariaDB réinitialisé avec succès."
+    echo "[✔] Nouveau mot de passe root : $NEW_PASS"
+    echo "---------------------------------------------"
+else
+    echo "[❌] Échec de la connexion root après redémarrage de MariaDB."
+    exit 1
+fi
\ No newline at end of file