From 852de64c864cf09c0e6cd1819080a17f7259ddbf Mon Sep 17 00:00:00 2001 From: Johnny Date: Tue, 30 Dec 2025 12:12:37 +0000 Subject: [PATCH] Ajouter system_hardening_optimized.sh --- system_hardening_optimized.sh | 1857 +++++++++++++++++++++++++++++++++ 1 file changed, 1857 insertions(+) create mode 100644 system_hardening_optimized.sh diff --git a/system_hardening_optimized.sh b/system_hardening_optimized.sh new file mode 100644 index 0000000..c88ea7b --- /dev/null +++ b/system_hardening_optimized.sh @@ -0,0 +1,1857 @@ +#!/bin/bash + +# Script de durcissement système Linux +# Version: 3.0 - Idempotent et Robuste +# Auteur: Optimisé pour sécurité renforcée et réutilisabilité + +set -euo pipefail + +# ============================================================================ +# CONFIGURATION GLOBALE +# ============================================================================ + +readonly SCRIPT_VERSION="3.0" +readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +readonly STATE_DIR="/var/lib/hardening-script" +readonly BACKUP_BASE_DIR="/root/backup_hardening" +readonly LOG_FILE="/var/log/hardening-script.log" +readonly SSH_PORT="${SSH_PORT:-2222}" +readonly LOCK_FILE="/var/run/hardening-script.lock" + +# Couleurs +readonly RED='\033[0;31m' +readonly GREEN='\033[0;32m' +readonly YELLOW='\033[1;33m' +readonly BLUE='\033[0;34m' +readonly MAGENTA='\033[0;35m' +readonly CYAN='\033[0;36m' +readonly NC='\033[0m' + +# ============================================================================ +# FONCTIONS UTILITAIRES +# ============================================================================ + +# Logging amélioré avec fichier +log() { + local msg="[$(date '+%Y-%m-%d %H:%M:%S')] $1" + echo -e "${GREEN}${msg}${NC}" + echo "$msg" >> "$LOG_FILE" +} + +warn() { + local msg="[ATTENTION] $1" + echo -e "${YELLOW}${msg}${NC}" + echo "$msg" >> "$LOG_FILE" +} + +error() { + local msg="[ERREUR] $1" + echo -e "${RED}${msg}${NC}" >&2 + echo "$msg" >> "$LOG_FILE" +} + +info() { + local msg="[INFO] $1" + echo -e "${CYAN}${msg}${NC}" + echo "$msg" >> "$LOG_FILE" +} + +success() { + local msg="[OK] $1" + echo -e "${GREEN}${msg}${NC}" + echo "$msg" >> "$LOG_FILE" +} + +# Fonction pour vérifier si une tâche a déjà été exécutée (idempotence) +is_task_done() { + local task_name="$1" + [[ -f "${STATE_DIR}/${task_name}.done" ]] +} + +# Marquer une tâche comme terminée +mark_task_done() { + local task_name="$1" + mkdir -p "$STATE_DIR" + touch "${STATE_DIR}/${task_name}.done" + echo "$(date '+%Y-%m-%d %H:%M:%S')" > "${STATE_DIR}/${task_name}.timestamp" +} + +# Réinitialiser l'état d'une tâche +reset_task() { + local task_name="$1" + rm -f "${STATE_DIR}/${task_name}.done" "${STATE_DIR}/${task_name}.timestamp" +} + +# Exécuter une tâche de manière idempotente +run_task() { + local task_name="$1" + local task_function="$2" + local force="${3:-false}" + + if is_task_done "$task_name" && [[ "$force" != "true" ]]; then + info "Tâche '$task_name' déjà effectuée - ignorée (utilisez --force pour réexécuter)" + return 0 + fi + + log "Exécution de la tâche: $task_name" + if $task_function; then + mark_task_done "$task_name" + success "Tâche '$task_name' terminée avec succès" + return 0 + else + error "Échec de la tâche '$task_name'" + return 1 + fi +} + +# Gestion du verrou pour éviter les exécutions simultanées +acquire_lock() { + exec 200>"$LOCK_FILE" + if ! flock -n 200; then + error "Une autre instance du script est en cours d'exécution" + exit 1 + fi +} + +release_lock() { + flock -u 200 + rm -f "$LOCK_FILE" +} + +# Nettoyage amélioré +cleanup() { + error "Script interrompu. Nettoyage en cours..." + release_lock + exit 1 +} + +trap cleanup INT TERM EXIT + +# ============================================================================ +# VÉRIFICATIONS PRÉLIMINAIRES +# ============================================================================ + +check_root() { + if [[ $EUID -ne 0 ]]; then + error "Ce script doit être exécuté en tant que root (sudo ./script.sh)" + exit 1 + fi +} + +check_distribution() { + if [[ -f /etc/os-release ]]; then + source /etc/os-release + info "Distribution détectée: $PRETTY_NAME" + + if [[ "$ID_LIKE" =~ (debian|ubuntu) ]] || [[ "$ID" =~ (debian|ubuntu) ]]; then + return 0 + fi + fi + + error "Ce script est conçu pour les distributions basées sur Debian/Ubuntu" + exit 1 +} + +check_disk_space() { + local required_space=1048576 # 1GB en KB + local available_space=$(df / | awk 'NR==2 {print $4}') + + if [[ $available_space -lt $required_space ]]; then + error "Espace disque insuffisant. Requis: 1GB, Disponible: $((available_space/1024))MB" + exit 1 + fi +} + +check_internet_connectivity() { + if ! ping -c 1 -W 2 8.8.8.8 &> /dev/null; then + warn "Pas de connectivité Internet détectée. Certaines opérations peuvent échouer." + read -p "Continuer quand même? (y/N) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi + fi +} + +# ============================================================================ +# SAUVEGARDE ET RESTAURATION +# ============================================================================ + +backup_configs() { + local backup_dir="${BACKUP_BASE_DIR}_$(date +%Y%m%d_%H%M%S)" + + if is_task_done "backup_configs"; then + info "Sauvegarde déjà effectuée" + return 0 + fi + + log "Sauvegarde des fichiers de configuration..." + mkdir -p "$backup_dir" + + local files=( + "/etc/ssh/sshd_config" + "/etc/login.defs" + "/etc/pam.d/common-password" + "/etc/pam.d/common-auth" + "/etc/security/limits.conf" + "/etc/sysctl.conf" + "/etc/fstab" + "/etc/default/grub" + "/etc/audit/auditd.conf" + "/etc/rsyslog.conf" + ) + + for file in "${files[@]}"; do + if [[ -f "$file" ]]; then + cp -p "$file" "$backup_dir/" 2>/dev/null || warn "Impossible de sauvegarder $file" + fi + done + + # Sauvegarder la liste des paquets installés + dpkg --get-selections > "$backup_dir/installed_packages.list" + + # Sauvegarder les règles UFW + if command -v ufw &> /dev/null; then + ufw status numbered > "$backup_dir/ufw_rules.txt" 2>/dev/null || true + fi + + # Sauvegarder les services actifs + systemctl list-units --type=service --state=running > "$backup_dir/active_services.txt" + + # Créer un fichier de métadonnées + cat > "$backup_dir/metadata.txt" < "${STATE_DIR}/last_backup_dir" +} + +# ============================================================================ +# MISE À JOUR ET INSTALLATION +# ============================================================================ + +update_system() { + log "Mise à jour du système..." + export DEBIAN_FRONTEND=noninteractive + + # Nettoyer les verrous APT si nécessaire + rm -f /var/lib/apt/lists/lock + rm -f /var/cache/apt/archives/lock + rm -f /var/lib/dpkg/lock* + + # Configurer dpkg pour éviter les prompts + dpkg --configure -a + + apt update -qq || { + error "Échec de la mise à jour des dépôts" + return 1 + } + + apt upgrade -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" + apt autoremove -y -qq + apt autoclean -qq + + # Mettre à jour la base de données locate si présente + command -v updatedb &> /dev/null && updatedb || true +} + +install_security_tools() { + log "Installation des outils de durcissement..." + + local packages=( + # Outils de sécurité + lynis fail2ban ufw aide aide-common + # Antivirus + clamav clamav-daemon clamav-freshclam + # Détection rootkit + chkrootkit rkhunter + # Audit et logging + auditd audispd-plugins + rsyslog logwatch logrotate + # Authentification + libpam-tmpdir libpam-pwquality libpam-cracklib + # Monitoring + sysstat iotop htop + # Outils réseau + net-tools tcpdump nmap + # Synchronisation temps + chrony + # Détection d'intrusion + psad + # Autres + debsums apt-listchanges unattended-upgrades + acct apparmor apparmor-utils apparmor-profiles + tiger needrestart debsecan + ) + + local failed_packages=() + + export DEBIAN_FRONTEND=noninteractive + + for package in "${packages[@]}"; do + if ! dpkg -l | grep -q "^ii $package "; then + if apt install -y -qq -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" "$package" 2>/dev/null; then + info "✓ $package installé" + else + warn "✗ Échec de l'installation de $package" + failed_packages+=("$package") + fi + else + info "✓ $package déjà installé" + fi + done + + if [[ ${#failed_packages[@]} -gt 0 ]]; then + warn "Paquets non installés: ${failed_packages[*]}" + fi +} + +# ============================================================================ +# CONFIGURATION FAIL2BAN +# ============================================================================ + +configure_fail2ban() { + log "Configuration de Fail2ban..." + + # Configuration locale qui ne sera pas écrasée + cat > /etc/fail2ban/jail.local </dev/null; then + cat >> /etc/fail2ban/jail.local </dev/null; then + cat >> /etc/fail2ban/jail.local </dev/null; then + cat >> /etc/fail2ban/jail.local < /dev/null; then + systemctl enable fail2ban + systemctl restart fail2ban + success "Fail2ban configuré et démarré" + else + error "Erreur dans la configuration Fail2ban" + return 1 + fi +} + +# ============================================================================ +# CONFIGURATION UFW (PARE-FEU) +# ============================================================================ + +configure_ufw() { + log "Configuration du pare-feu UFW..." + + # Sauvegarder les règles actuelles si UFW est déjà actif + if ufw status | grep -q "Status: active"; then + ufw status numbered > "${STATE_DIR}/ufw_backup_$(date +%Y%m%d_%H%M%S).txt" + fi + + # Désactiver UFW temporairement + ufw --force disable + + # Réinitialiser SEULEMENT si pas déjà configuré + if [[ ! -f "${STATE_DIR}/ufw_configured" ]]; then + ufw --force reset + fi + + # Politique par défaut + ufw default deny incoming + ufw default allow outgoing + ufw default deny forward + + # Autoriser le loopback + ufw allow in on lo + ufw allow out on lo + + # SSH sur port personnalisé + ufw allow ${SSH_PORT}/tcp comment 'SSH Custom Port' + + # Services web (commentés par défaut) + # ufw allow 80/tcp comment 'HTTP' + # ufw allow 443/tcp comment 'HTTPS' + + # DNS (sortant seulement, entrant généralement pas nécessaire) + ufw allow out 53 comment 'DNS' + + # NTP + ufw allow out 123/udp comment 'NTP' + + # Protection contre les scans de ports + ufw limit ${SSH_PORT}/tcp + + # Logging + ufw logging medium + + # Activer UFW + ufw --force enable + + touch "${STATE_DIR}/ufw_configured" + + # Afficher les règles + ufw status verbose +} + +# ============================================================================ +# CONFIGURATION SSH SÉCURISÉE +# ============================================================================ + +configure_ssh() { + log "Configuration sécurisée de SSH..." + + # Vérifier si des clés SSH existent pour les utilisateurs + local has_ssh_keys=false + for user_home in /home/*; do + if [[ -f "$user_home/.ssh/authorized_keys" ]] && [[ -s "$user_home/.ssh/authorized_keys" ]]; then + has_ssh_keys=true + break + fi + done + + if [[ "$has_ssh_keys" == "false" ]]; then + warn "ATTENTION: Aucune clé SSH trouvée pour les utilisateurs !" + warn "L'authentification par mot de passe SSH sera DÉSACTIVÉE." + read -p "Continuer? Vous pourriez perdre l'accès SSH! (y/N) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + error "Configuration SSH annulée. Configurez d'abord vos clés SSH." + return 1 + fi + fi + + # Sauvegarder la config actuelle si pas déjà fait + [[ ! -f /etc/ssh/sshd_config.bak ]] && cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak + + # Configuration SSH durcie + cat > /etc/ssh/sshd_config < /etc/issue.net <<'EOF' +################################################################################ +# # +# SYSTÈME SÉCURISÉ - ACCÈS RESTREINT # +# # +# Ce système est réservé exclusivement aux utilisateurs autorisés. # +# Toutes les connexions et activités sont surveillées et enregistrées. # +# L'accès non autorisé est strictement interdit et sera poursuivi. # +# # +# Si vous n'êtes pas autorisé, déconnectez-vous immédiatement. # +# # +################################################################################ +EOF + + # Appliquer aussi la bannière au login local + cp /etc/issue.net /etc/issue + + # Vérifier et appliquer la configuration + if sshd -t 2>/dev/null; then + systemctl restart sshd + success "Configuration SSH appliquée - Port: ${SSH_PORT}" + info "Testez votre connexion SSH sur le port ${SSH_PORT} AVANT de fermer cette session!" + else + error "Erreur dans la configuration SSH!" + sshd -t + return 1 + fi +} + +# ============================================================================ +# CONFIGURATION SYSCTL (KERNEL) +# ============================================================================ + +configure_sysctl() { + log "Configuration des paramètres kernel (sysctl)..." + + # Créer un fichier de configuration dédié + cat > /etc/sysctl.d/99-hardening.conf <<'EOF' +# Configuration de sécurité kernel - Hardening Script +# Généré automatiquement + +# ============================================================================ +# SÉCURITÉ RÉSEAU IPv4 +# ============================================================================ + +# Protection contre IP spoofing (vérification de la source) +net.ipv4.conf.default.rp_filter = 1 +net.ipv4.conf.all.rp_filter = 1 + +# Ignorer les pings ICMP (protection contre ping flood) +net.ipv4.icmp_echo_ignore_all = 1 +net.ipv4.icmp_ignore_bogus_error_responses = 1 + +# Ignorer les redirections ICMP +net.ipv4.conf.all.accept_redirects = 0 +net.ipv4.conf.default.accept_redirects = 0 +net.ipv4.conf.all.secure_redirects = 0 +net.ipv4.conf.default.secure_redirects = 0 + +# Ne pas envoyer de redirections ICMP +net.ipv4.conf.all.send_redirects = 0 +net.ipv4.conf.default.send_redirects = 0 + +# Ignorer les paquets source routed +net.ipv4.conf.all.accept_source_route = 0 +net.ipv4.conf.default.accept_source_route = 0 + +# Protection SYN flood +net.ipv4.tcp_syncookies = 1 +net.ipv4.tcp_max_syn_backlog = 2048 +net.ipv4.tcp_synack_retries = 2 +net.ipv4.tcp_syn_retries = 5 + +# Désactiver le routage IP si non routeur +net.ipv4.ip_forward = 0 +net.ipv4.conf.all.forwarding = 0 +net.ipv4.conf.default.forwarding = 0 + +# Log des paquets suspects +net.ipv4.conf.all.log_martians = 1 +net.ipv4.conf.default.log_martians = 1 + +# Protection contre les attaques de temps +net.ipv4.tcp_timestamps = 0 + +# Amélioration des performances TCP +net.ipv4.tcp_window_scaling = 1 +net.ipv4.tcp_sack = 1 + +# ============================================================================ +# SÉCURITÉ RÉSEAU IPv6 +# ============================================================================ + +# Désactiver IPv6 si non utilisé (décommenter si nécessaire) +# net.ipv6.conf.all.disable_ipv6 = 1 +# net.ipv6.conf.default.disable_ipv6 = 1 +# net.ipv6.conf.lo.disable_ipv6 = 1 + +# Si IPv6 est utilisé, appliquer les mêmes protections +net.ipv6.conf.all.accept_redirects = 0 +net.ipv6.conf.default.accept_redirects = 0 +net.ipv6.conf.all.accept_source_route = 0 +net.ipv6.conf.default.accept_source_route = 0 +net.ipv6.conf.all.accept_ra = 0 +net.ipv6.conf.default.accept_ra = 0 +net.ipv6.conf.all.forwarding = 0 + +# ============================================================================ +# SÉCURITÉ KERNEL +# ============================================================================ + +# Restreindre l'accès aux logs kernel +kernel.dmesg_restrict = 1 + +# Masquer les adresses kernel +kernel.kptr_restrict = 2 + +# Protection ptrace (empêche l'attachement aux processus) +kernel.yama.ptrace_scope = 1 + +# Protection contre les attaques par lien symbolique +fs.protected_symlinks = 1 +fs.protected_hardlinks = 1 + +# Protection FIFO et fichiers réguliers +fs.protected_fifos = 2 +fs.protected_regular = 2 + +# Désactiver les SysRq sauf reboot/shutdown d'urgence +kernel.sysrq = 16 + +# Limiter la visibilité des processus +# kernel.unprivileged_userns_clone = 0 + +# ============================================================================ +# AUTRES PARAMÈTRES DE SÉCURITÉ +# ============================================================================ + +# Randomisation de l'espace d'adressage +kernel.randomize_va_space = 2 + +# Core dumps +kernel.core_uses_pid = 1 +fs.suid_dumpable = 0 + +# Limite des fichiers ouverts +fs.file-max = 2097152 + +# IPC +kernel.msgmnb = 65536 +kernel.msgmax = 65536 + +# Shared memory +kernel.shmmax = 68719476736 +kernel.shmall = 4294967296 +EOF + + # Appliquer immédiatement les changements + sysctl -p /etc/sysctl.d/99-hardening.conf + + success "Paramètres kernel appliqués" +} + +# ============================================================================ +# POLITIQUE DE MOTS DE PASSE +# ============================================================================ + +configure_password_policy() { + log "Configuration de la politique de mots de passe..." + + # Sauvegarde + [[ ! -f /etc/login.defs.bak ]] && cp /etc/login.defs /etc/login.defs.bak + + # Configuration login.defs (idempotent avec sed) + sed -i.tmp 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs + sed -i.tmp 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS 1/' /etc/login.defs + sed -i.tmp 's/^PASS_WARN_AGE.*/PASS_WARN_AGE 14/' /etc/login.defs + sed -i.tmp 's/^UMASK.*/UMASK 027/' /etc/login.defs + sed -i.tmp 's/^ENCRYPT_METHOD.*/ENCRYPT_METHOD SHA512/' /etc/login.defs + + # Ajouter les paramètres manquants (idempotent) + grep -q "^SHA_CRYPT_MIN_ROUNDS" /etc/login.defs || echo "SHA_CRYPT_MIN_ROUNDS 5000" >> /etc/login.defs + grep -q "^SHA_CRYPT_MAX_ROUNDS" /etc/login.defs || echo "SHA_CRYPT_MAX_ROUNDS 5000" >> /etc/login.defs + grep -q "^FAILLOG_ENAB" /etc/login.defs || echo "FAILLOG_ENAB yes" >> /etc/login.defs + grep -q "^LOG_UNKFAIL_ENAB" /etc/login.defs || echo "LOG_UNKFAIL_ENAB yes" >> /etc/login.defs + + # Configuration PAM pour la qualité des mots de passe (idempotent) + if [[ -f /etc/pam.d/common-password ]]; then + [[ ! -f /etc/pam.d/common-password.bak ]] && cp /etc/pam.d/common-password /etc/pam.d/common-password.bak + + if ! grep -q "pam_pwquality.so" /etc/pam.d/common-password; then + sed -i '/pam_unix.so/i password requisite pam_pwquality.so retry=3 minlen=14 difok=4 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=2 reject_username enforce_for_root' /etc/pam.d/common-password + fi + + # Ajouter pam_pwhistory pour empêcher la réutilisation des mots de passe + if ! grep -q "pam_pwhistory.so" /etc/pam.d/common-password; then + sed -i '/pam_unix.so/a password required pam_pwhistory.so remember=5 use_authtok' /etc/pam.d/common-password + fi + fi + + # Configuration de verrouillage de compte après échecs + if [[ -f /etc/pam.d/common-auth ]]; then + [[ ! -f /etc/pam.d/common-auth.bak ]] && cp /etc/pam.d/common-auth /etc/pam.d/common-auth.bak + + if ! grep -q "pam_faillock.so" /etc/pam.d/common-auth; then + sed -i '1i auth required pam_faillock.so preauth silent audit deny=5 unlock_time=900' /etc/pam.d/common-auth + echo "auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=900" >> /etc/pam.d/common-auth + echo "auth sufficient pam_faillock.so authsucc" >> /etc/pam.d/common-auth + fi + fi + + success "Politique de mots de passe configurée" +} + +# ============================================================================ +# LIMITES SYSTÈME +# ============================================================================ + +configure_limits() { + log "Configuration des limites système..." + + [[ ! -f /etc/security/limits.conf.bak ]] && cp /etc/security/limits.conf /etc/security/limits.conf.bak + + # Ajouter les limites si elles n'existent pas déjà + if ! grep -q "# Hardening Script Limits" /etc/security/limits.conf; then + cat >> /etc/security/limits.conf <<'EOF' + +# Hardening Script Limits +# Core dumps désactivés pour tous +* hard core 0 +* soft core 0 + +# Limites de processus +* soft nproc 65536 +* hard nproc 65536 + +# Limites de fichiers ouverts +* soft nofile 65536 +* hard nofile 65536 + +# Stack size +* hard stack 2048 + +# Root illimité pour les processus +root soft nproc unlimited +root hard nproc unlimited +EOF + fi + + success "Limites système configurées" +} + +# ============================================================================ +# DÉSACTIVATION DES MODULES ET SERVICES +# ============================================================================ + +disable_unnecessary_services() { + log "Désactivation des services et modules non nécessaires..." + + # Désactiver les modules noyau dangereux + cat > /etc/modprobe.d/hardening-disable-modules.conf <<'EOF' +# Désactivation des protocoles réseau non nécessaires +install dccp /bin/true +install sctp /bin/true +install tipc /bin/true +install rds /bin/true + +# Désactivation des systèmes de fichiers rares +install cramfs /bin/true +install freevxfs /bin/true +install jffs2 /bin/true +install hfs /bin/true +install hfsplus /bin/true +install squashfs /bin/true +install udf /bin/true +install vfat /bin/true + +# Désactivation des modules sans fil et bluetooth +blacklist firewire-core +blacklist thunderbolt +blacklist bluetooth +blacklist btusb +blacklist bnep + +# Désactivation USB (décommenter si serveur sans USB) +# blacklist usb-storage +# blacklist uas + +# Désactivation de modules anciens +blacklist floppy +EOF + + # Liste des services à désactiver (si présents) + local services_to_disable=( + bluetooth.service + cups.service + cups-browsed.service + avahi-daemon.service + avahi-daemon.socket + rpcbind.service + rpcbind.socket + nfs-common.service + nfs-kernel-server.service + iscsid.service + open-iscsi.service + snapd.service + snapd.socket + ) + + for service in "${services_to_disable[@]}"; do + if systemctl list-unit-files | grep -q "^${service}"; then + if systemctl is-enabled "$service" &>/dev/null; then + systemctl disable "$service" 2>/dev/null || true + systemctl stop "$service" 2>/dev/null || true + info "✓ Service désactivé: $service" + fi + fi + done + + success "Services inutiles désactivés" +} + +# ============================================================================ +# CONFIGURATION ANTIVIRUS (CLAMAV) +# ============================================================================ + +configure_clamav() { + log "Configuration de ClamAV..." + + if ! command -v freshclam &> /dev/null; then + warn "ClamAV non installé, passage" + return 0 + fi + + # Arrêter le service temporairement + systemctl stop clamav-freshclam 2>/dev/null || true + + # Configuration freshclam pour mises à jour automatiques + if [[ -f /etc/clamav/freshclam.conf ]]; then + sed -i 's/^#DatabaseMirror/DatabaseMirror/' /etc/clamav/freshclam.conf + sed -i 's/^Example/#Example/' /etc/clamav/freshclam.conf + fi + + # Mettre à jour la base de données (avec timeout) + timeout 300 freshclam || warn "Mise à jour ClamAV timeout (normal lors de la première exécution)" + + # Activer et démarrer les services + systemctl enable clamav-freshclam 2>/dev/null || true + systemctl start clamav-freshclam 2>/dev/null || true + + if systemctl list-unit-files | grep -q "clamav-daemon"; then + systemctl enable clamav-daemon 2>/dev/null || true + systemctl start clamav-daemon 2>/dev/null || true + fi + + # Créer un script de scan quotidien + cat > /etc/cron.daily/clamav-scan <<'EOF' +#!/bin/bash +SCAN_DIR="/home /var/www" +LOG_FILE="/var/log/clamav/daily-scan.log" +mkdir -p /var/log/clamav + +# Scanner les répertoires importants +clamscan -r -i --exclude-dir="^/sys" --exclude-dir="^/proc" --exclude-dir="^/dev" \ + $SCAN_DIR > "$LOG_FILE" 2>&1 + +# Envoyer un email si des virus sont détectés +if grep -q "Infected files: [1-9]" "$LOG_FILE"; then + mail -s "ClamAV: Virus détectés sur $(hostname)" root < "$LOG_FILE" +fi +EOF + chmod +x /etc/cron.daily/clamav-scan + + success "ClamAV configuré" +} + +# ============================================================================ +# CONFIGURATION AIDE (DÉTECTION D'INTRUSION) +# ============================================================================ + +configure_aide() { + log "Configuration d'AIDE (détection d'intrusion)..." + + if ! command -v aide &> /dev/null; then + warn "AIDE non installé, passage" + return 0 + fi + + # Configuration AIDE personnalisée + cat > /etc/aide/aide.conf.d/99_hardening <<'EOF' +# Configuration AIDE - Hardening Script + +# Répertoires système critiques à surveiller +/bin R+b+sha256 +/sbin R+b+sha256 +/usr/bin R+b+sha256 +/usr/sbin R+b+sha256 +/lib R+b+sha256 +/lib64 R+b+sha256 +/usr/lib R+b+sha256 +/usr/lib64 R+b+sha256 + +# Configuration système +/etc R+b+sha256 +!/etc/mtab +!/etc/adjtime + +# Fichiers de démarrage +/boot R+b+sha256 + +# Exclure les répertoires dynamiques +!/var/log +!/var/cache +!/var/tmp +!/tmp +!/proc +!/sys +!/dev +!/run +EOF + + # Initialiser la base de données AIDE (long processus) + if [[ ! -f /var/lib/aide/aide.db ]]; then + log "Initialisation de la base AIDE (peut prendre plusieurs minutes)..." + aideinit || warn "Échec de l'initialisation AIDE" + + if [[ -f /var/lib/aide/aide.db.new ]]; then + mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db + fi + fi + + # Script de vérification quotidienne + cat > /etc/cron.daily/aide-check <<'EOF' +#!/bin/bash +LOG_FILE="/var/log/aide/aide-check-$(date +%Y%m%d).log" +mkdir -p /var/log/aide + +# Exécuter la vérification +/usr/bin/aide --check > "$LOG_FILE" 2>&1 +EXIT_CODE=$? + +# Si des changements sont détectés (code 7) +if [[ $EXIT_CODE -eq 7 ]]; then + # Envoyer un email d'alerte + mail -s "AIDE: Modifications détectées sur $(hostname)" root < "$LOG_FILE" + + # Logger dans syslog + logger -t aide-check "ATTENTION: Modifications système détectées" +fi + +# Rotation des logs (garder 30 jours) +find /var/log/aide -name "aide-check-*.log" -mtime +30 -delete +EOF + chmod +x /etc/cron.daily/aide-check + + success "AIDE configuré" +} + +# ============================================================================ +# MISES À JOUR AUTOMATIQUES +# ============================================================================ + +configure_auto_updates() { + log "Configuration des mises à jour automatiques de sécurité..." + + if ! command -v unattended-upgrade &> /dev/null; then + warn "unattended-upgrades non installé, passage" + return 0 + fi + + # Configuration des mises à jour automatiques + cat > /etc/apt/apt.conf.d/50unattended-upgrades <<'EOF' +Unattended-Upgrade::Allowed-Origins { + "${distro_id}:${distro_codename}-security"; + "${distro_id}ESMApps:${distro_codename}-apps-security"; + "${distro_id}ESM:${distro_codename}-infra-security"; +}; + +Unattended-Upgrade::Package-Blacklist { + // Ajouter ici les paquets à ne jamais mettre à jour automatiquement + // "mysql-server"; + // "postgresql"; +}; + +Unattended-Upgrade::DevRelease "false"; +Unattended-Upgrade::AutoFixInterruptedDpkg "true"; +Unattended-Upgrade::MinimalSteps "true"; +Unattended-Upgrade::InstallOnShutdown "false"; +Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; +Unattended-Upgrade::Remove-New-Unused-Dependencies "true"; +Unattended-Upgrade::Remove-Unused-Dependencies "true"; +Unattended-Upgrade::Automatic-Reboot "false"; +Unattended-Upgrade::Automatic-Reboot-WithUsers "false"; +Unattended-Upgrade::Automatic-Reboot-Time "03:00"; + +Unattended-Upgrade::Mail "root"; +Unattended-Upgrade::MailReport "on-change"; + +Unattended-Upgrade::SyslogEnable "true"; +Unattended-Upgrade::SyslogFacility "daemon"; +EOF + + cat > /etc/apt/apt.conf.d/20auto-upgrades <<'EOF' +APT::Periodic::Update-Package-Lists "1"; +APT::Periodic::Download-Upgradeable-Packages "1"; +APT::Periodic::Unattended-Upgrade "1"; +APT::Periodic::AutocleanInterval "7"; +APT::Periodic::Verbose "1"; +EOF + + # Tester la configuration + unattended-upgrade --dry-run --debug + + systemctl enable unattended-upgrades + systemctl restart unattended-upgrades + + success "Mises à jour automatiques configurées" +} + +# ============================================================================ +# CONFIGURATION AUDITD +# ============================================================================ + +configure_auditd() { + log "Configuration d'auditd (audit système)..." + + if ! command -v auditctl &> /dev/null; then + warn "auditd non installé, passage" + return 0 + fi + + # Règles d'audit personnalisées + cat > /etc/audit/rules.d/hardening.rules <<'EOF' +# Règles d'audit - Hardening Script +# Supprimer toutes les règles précédentes +-D + +# Buffer +-b 8192 + +# Échec d'audit +-f 1 + +# Surveiller les modifications de configuration +-w /etc/passwd -p wa -k identity +-w /etc/group -p wa -k identity +-w /etc/shadow -p wa -k identity +-w /etc/gshadow -p wa -k identity +-w /etc/security/opasswd -p wa -k identity + +# Surveiller les modifications sudo +-w /etc/sudoers -p wa -k sudoers +-w /etc/sudoers.d/ -p wa -k sudoers + +# Surveiller les commandes privilégiées +-a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged +-a always,exit -F path=/usr/bin/su -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged + +# Surveiller les modifications du système de fichiers +-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts +-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts + +# Surveiller les suppressions +-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete +-a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete + +# Surveiller les changements de permissions +-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod + +# Surveiller les accès réseau +-a always,exit -F arch=b64 -S socket -S connect -k network_connect +-a always,exit -F arch=b32 -S socket -S connect -k network_connect + +# Surveiller les modifications de configuration réseau +-w /etc/network/ -p wa -k network_modifications +-w /etc/sysconfig/network-scripts/ -p wa -k network_modifications + +# Surveiller les modifications SSH +-w /etc/ssh/sshd_config -p wa -k sshd_config + +# Surveiller les logs +-w /var/log/wtmp -p wa -k logins +-w /var/log/btmp -p wa -k logins +-w /var/log/lastlog -p wa -k logins + +# Surveiller les modules kernel +-w /sbin/insmod -p x -k modules +-w /sbin/rmmod -p x -k modules +-w /sbin/modprobe -p x -k modules + +# Rendre les règles immuables (nécessite un reboot pour changer) +-e 2 +EOF + + # Recharger les règles + systemctl enable auditd + systemctl restart auditd + + success "Auditd configuré" +} + +# ============================================================================ +# CONFIGURATION APPARMOR +# ============================================================================ + +configure_apparmor() { + log "Configuration d'AppArmor..." + + if ! command -v aa-status &> /dev/null; then + warn "AppArmor non installé, passage" + return 0 + fi + + # Activer AppArmor + systemctl enable apparmor + systemctl start apparmor + + # Activer tous les profils en mode enforce + aa-enforce /etc/apparmor.d/* 2>/dev/null || true + + # Afficher le statut + aa-status + + success "AppArmor configuré" +} + +# ============================================================================ +# SÉCURISATION DU GRUB +# ============================================================================ + +secure_grub() { + log "Sécurisation du bootloader GRUB..." + + if [[ ! -f /etc/default/grub ]]; then + warn "GRUB non trouvé, passage" + return 0 + fi + + [[ ! -f /etc/default/grub.bak ]] && cp /etc/default/grub /etc/default/grub.bak + + # Ajouter les paramètres de sécurité au kernel + if ! grep -q "GRUB_CMDLINE_LINUX.*audit=1" /etc/default/grub; then + sed -i 's/GRUB_CMDLINE_LINUX="/GRUB_CMDLINE_LINUX="audit=1 /' /etc/default/grub + fi + + # Générer un mot de passe GRUB si demandé + read -p "Voulez-vous protéger GRUB par mot de passe? (y/N) " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + log "Génération du mot de passe GRUB..." + grub-mkpasswd-pbkdf2 | tee /tmp/grub-password.txt + warn "Copiez le hash PBKDF2 et ajoutez-le manuellement dans /etc/grub.d/40_custom" + warn "Exemple: set superusers=\"root\"" + warn " password_pbkdf2 root " + fi + + # Mettre à jour GRUB + update-grub + + success "GRUB sécurisé" +} + +# ============================================================================ +# SÉCURISATION DES PARTITIONS +# ============================================================================ + +secure_partitions() { + log "Vérification de la sécurisation des partitions..." + + # Créer une copie de fstab + [[ ! -f /etc/fstab.bak ]] && cp /etc/fstab /etc/fstab.bak + + # Suggestions pour /tmp, /var/tmp, /dev/shm + info "Vérification des options de montage sécurisées..." + + local suggestions="" + + # Vérifier /tmp + if mount | grep -q "on /tmp "; then + if ! mount | grep "on /tmp " | grep -q "noexec"; then + suggestions+="- /tmp devrait être monté avec noexec,nodev,nosuid\n" + fi + else + suggestions+="- Envisagez de créer une partition séparée pour /tmp\n" + fi + + # Vérifier /var/tmp + if mount | grep -q "on /var/tmp "; then + if ! mount | grep "on /var/tmp " | grep -q "noexec"; then + suggestions+="- /var/tmp devrait être monté avec noexec,nodev,nosuid\n" + fi + fi + + # Vérifier /dev/shm + if ! mount | grep "on /dev/shm " | grep -q "noexec"; then + suggestions+="- /dev/shm devrait être monté avec noexec,nodev,nosuid\n" + fi + + # Vérifier /home + if mount | grep -q "on /home "; then + if ! mount | grep "on /home " | grep -q "nodev"; then + suggestions+="- /home devrait être monté avec nodev\n" + fi + fi + + if [[ -n "$suggestions" ]]; then + warn "Suggestions de sécurisation des partitions:" + echo -e "$suggestions" + warn "Ces modifications doivent être faites manuellement dans /etc/fstab" + else + success "Partitions correctement sécurisées" + fi +} + +# ============================================================================ +# CONFIGURATION DES LOGS +# ============================================================================ + +configure_logging() { + log "Configuration avancée des logs..." + + # Configuration rsyslog pour logs centralisés + cat > /etc/rsyslog.d/99-hardening.conf <<'EOF' +# Configuration rsyslog - Hardening Script + +# Logger les messages authpriv séparément +authpriv.* /var/log/auth.log + +# Logger les cron jobs +cron.* /var/log/cron.log + +# Logger les messages kernel +kern.* /var/log/kern.log + +# Logger tous les messages d'urgence +*.emerg :omusrmsg:* + +# Rotation et rétention +$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat +EOF + + systemctl restart rsyslog + + # Configuration logrotate pour conservation + cat > /etc/logrotate.d/hardening <<'EOF' +/var/log/auth.log +/var/log/cron.log +/var/log/kern.log +{ + rotate 90 + daily + missingok + notifempty + compress + delaycompress + sharedscripts + postrotate + /usr/lib/rsyslog/rsyslog-rotate + endscript +} +EOF + + success "Logging configuré" +} + +# ============================================================================ +# SCAN ET AUDIT FINAL +# ============================================================================ + +run_security_scan() { + log "Exécution du scan de sécurité final..." + + local report_file="${STATE_DIR}/security_report_$(date +%Y%m%d_%H%M%S).txt" + + { + echo "==========================================" + echo "RAPPORT DE SÉCURITÉ" + echo "Date: $(date)" + echo "Hostname: $(hostname)" + echo "==========================================" + echo "" + + # Lynis + if command -v lynis &> /dev/null; then + echo "=== AUDIT LYNIS ===" + lynis audit system --quick --quiet + echo "" + fi + + # Vérification des paquets + echo "=== VÉRIFICATION INTÉGRITÉ PAQUETS ===" + debsums -s 2>&1 | head -20 + echo "" + + # Rootkit check + if command -v chkrootkit &> /dev/null; then + echo "=== SCAN ROOTKIT (chkrootkit) ===" + chkrootkit -q 2>&1 | head -20 + echo "" + fi + + if command -v rkhunter &> /dev/null; then + echo "=== SCAN ROOTKIT (rkhunter) ===" + rkhunter --check --skip-keypress --report-warnings-only 2>&1 | head -20 + echo "" + fi + + # Ports ouverts + echo "=== PORTS OUVERTS ===" + ss -tulpn + echo "" + + # Services actifs + echo "=== SERVICES ACTIFS ===" + systemctl list-units --type=service --state=running + echo "" + + # Utilisateurs avec shell + echo "=== UTILISATEURS AVEC SHELL ===" + grep -v "/nologin\|/false" /etc/passwd + echo "" + + # Dernières connexions + echo "=== DERNIÈRES CONNEXIONS ===" + last -n 20 + echo "" + + } | tee "$report_file" + + success "Rapport de sécurité généré: $report_file" +} + +# ============================================================================ +# FONCTIONS D'AIDE ET D'INFORMATION +# ============================================================================ + +show_help() { + cat </dev/null || echo "inconnue") + echo -e "${GREEN}[✓]${NC} $task (${timestamp})" + else + echo -e "${RED}[✗]${NC} $task" + fi + done +} + +list_tasks() { + echo "Tâches disponibles:" + echo " - backup_configs" + echo " - update_system" + echo " - install_tools" + echo " - fail2ban" + echo " - ufw" + echo " - ssh" + echo " - sysctl" + echo " - password_policy" + echo " - limits" + echo " - disable_services" + echo " - clamav" + echo " - aide" + echo " - auto_updates" + echo " - auditd" + echo " - apparmor" + echo " - grub" + echo " - partitions" + echo " - logging" + echo " - security_scan" +} + +reset_all_tasks() { + warn "Réinitialisation de toutes les tâches..." + rm -rf "$STATE_DIR"/*.done "$STATE_DIR"/*.timestamp + success "Toutes les tâches ont été réinitialisées" +} + +# ============================================================================ +# FONCTION PRINCIPALE +# ============================================================================ + +main() { + local force_mode=false + local skip_tasks=() + local only_task="" + + # Parser les arguments + while [[ $# -gt 0 ]]; do + case $1 in + -h|--help) + show_help + exit 0 + ;; + -v|--version) + echo "Version $SCRIPT_VERSION" + exit 0 + ;; + -f|--force) + force_mode=true + shift + ;; + -s|--skip) + skip_tasks+=("$2") + shift 2 + ;; + -o|--only) + only_task="$2" + shift 2 + ;; + --status) + show_status + exit 0 + ;; + --reset) + check_root + reset_all_tasks + exit 0 + ;; + --list-tasks) + list_tasks + exit 0 + ;; + *) + error "Option inconnue: $1" + show_help + exit 1 + ;; + esac + done + + # Initialisation + mkdir -p "$STATE_DIR" + touch "$LOG_FILE" + + log "========================================" + log "Script de Durcissement Linux v${SCRIPT_VERSION}" + log "Début: $(date)" + log "========================================" + echo "" + + # Vérifications préliminaires + check_root + check_distribution + check_disk_space + check_internet_connectivity + + # Acquérir le verrou + acquire_lock + + # Si mode "only", exécuter uniquement la tâche spécifiée + if [[ -n "$only_task" ]]; then + info "Mode: exécution de la tâche '$only_task' uniquement" + case $only_task in + backup_configs) run_task "backup_configs" backup_configs "$force_mode" ;; + update_system) run_task "update_system" update_system "$force_mode" ;; + install_tools) run_task "install_tools" install_security_tools "$force_mode" ;; + fail2ban) run_task "fail2ban" configure_fail2ban "$force_mode" ;; + ufw) run_task "ufw" configure_ufw "$force_mode" ;; + ssh) run_task "ssh" configure_ssh "$force_mode" ;; + sysctl) run_task "sysctl" configure_sysctl "$force_mode" ;; + password_policy) run_task "password_policy" configure_password_policy "$force_mode" ;; + limits) run_task "limits" configure_limits "$force_mode" ;; + disable_services) run_task "disable_services" disable_unnecessary_services "$force_mode" ;; + clamav) run_task "clamav" configure_clamav "$force_mode" ;; + aide) run_task "aide" configure_aide "$force_mode" ;; + auto_updates) run_task "auto_updates" configure_auto_updates "$force_mode" ;; + auditd) run_task "auditd" configure_auditd "$force_mode" ;; + apparmor) run_task "apparmor" configure_apparmor "$force_mode" ;; + grub) run_task "grub" secure_grub "$force_mode" ;; + partitions) run_task "partitions" secure_partitions "$force_mode" ;; + logging) run_task "logging" configure_logging "$force_mode" ;; + security_scan) run_task "security_scan" run_security_scan "$force_mode" ;; + *) + error "Tâche inconnue: $only_task" + list_tasks + exit 1 + ;; + esac + exit 0 + fi + + # Exécution normale de toutes les tâches + info "Mode: exécution complète (utilisez --only pour exécuter une seule tâche)" + + # Tableau des tâches à exécuter (dans l'ordre) + local task_execution_plan=( + "backup_configs:Sauvegarde des configurations" + "update_system:Mise à jour système" + "install_tools:Installation outils sécurité" + "ssh:Configuration SSH sécurisée" + "ufw:Configuration pare-feu UFW" + "fail2ban:Configuration Fail2ban" + "sysctl:Configuration paramètres kernel" + "password_policy:Politique mots de passe" + "limits:Limites système" + "disable_services:Désactivation services" + "clamav:Configuration antivirus" + "aide:Configuration détection intrusion" + "auto_updates:Mises à jour automatiques" + "auditd:Configuration audit système" + "apparmor:Configuration AppArmor" + "grub:Sécurisation GRUB" + "partitions:Sécurisation partitions" + "logging:Configuration logs" + "security_scan:Scan sécurité final" + ) + + # Exécution des tâches + local total_tasks=${#task_execution_plan[@]} + local current_task=0 + local failed_tasks=() + + for task_entry in "${task_execution_plan[@]}"; do + IFS=':' read -r task_name task_description <<< "$task_entry" + current_task=$((current_task + 1)) + + # Vérifier si la tâche doit être ignorée + if [[ " ${skip_tasks[*]} " == *" $task_name "* ]]; then + info "[$current_task/$total_tasks] Ignoré: $task_description" + continue + fi + + info "[$current_task/$total_tasks] Début: $task_description" + + # Exécuter la tâche + case $task_name in + backup_configs) + run_task "$task_name" backup_configs "$force_mode" || failed_tasks+=("$task_name") + ;; + update_system) + run_task "$task_name" update_system "$force_mode" || failed_tasks+=("$task_name") + ;; + install_tools) + run_task "$task_name" install_security_tools "$force_mode" || failed_tasks+=("$task_name") + ;; + ssh) + run_task "$task_name" configure_ssh "$force_mode" || failed_tasks+=("$task_name") + ;; + ufw) + run_task "$task_name" configure_ufw "$force_mode" || failed_tasks+=("$task_name") + ;; + fail2ban) + run_task "$task_name" configure_fail2ban "$force_mode" || failed_tasks+=("$task_name") + ;; + sysctl) + run_task "$task_name" configure_sysctl "$force_mode" || failed_tasks+=("$task_name") + ;; + password_policy) + run_task "$task_name" configure_password_policy "$force_mode" || failed_tasks+=("$task_name") + ;; + limits) + run_task "$task_name" configure_limits "$force_mode" || failed_tasks+=("$task_name") + ;; + disable_services) + run_task "$task_name" disable_unnecessary_services "$force_mode" || failed_tasks+=("$task_name") + ;; + clamav) + run_task "$task_name" configure_clamav "$force_mode" || failed_tasks+=("$task_name") + ;; + aide) + run_task "$task_name" configure_aide "$force_mode" || failed_tasks+=("$task_name") + ;; + auto_updates) + run_task "$task_name" configure_auto_updates "$force_mode" || failed_tasks+=("$task_name") + ;; + auditd) + run_task "$task_name" configure_auditd "$force_mode" || failed_tasks+=("$task_name") + ;; + apparmor) + run_task "$task_name" configure_apparmor "$force_mode" || failed_tasks+=("$task_name") + ;; + grub) + run_task "$task_name" secure_grub "$force_mode" || failed_tasks+=("$task_name") + ;; + partitions) + run_task "$task_name" secure_partitions "$force_mode" || failed_tasks+=("$task_name") + ;; + logging) + run_task "$task_name" configure_logging "$force_mode" || failed_tasks+=("$task_name") + ;; + security_scan) + run_task "$task_name" run_security_scan "$force_mode" || failed_tasks+=("$task_name") + ;; + esac + + echo "" + done + + # Résumé final + log "========================================" + log "EXÉCUTION TERMINÉE" + log "Date: $(date)" + log "Durée: ~$(($SECONDS / 60)) minutes" + log "========================================" + + if [[ ${#failed_tasks[@]} -eq 0 ]]; then + success "Toutes les tâches ont été exécutées avec succès!" + success "Le système a été durci avec succès." + + # Afficher les recommandations finales + echo "" + info "=== RECOMMANDATIONS FINALES ===" + info "1. Testez votre connexion SSH sur le port ${SSH_PORT}" + info "2. Vérifiez les règles UFW: ufw status verbose" + info "3. Testez Fail2ban: fail2ban-client status" + info "4. Redémarrez le système pour appliquer tous les changements" + info "5. Consultez le rapport de sécurité dans: ${STATE_DIR}/" + + echo "" + warn "IMPORTANT: Sauvegardez vos clés SSH et mots de passe!" + warn "Le redémarrage est recommandé pour appliquer tous les changements." + + else + error "Certaines tâches ont échoué: ${failed_tasks[*]}" + warn "Consultez le fichier de log: $LOG_FILE" + warn "Vous pouvez réessayer les tâches échouées avec: $0 --only " + fi + + echo "" + info "Fichier de log complet: $LOG_FILE" + info "État des tâches: $0 --status" + + # Libérer le verrou + release_lock +} + +# ============================================================================ +# POINT D'ENTRÉE DU SCRIPT +# ============================================================================ + +# Vérifier que le script n'est pas sourcé +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "$@" +fi + +# ============================================================================ +# NOTES DE SÉCURITÉ FINALES +# ============================================================================ + +# Ce script effectue les actions suivantes: +# 1. Sauvegarde des configurations existantes +# 2. Mise à jour complète du système +# 3. Installation des outils de sécurité essentiels +# 4. Configuration SSH sécurisée (port personnalisé, désactivation root login) +# 5. Configuration du pare-feu UFW avec règles restrictives +# 6. Configuration Fail2ban pour prévention des attaques par force brute +# 7. Hardening des paramètres kernel via sysctl +# 8. Politique de mots de passe stricte +# 9. Limites système pour prévenir les DoS +# 10. Désactivation des services non nécessaires +# 11. Configuration antivirus ClamAV +# 12. Configuration AIDE pour détection d'intrusion +# 13. Mises à jour automatiques de sécurité +# 14. Configuration auditd pour audit système +# 15. Activation d'AppArmor +# 16. Sécurisation du bootloader GRUB +# 17. Recommandations pour sécurisation des partitions +# 18. Configuration avancée des logs +# 19. Scan de sécurité final avec génération de rapport + +# AVERTISSEMENT: +# - Testez toujours dans un environnement de test avant la production +# - Assurez-vous d'avoir un accès de secours (console, KVM, etc.) +# - Conservez une sauvegarde fonctionnelle du système +# - Certaines configurations peuvent nécessiter un redémarrage \ No newline at end of file