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