859 lines
33 KiB
Bash
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 "$@"
|