#!/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" </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" < 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