2025-04-19 21:29:57 +02:00

859 lines
33 KiB
Bash

#!/bin/bash
# Variables Global
VERSION="1.2"
VERBOSE=false
BACKUP_DIR="/root/security-backup-$(date +%Y%m%d_%H%M%S)"
LOG_FILE="/var/log/security-hardening.log"
SCRIPT_NAME=$(basename "$0")
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\[\033[0;34m\]'
PINK='\[\033[0;35m\]'
NOCOLOR='\033[0m'
# Fonction pour la présentatation du script
start() {
echo -e " " | tee -a "$LOG_FILE"
echo -e " ############################################################################## " | tee -a "$LOG_FILE"
echo -e " # " | tee -a "$LOG_FILE"
echo -e " # ██ ██ █████ ██████ ██████ ███████ ███ ██ ██ ███ ██ ██████ " | tee -a "$LOG_FILE"
echo -e " # ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ " | tee -a "$LOG_FILE"
echo -e " # ███████ ███████ ██████ ██ ██ █████ ██ ██ ██ ██ ██ ██ ██ ██ ███ " | tee -a "$LOG_FILE"
echo -e " # ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ " | tee -a "$LOG_FILE"
echo -e " # ██ ██ ██ ██ ██ ██ ██████ ███████ ██ ████ ██ ██ ████ ██████ " | tee -a "$LOG_FILE"
echo -e " # " | tee -a "$LOG_FILE"
echo -e " # Script de renforcement de la sécurité Linux v$VERSION" | tee -a "$LOG_FILE"
echo -e " # " | tee -a "$LOG_FILE"
echo -e " ############################################################################## " | tee -a "$LOG_FILE"
echo -e " " | tee -a "$LOG_FILE"
}
# Fonction pour l'enregistrement des logs
log() {
local message="${YELLOW} $(date '+%Y-%m-%d %H:%M:%S') ${NOCOLOR} : ${GREEN} $1 ${NOCOLOR}"
echo -e "$message" | tee -a "$LOG_FILE"
$VERBOSE && echo -e " ${BLUE} * $message"
}
# Fonction pour la gestion des warnings
handle_warning() {
log "${PINK} - Avertissement : $1 ${NOCOLOR}"
}
# Fonction pour la gestion des erreurs
handle_error() {
log "${RED} - Erreur : $1 ${NOCOLOR}"
exit 1
}
# Fonction d'installation des paquets
install_package() {
log "Installion $1 ..."
DEBIAN_FRONTEND=noninteractive apt install -y "$1" || handle_error "Échec de l'installation $1"
}
# Fonction de sauvegarde des fichiers
backup_files() {
log "Sauvegarde des fichiers ..."
mkdir -p "$BACKUP_DIR" || handle_error "Échec de la création du répertoire de sauvegarde"
local files_to_backup=(
"/etc/default/grub"
"/etc/ssh/sshd_config"
"/etc/ssh/ssh_config"
"/etc/snmp/snmpd.conf"
"/etc/pam.d/common-password"
"/etc/login.defs"
"/etc/sysctl.conf"
)
for file in "${files_to_backup[@]}"; do
if [ -f "$file" ]; then
cp "$file" "$BACKUP_DIR/" || log "Avertissement : Échec de la sauvegarde $file"
else
log "Avertissement: $file introuvable, sauvegarde ignorée"
fi
done
log " * Sauvegarde créée en $BACKUP_DIR"
}
# Fonction de restauration à partir d'une sauvegarde
restore_backup() {
if [ -d "$BACKUP_DIR" ]; then
for file in "$BACKUP_DIR"/*; do
cp "$file" "$(dirname "$(readlink -f "$file")")" || log "Avertissement : Échec de la restauration $(basename "$file")"
done
log "Configurations rétablies à partir de $BACKUP_DIR"
else
log "Répertoire de sauvegarde introuvable. Impossible de restaurer."
fi
}
# Fonction d'affichage de l'aide
display_help() {
echo "Usage: sudo ./$SCRIPT_NAME [OPTIONS]"
echo "Options:"
echo " -h, --help Display this help message"
echo " -v, --verbose Enable verbose output"
echo " --version Display script version"
echo " --dry-run Perform a dry run without making changes"
echo " --restore Restore system from the most recent backup"
exit 0
}
# Fonction d'affichage de la version
display_version() {
echo "Script de renforcement de la sécurité Linux v$VERSION"
exit 0
}
# Fonction de vérification des autorisations pour Ubuntu
check_permissions() {
if [ "$EUID" -ne 0 ]; then
echo -e "${RED} * Ce script doit être exécuté avec les privilèges sudo."
echo -e "${RED} * Veuillez l'exécuter à nouveau en utilisant : sudo $0"
exit 1
fi
}
# Fonction de controle de la présence d'un proxy web
check_proxy() {
log "Test présence proxy web ..."
if apt update > /dev/null 2>&1; then
log " * Aucune configuration proxy requise. La mise à jour des paquets a réussi."
else
log " * Erreur lors de la mise à jour des paquets. Vérification des besoins en proxy web ..."
# Tester la connectivité Internet
if ping -c 1 google.com > /dev/null 2>&1; then
log "La connectivité Internet est présente, mais apt ne fonctionne pas. Configuration du proxy requise."
cp 00-proxy/02proxy /etc/apt/apt.conf.d/02proxy || handle_error "Échec de la copie du fichier de configuration du proxy"
log " * Configuration du proxy appliquée."
handle_warning "Essayez de nouveau la mise à jour des paquets avec 'apt update'."
else
handle_error "Aucune connectivité Internet. Vérifiez votre connexion réseau."
fi
fi
}
# Fonction de vérification des exigences du système
check_requirements() {
log "Identification du système ..."
if ! command -v lsb_release &> /dev/null; then
handle_error "La commande lsb_release n'a pas été trouvée. Ce script nécessite un système basé sur Ubuntu et Debian."
fi
local os_name=$(lsb_release -si)
local os_version=$(lsb_release -sr)
if [[ "$os_name" != "Ubuntu" && "$os_name" != "Debian" ]]; then
handle_error "Ce script est conçu pour les systèmes basés sur Ubuntu ou Debian. OS detecté : $os_name"
if [[ $(echo "$os_version < 18.04" | bc) -eq 1 ]]; then
handle_error "Ce script nécessite Ubuntu 18.04 ou une version ultérieure. Version detecté : $os_version"
elif [[ "$os_name" == "Debian" && $(echo "$os_version < 12.0" | bc) -eq 1 ]]; then
handle_error "Ce script nécessite Debian 12.0 ou une version ultérieure. Version detecté : $os_version"
fi
fi
log " * La vérification de la configuration requise a été effectuée. OS: $os_name VERSION: $os_version"
}
# Fonction de mise à jour du système
update_system() {
log "Mise à jour du système ..."
# Mise à jour de la liste des paquets
apt update -y || handle_error "Échec de la mise à jour du système"
# Mise à niveau du système
DEBIAN_FRONTEND=noninteractive apt full-upgrade -y || handle_error "Échec de la mise à niveau du système"
}
# Fonction de mise en place de clé SSH
setup_ssh() {
log "Installation et configuration des clés SSH ..."
# Demande à l'utilisateur s'il souhaite appliquer les clé SSH
local apply_key_ssh
read -p "Voulez-vous appliquer les clé SSH ? (y/N): " apply_key_ssh
#
case $apply_key_ssh in
[Yy]* )
log "Application des clé ssh ..."
# Copie du fichier des clés SSH
cp 01-key/authorized_keys /root/.ssh/authorized_keys || handle_error "Échec de la copie de authorized_keys"
# Mise en place des droits
chmod 600 /root/.ssh/authorized_keys || handle_error "Échec de la mise en place des droits sur le fichier authorized_keys"
chmod 700 /root/.ssh || handle_error "Échec de la mise en place des droits sur le répertoire .ssh"
# Création du répertoire authorized_keys
mkdir -p /etc/ssh/authorized_keys/ || handle_error "Échec de la création du répertoire authorized_keys"
cd /etc/ssh/authorized_keys/ >> /dev/null
# Création du lien symbolique
ln -s /root/.ssh/authorized_keys root || handle_error "Échec de la création du lien symbolique"
#
local file="/etc/ssh/sshd_config"
local line=`grep -n "^.*AuthorizedKeysFile.*authorized_keys.*" $file | cut -d ":" -f 1`
#echo $line
# Vérification de la présence de la ligne AuthorizedKeysFile
if [ -z "$line" ]; then
echo "AuthorizedKeysFile .ssh/authorized_keys" | tee -a $file
else
sed -i ''$line'c\AuthorizedKeysFile .ssh/authorized_keys' $file > /dev/null || handle_error "Échec de "
fi
#
line=`grep -n "^.*AuthorizedKeysFile.*authorized_keys.*" $file | cut -d ":" -f 1` || handle_error "Échec de "
# Redémarrage du service sshd
systemctl restart sshd || handle_error "Échec du redémarrage du service SSH"
log " * Mise en place de clé SSH "
;;
* )
log " * Sauter la mise en place de clé SSH"
;;
esac
}
# Fonction de configuration du prompt de connexion
setup_prompt() {
log "Installation et configuration du prompt de connexion ..."
# Demande à l'utilisateur s'il souhaite appliquer le prompt de connexion
local apply_prompt
read -p "Voulez-vous appliquer le prompt de connexion ? (y/N): " apply_prompt
#
case $apply_prompt in
[Yy]* )
log "Application du prompt ..."
# Copie des fichiers de configuration
cp 02-prompt/banner /etc/banner || handle_error "Échec de la copie de banner"
cp 02-prompt/00-basic /etc/update-motd.d/00-basic || handle_error "Échec de la copie de 00-basic"
# Mise en place des droits
chmod +x /etc/update-motd.d/00-basic || handle_error "Échec de la mise en place des droits sur 00-basic"
# Redémarrage du service sshd
systemctl restart sshd >> /dev/null
log " * Mise en place du prompt de connexion"
;;
* )
log " * Sauter la mise en place du prompt de connexion"
;;
esac
}
# Fonction de configuration du pare-feu
setup_firewall() {
log "Installation et configuration du pare-feu ..."
# Demande à l'utilisateur s'il souhaite appliquer le prompt de connexion
local apply_firewall
read -p "Voulez-vous appliquer la configuration firewall ? (y/N): " apply_firewall
#
case $apply_firewall in
[Yy]* )
log "Application du prompt ..."
# Vérification de la présence de UFW
install_package "ufw"
# Vérification de la présence de iptables
ufw default deny incoming || handle_error "Échec de la définition de la politique de réception par défaut de l'UFW"
ufw default allow outgoing || handle_error "Échec de la définition de la politique de sortie par défaut de l'UFW"
ufw limit ssh comment 'Allow SSH with rate limiting' || handle_error "Échec de la configuration de SSH dans UFW"
ufw allow 80/tcp comment 'Allow HTTP' || handle_error "Échec de l'autorisation de HTTP dans l'UFW"
ufw allow 443/tcp comment 'Allow HTTPS' || handle_error "Échec de l'autorisation de HTTPS dans l'UFW"
ufw allow 22/tcp comment 'Allow HTTPS' || handle_error "Échec de l'autorisation de SSH dans l'UFW"
# Demande à l'utilisateur s'il souhaite appliquer des règles de pare-feu spécifiques à IPv6
local apply_ipv6_rules
read -p "Voulez-vous appliquer des règles de pare-feu spécifiques à IPv6 ? (y/N): " apply_ipv6_rules
# Application des règles de pare-feu spécifiques à IPv6
case $apply_ipv6_rules in
[Yy]* )
log "Application de règles de pare-feu spécifiques à IPv6 ..."
ufw allow in on lo || handle_error "Échec de l'autorisation du trafic de bouclage"
ufw allow out on lo || handle_error "Échec de l'autorisation du trafic de bouclage"
ufw deny in from ::/0 || handle_error "Échec du refus de l'ensemble du trafic IPv6 entrant"
ufw allow out to ::/0 || handle_error "Échec de l'autorisation de tout le trafic IPv6 sortant"
log "Règles de pare-feu IPv6 appliquées"
;;
* )
log "Sauter les règles de pare-feu spécifiques à IPv6"
;;
esac
# Activation de la journalisation UFW
ufw logging on || handle_error "Échec de l'activation de la journalisation UFW"
ufw --force enable || handle_error "Échec de l'activation de l'UFW"
log " * Pare-feu configuré et activé"
;;
* )
log " * Sauter la mise en place du pare-feu"
;;
esac
}
# Fonction de configuration de Fail2Ban
setup_fail2ban() {
log "Installation et configuration de Fail2Ban ..."
# Demande à l'utilisateur s'il souhaite installer Fail2Ban
local apply_fail2ban
read -p "Voulez-vous appliquer la configuration Fail2Ban ? (y/N): " apply_fail2ban
#
case $apply_fail2ban in
[Yy]* )
# Vérification de la présence de Fail2Ban
install_package "fail2ban"
# Copie de la configuration locale de Fail2Ban
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local || handle_error "Échec de la création de la configuration locale de Fail2Ban"
cp 03-Fail2ban/etc/fail2ban/jail.conf /etc/fail2ban/jail.d/ || handle_error "Échec de la ccopie des configurations Fail2Ban"
# Configuration de Fail2Ban
sed -i 's/bantime = 10m/bantime = 1h/' /etc/fail2ban/jail.local || handle_error "Échec de la mise en place de Fail2Ban bantime"
sed -i 's/maxretry = 5/maxretry = 3/' /etc/fail2ban/jail.local || handle_error "Échec de la définition de Fail2Ban maxretry"
#
systemctl enable fail2ban || handle_error "Échec de l'activation du service Fail2Ban"
systemctl start fail2ban || handle_error "Échec du démarrage du service Fail2Ban"
log "Fail2Ban configuré et démarré"
;;
* )
log " * Sauter de l'installation de fail2ban"
;;
esac
}
# Fonction de configuration de ClamAV
setup_clamav() {
log "Installation et mise à jour de ClamAV ..."
# Demande à l'utilisateur s'il souhaite installer ClamAV
local apply_clamav
read -p "Voulez-vous appliquer la configuration firewall ? (y/N): " apply_clamav
#
case $apply_clamav in
[Yy]* )
# Vérification de la présence de ClamAV
install_package "clamav"
install_package "clamav-daemon"
# Vérification de la présence de Freshclam
systemctl stop clamav-freshclam || log "Avertissement : Échec de l'arrêt de clamav-freshclam"
freshclam || log "Avertissement : La mise à jour de la base de données de ClamAV a échoué"
# Configuration de Freshclam
systemctl start clamav-freshclam || handle_error "Échec du démarrage de clamav-freshclam"
systemctl enable clamav-freshclam || handle_error "Échec de l'activation de clamav-freshclam"
log "ClamAV installé et mis à jour"
;;
* )
log " * Sauter de l'installation de ClamAV"
;;
esac
}
# Fonction de configuration de SNMP
setup_snmp() {
log "Installation et configuration de SNMP ..."
# Demande à l'utilisateur s'il souhaite installer SNMP
local apply_snmp
read -p "Voulez-vous appliquer la configuration SNMP ? (y/N): " apply_snmp
#
case $apply_snmp in
[Yy]* )
# Vérification de la présence de SNMP
install_package "snmpd"
install_package "snmp"
# Copie de la configuration SNMP
cp 05-snmp/snmpd.conf /etc/snmp/snmpd.conf >> /dev/null
systemctl reload daemon
systemctl enable snmpd || handle_error "Échec de l'activation du service SNMP"
systemctl start snmpd || handle_error "Échec du démarrage du service SNMP"
log "SNMP installé et configuré"
;;
* )
log " * Sauter de l'installation de SNMP"
;;
esac
}
# Fonction permettant de désactiver l'accès à la racine
disable_root() {
log "Vérification de la présence d'utilisateurs non root ayant des privilèges sudo ..."
# Obtenir la liste des utilisateurs ayant des privilèges sudo
sudo_users=$(getent group sudo | cut -d: -f4 | tr ',' '\n' | grep -v "^root$")
# Vérifier s'il y a des utilisateurs non root avec des privilèges sudo
if [ -z "$sudo_users" ]; then
log "Attention : Aucun utilisateur non-root avec des privilèges sudo n'a été trouvé. Sauter la désactivation de la connexion root pour plus de sécurité."
echo "Veuillez créer un utilisateur non root avec les privilèges sudo avant de désactiver la connexion root."
return
fi
log "Des utilisateurs non root avec des privilèges sudo ont été trouvés. Procédure de désactivation de l'accès à la racine ..."
# Désactiver l'accès à root
if passwd -l root; then
log "La connexion à root a été désactivée avec succès."
else
handle_error "Échec du verrouillage du compte root"
fi
# Désactiver la connexion SSH de root à titre de précaution supplémentaire
if grep -q "^PermitRootLogin" /etc/ssh/sshd_config; then
sed -i 's/^#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config || handle_error "Échec de la désactivation de la connexion SSH de root dans sshd_config"
else
echo "PermitRootLogin no" | tee -a /etc/ssh/sshd_config > /dev/null || handle_error "Échec de l'ajout de PermitRootLogin no à sshd_config"
fi
# Redémarrer le service SSH pour appliquer les changements
systemctl reload daemon
systemctl restart sshd || handle_error "Échec du redémarrage du service SSH"
log "La connexion de root a été désactivée et la connexion à root par SSH a été explicitement interdite."
}
# Fonction de suppression des paquets inutiles
remove_packages() {
log "Suppression des paquets inutiles ..."
DEBIAN_FRONTEND=noninteractive apt remove --purge -y telnetd nis yp-tools rsh-client rsh-redone-client xinetd || log "Avertissement : Échec de la suppression de certains paquets"
apt autoremove -y || log "Avertissement : échec de l'autoremove"
log "Suppression des paquets inutiles"
}
# Fonction de mise en place de l'audit
setup_audit() {
log "Configuration des règles d'audit ..."
# Vérification de la présence d'auditd
install_package "auditd"
local audit_rules=(
"-w /etc/passwd -p wa -k identity"
"-w /etc/group -p wa -k identity"
"-w /etc/shadow -p wa -k identity"
"-w /etc/sudoers -p wa -k sudoers"
"-w /var/log/auth.log -p wa -k auth_log"
"-w /sbin/insmod -p x -k modules"
"-w /sbin/rmmod -p x -k modules"
"-w /sbin/modprobe -p x -k modules"
"-w /var/log/faillog -p wa -k logins"
"-w /var/log/lastlog -p wa -k logins"
"-w /var/run/utmp -p wa -k session"
"-w /var/log/wtmp -p wa -k session"
"-w /var/log/btmp -p wa -k session"
"-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change"
"-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change"
"-a always,exit -F arch=b64 -S clock_settime -k time-change"
"-a always,exit -F arch=b32 -S clock_settime -k time-change"
"-w /etc/localtime -p wa -k time-change"
)
for rule in "${audit_rules[@]}"; do
echo "$rule" | tee -a /etc/audit/rules.d/audit.rules > /dev/null || handle_error "Échec de l'ajout d'une règle d'audit : $rule"
done
systemctl enable auditd || handle_error "Échec de l'activation du service auditd"
systemctl start auditd || handle_error "Échec du démarrage du service auditd"
log "Règles d'audit configurées et auditd démarré"
}
# Fonction permettant de désactiver les systèmes de fichiers inutilisés
disable_filesystems() {
log "Désactivation des systèmes de fichiers inutilisés ..."
local filesystems=("cramfs" "freevxfs" "jffs2" "hfs" "hfsplus" "squashfs" "udf" "vfat")
for fs in "${filesystems[@]}"; do
echo "install $fs /bin/true" | sudo tee -a /etc/modprobe.d/CIS.conf > /dev/null || handle_error "Échec de la désactivation du système de fichiers : $fs"
done
log "Systèmes de fichiers inutilisés désactivés"
}
# Fonction de sécurisation des paramètres de démarrage
secure_boot() {
log "Sécurisation des paramètres de démarrage ..."
# Fichier de configuration GRUB sécurisé
if [ -f /boot/grub/grub.cfg ]; then
chown root:root /boot/grub/grub.cfg || handle_error "Échec du changement de propriétaire de grub.cfg"
chmod 600 /boot/grub/grub.cfg || handle_error "Échec de la modification des permissions de grub.cfg"
log "Fichier de configuration GRUB sécurisé"
else
log "Avertissement : /boot/grub/grub.cfg n'a pas été trouvé. Ignorer les permissions du fichier GRUB."
fi
# Modifier les paramètres du noyau
if [ -f /etc/default/grub ]; then
# Sauvegarde du fichier original
cp /etc/default/grub /etc/default/grub.bak || handle_error "Échec de la sauvegarde du fichier grub"
# Ajouter ou modifier les paramètres du noyau
local kernel_params="audit=1 net.ipv4.conf.all.rp_filter=1 net.ipv4.conf.all.accept_redirects=0 net.ipv4.conf.all.send_redirects=0"
# Demande si l'utilisateur souhaite désactiver SACK
local disable_sack
read -p "Voulez-vous désactiver TCP SACK ? Ce n'est généralement pas recommandé. (y/N): " disable_sack
case $disable_sack in
[Yy]* )
kernel_params+=" net.ipv4.tcp_sack=0"
log "TCP SACK sera désactivée"
;;
* )
log "TCP SACK restera activée"
;;
esac
sed -i "s/GRUB_CMDLINE_LINUX=\"\"/GRUB_CMDLINE_LINUX=\"$kernel_params\"/" /etc/default/grub || handle_error "Échec de la modification des paramètres du noyau"
# Update GRUB
if command -v update-grub &> /dev/null; then
update-grub || handle_error "Échec de la mise à jour du GRUB"
elif command -v grub2-mkconfig &> /dev/null; then
grub2-mkconfig -o /boot/grub2/grub.cfg || handle_error "Échec de la mise à jour du GRUB"
else
log "Avertissement : Ni update-grub ni grub2-mkconfig n'ont été trouvés. Veuillez mettre à jour GRUB manuellement."
fi
log "Mise à jour des paramètres du noyau"
else
log "Avertissement : /etc/default/grub n'a pas été trouvé. Sauter les modifications des paramètres du noyau."
fi
log "Paramètres de démarrage sécurisés"
}
# Fonction de configuration d'IPv6
configure_ipv6() {
local disable_ipv6
read -p "Voulez-vous désactiver IPv6 ? (y/N): " disable_ipv6
case $disable_ipv6 in
[Yy]* )
log "Désactivation IPv6 ..."
echo "net.ipv6.conf.all.disable_ipv6 = 1" | tee -a /etc/sysctl.conf || handle_error "Échec de la désactivation d'IPv6 (all)"
echo "net.ipv6.conf.default.disable_ipv6 = 1" | tee -a /etc/sysctl.conf || handle_error "Échec de la désactivation d'IPv6 (default)"
echo "net.ipv6.conf.lo.disable_ipv6 = 1" | tee -a /etc/sysctl.conf || handle_error "Échec de la désactivation d'IPv6 (lo)"
sysctl -p || handle_error "Échec de l'application des changements sysctl"
log "IPv6 a été désactivé"
;;
* )
log "IPv6 reste activé"
;;
esac
}
# Fonction de configuration d'AppArmor
setup_apparmor() {
log "Configuration d'AppArmor ..."
if ! command -v apparmor_status &> /dev/null; then
install_package "apparmor"
install_package "apparmor-utils"
else
log "AppArmor est déjà installé. Sauter l'installation."
fi
systemctl reload daemon
systemctl enable apparmor || handle_error "Échec de l'activation du service AppArmor"
systemctl start apparmor || handle_error "Échec du démarrage du service AppArmor"
aa-enforce /etc/apparmor.d/* || log "Avertissement : Échec de l'application de certains profils AppArmor"
log "L'installation d'AppArmor est terminée. Tous les profils sont en mode exécution."
log "Moniteur /var/log/syslog and /var/log/auth.log pour tout problème lié à AppArmor."
}
# Fonction de configuration de NTP
setup_ntp() {
log "Configuration de la synchronisation de l'heure ..."
# Vérifier si systemd-timesyncd est disponible (systèmes Ubuntu modernes)
if systemctl list-unit-files | grep -q systemd-timesyncd.service; then
log "Utilisation de systemd-timesyncd pour la synchronisation temporelle"
systemctl reload daemon
systemctl enable systemd-timesyncd.service || handle_error "Échec de l'activation du service systemd-timesyncd"
systemctl start systemd-timesyncd.service || handle_error "Échec du démarrage du service systemd-timesyncd"
log "systemd-timesyncd installation terminée"
else
# Revenir au protocole NTP traditionnel si systemd-timesyncd n'est pas disponible
log "Utilisation du protocole NTP traditionnel pour la synchronisation du temps"
install_package "ntp"
systemctl reload daemon
systemctl enable ntp || handle_error "Échec de l'activation du service NTP"
systemctl start ntp || handle_error "Échec du démarrage du service NTP"
log "Configuration NTP terminée"
fi
}
# Fonction de configuration de l'AIDE
setup_aide() {
log "Mise en place d'AIDE ..."
install_package "aide"
aideinit || handle_error "Échec de l'initialisation de la base de données AIDE"
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db || handle_error "Échec du transfert de la base de données AIDE"
log "L'installation d'AIDE est terminée et la base de données a été initialisée."
}
# Fonction de configuration de sysctl
configure_sysctl() {
log "Configuration des paramètres sysctl ..."
local sysctl_config=(
"# IP Spoofing protection"
"net.ipv4.conf.all.rp_filter = 1"
"net.ipv4.conf.default.rp_filter = 1"
""
"# Ignore ICMP broadcast requests"
"net.ipv4.icmp_echo_ignore_broadcasts = 1"
""
"# Disable source packet routing"
"net.ipv4.conf.all.accept_source_route = 0"
"net.ipv6.conf.all.accept_source_route = 0"
""
"# Ignore send redirects"
"net.ipv4.conf.all.send_redirects = 0"
"net.ipv4.conf.default.send_redirects = 0"
""
"# Block SYN attacks"
"net.ipv4.tcp_syncookies = 1"
"net.ipv4.tcp_max_syn_backlog = 2048"
"net.ipv4.tcp_synack_retries = 2"
"net.ipv4.tcp_syn_retries = 5"
""
"# Log Martians"
"net.ipv4.conf.all.log_martians = 1"
"net.ipv4.icmp_ignore_bogus_error_responses = 1"
""
"# Ignore ICMP redirects"
"net.ipv4.conf.all.accept_redirects = 0"
"net.ipv6.conf.all.accept_redirects = 0"
""
"# Ignore Directed pings"
"net.ipv4.icmp_echo_ignore_all = 1"
""
"# Enable ASLR"
"kernel.randomize_va_space = 2"
""
"# Increase system file descriptor limit"
"fs.file-max = 65535"
""
"# Allow for more PIDs"
"kernel.pid_max = 65536"
""
"# Protect against kernel pointer leaks"
"kernel.kptr_restrict = 1"
""
"# Restrict dmesg access"
"kernel.dmesg_restrict = 1"
""
"# Restrict kernel profiling"
"kernel.perf_event_paranoid = 2"
)
printf "%s\n" "${sysctl_config[@]}" | sudo tee -a /etc/sysctl.conf || handle_error "Échec de la mise à jour sysctl.conf"
sysctl -p || handle_error "Échec de l'application des changements sysctl"
log "Paramètres sysctl configurés"
}
# Fonction pour des mesures de sécurité supplémentaires
additional_security() {
log "Appliquer des mesures de sécurité supplémentaires ..."
# Désactiver les vidages de noyau
echo "* hard core 0" | sudo tee -a /etc/security/limits.conf || handle_error "Échec de la désactivation des vidages de noyau"
# Définir des autorisations appropriées pour les fichiers sensibles
chmod 600 /etc/shadow || handle_error "Échec de la définition des autorisations sur /etc/shadow"
chmod 600 /etc/gshadow || handle_error "Échec de la définition des autorisations sur /etc/gshadow"
# Permettre la comptabilisation des processus
install_package "acct"
/usr/sbin/accton on || handle_error "Échec de l'activation de la comptabilité des processus"
# Restreindre SSH
sed -i 's/^#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config || handle_error "Échec de la désactivation de la connexion root via SSH"
sed -i 's/^#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config || handle_error "Échec de la désactivation de l'authentification par mot de passe pour SSH"
sed -i 's/^#Protocol.*/Protocol 2/' /etc/ssh/sshd_config || handle_error "Échec de la définition de la version du protocole SSH"
systemctl reload daemon
systemctl restart sshd || handle_error "Échec du redémarrage du service SSH"
# Configurer une politique de mot de passe fort
sed -i 's/PASS_MAX_DAYS\t99999/PASS_MAX_DAYS\t90/' /etc/login.defs || handle_error "Échec de la définition du nombre maximal de jours pour le mot de passe"
sed -i 's/PASS_MIN_DAYS\t0/PASS_MIN_DAYS\t7/' /etc/login.defs || handle_error "Échec de la définition du mot de passe (nombre de jours minimum)"
sed -i 's/password.*pam_unix.so.*/password [success=1 default=ignore] pam_unix.so obscure sha512 minlen=14 remember=5/' /etc/pam.d/common-password || handle_error "Échec de la configuration de la politique de mot de passe"
log "Mesures de sécurité supplémentaires appliquées"
}
# Fonction de mise à jour automatique
setup_automatic_updates() {
log "Mise en place de mises à jour de sécurité automatiques ..."
install_package "unattended-upgrades"
dpkg-reconfigure -plow unattended-upgrades || handle_error "Échec de la configuration des mises à jour sans surveillance"
log "Configuration des mises à jour de sécurité automatiques"
}
# Fonction principale
main() {
local dry_run=false
# Analyse des arguments de la ligne de commande
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
display_help
;;
-v|--verbose)
VERBOSE=true
shift
;;
--version)
display_version
;;
--dry-run)
dry_run=true
shift
;;
--restore)
restore_backup
exit 0
;;
*)
echo "Option inconnue : $1"
display_help
;;
esac
done
start
check_permissions
check_proxy
check_requirements
backup_files
if $dry_run; then
log "Exécution d'un 'dry run'. Aucune modification ne sera apportée."
else
update_system
setup_ssh
setup_prompt
setup_firewall
setup_fail2ban
setup_clamav
setup_snmp
# setup_nrpe
# setup_glpi
disable_root
remove_packages
setup_audit
disable_filesystems
secure_boot
configure_ipv6
setup_apparmor
setup_ntp
setup_aide
configure_sysctl
additional_security
setup_automatic_updates
fi
log "Configuration de la sécurité renforcée exécutée !!!"
log "Script by Tips-Of-Mine"
if ! $dry_run; then
# Demander à l'utilisateur s'il souhaite redémarrer
read -p "Voulez-vous redémarrer le système maintenant pour appliquer tous les changements ? (y/N): " restart_now
case $restart_now in
[Yy]* )
log "Redémarrage du système ..."
reboot
;;
* )
log "Veuillez redémarrer votre système manuellement pour appliquer tous les changements."
;;
esac
fi
}
# Exécuter la fonction principale
main "$@"