diff --git a/01-ssh/00-basic b/-01-ssh/00-basic similarity index 100% rename from 01-ssh/00-basic rename to -01-ssh/00-basic diff --git a/01-ssh/authorized_keys b/-01-ssh/authorized_keys similarity index 100% rename from 01-ssh/authorized_keys rename to -01-ssh/authorized_keys diff --git a/01-ssh/banner b/-01-ssh/banner similarity index 100% rename from 01-ssh/banner rename to -01-ssh/banner diff --git a/01-ssh/script.sh b/-01-ssh/script.sh similarity index 71% rename from 01-ssh/script.sh rename to -01-ssh/script.sh index 0174a49..4154d79 100644 --- a/01-ssh/script.sh +++ b/-01-ssh/script.sh @@ -8,6 +8,38 @@ NOCOLOR='\033[0m' echo "${YELLOW} ** ${NOCOLOR} Début du script : 01-ssh" echo "${NOCOLOR}" +echo "${YELLOW} * ${NOCOLOR} Controle des persmissions" +echo "${NOCOLOR}" + +check_permissions + +echo "${YELLOW} * ${NOCOLOR} Controle des persmissions : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Controle des pre requis" +echo "${NOCOLOR}" + +check_requirements + +echo "${YELLOW} * ${NOCOLOR} Controle des pre requis : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Sauvegarde ancien fichiers" +echo "${NOCOLOR}" + +backup_files + +echo "${YELLOW} * ${NOCOLOR} Sauvegarde ancien fichiers : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Update du systeme" +echo "${NOCOLOR}" + +update_system + +echo "${YELLOW} * ${NOCOLOR} Update du systeme : ${GREEN} OK" +echo "${NOCOLOR}" + echo "${YELLOW} * ${NOCOLOR} Copie du fichier : authorized_keys" echo "${NOCOLOR}" diff --git a/01-ssh/ssh_config b/-01-ssh/ssh_config similarity index 100% rename from 01-ssh/ssh_config rename to -01-ssh/ssh_config diff --git a/01-ssh/sshd_config b/-01-ssh/sshd_config similarity index 100% rename from 01-ssh/sshd_config rename to -01-ssh/sshd_config diff --git a/02-apt/02proxy b/-02-apt/02proxy similarity index 100% rename from 02-apt/02proxy rename to -02-apt/02proxy diff --git a/02-apt/script.sh b/-02-apt/script.sh similarity index 100% rename from 02-apt/script.sh rename to -02-apt/script.sh diff --git a/03-cortex/etc/panw/cortex.conf b/-03-antivirus/etc/panw/cortex.conf similarity index 100% rename from 03-cortex/etc/panw/cortex.conf rename to -03-antivirus/etc/panw/cortex.conf diff --git a/03-cortex/script.sh b/-03-antivirus/script.sh similarity index 100% rename from 03-cortex/script.sh rename to -03-antivirus/script.sh diff --git a/04-agent-glpi/root-ca.cer b/-04-agent-glpi/root-ca.cer similarity index 100% rename from 04-agent-glpi/root-ca.cer rename to -04-agent-glpi/root-ca.cer diff --git a/04-agent-glpi/script.sh b/-04-agent-glpi/script.sh similarity index 100% rename from 04-agent-glpi/script.sh rename to -04-agent-glpi/script.sh diff --git a/05-manageengine/DMRootCA-Server.crt b/-05-manageengine/DMRootCA-Server.crt similarity index 100% rename from 05-manageengine/DMRootCA-Server.crt rename to -05-manageengine/DMRootCA-Server.crt diff --git a/05-manageengine/DMRootCA.crt b/-05-manageengine/DMRootCA.crt similarity index 100% rename from 05-manageengine/DMRootCA.crt rename to -05-manageengine/DMRootCA.crt diff --git a/05-manageengine/LINUX_README.txt b/-05-manageengine/LINUX_README.txt similarity index 100% rename from 05-manageengine/LINUX_README.txt rename to -05-manageengine/LINUX_README.txt diff --git a/05-manageengine/script.sh b/-05-manageengine/script.sh similarity index 100% rename from 05-manageengine/script.sh rename to -05-manageengine/script.sh diff --git a/05-manageengine/serverinfo.json b/-05-manageengine/serverinfo.json similarity index 100% rename from 05-manageengine/serverinfo.json rename to -05-manageengine/serverinfo.json diff --git a/06-snmp/script.sh b/-06-snmp/script.sh similarity index 100% rename from 06-snmp/script.sh rename to -06-snmp/script.sh diff --git a/06-snmp/snmpd.conf b/-06-snmp/snmpd.conf similarity index 100% rename from 06-snmp/snmpd.conf rename to -06-snmp/snmpd.conf diff --git a/00-proxy/02proxy b/00-proxy/02proxy new file mode 100644 index 0000000..6f630b1 --- /dev/null +++ b/00-proxy/02proxy @@ -0,0 +1,3 @@ +Acquire::http::proxy "http://serv-proxy.fr.dgs.group:3128"; +Acquire::https::proxy "http://serv-proxy.fr.dgs.group:3128"; +Acquire::ftp::proxy "http://serv-proxy.fr.dgs.group:3128"; diff --git a/00-proxy/script.sh b/00-proxy/script.sh new file mode 100644 index 0000000..229ed04 --- /dev/null +++ b/00-proxy/script.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# Pour la configuration de l'APT d'utiliser le proxy + +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NOCOLOR='\033[0m' + +echo "${YELLOW} ** ${NOCOLOR} Début du script : 02-apt" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Copie du fichier : 02proxy" +echo "${NOCOLOR}" + +cp 02-apt/02proxy /etc/apt/apt.conf.d/02proxy >> /dev/null + +echo "${YELLOW} * ${NOCOLOR} Copie du fichier : 02proxy : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Référence update" +echo "${NOCOLOR}" + +apt update >> /dev/null + +echo "${YELLOW} * ${NOCOLOR} Référence update : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Mise à jour" +echo "${NOCOLOR}" + +apt full-upgrade -y >> /dev/null + +echo "${YELLOW} * ${NOCOLOR} Mise à jour : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} ** ${NOCOLOR} Fin du script : 02-apt" +echo "${NOCOLOR}" \ No newline at end of file diff --git a/01-key/authorized_keys b/01-key/authorized_keys new file mode 100644 index 0000000..35f0531 --- /dev/null +++ b/01-key/authorized_keys @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQA \ No newline at end of file diff --git a/02-prompt/00-basic b/02-prompt/00-basic new file mode 100644 index 0000000..9d1c918 --- /dev/null +++ b/02-prompt/00-basic @@ -0,0 +1,66 @@ +#!/bin/bash + +# get load averages +IFS=" " read LOAD1 LOAD5 LOAD15 <<<$(awk '{ print $1,$2,$3 }' /proc/loadavg) +# get free memory +IFS=" " read USED AVAIL TOTAL <<<$(free -htm | awk '/Mem/ { print $3,$7,$2 }') +# get processes +PROCESS=$(ps -eo user=|sort|uniq -c | awk '{ print $2 " " $1 }') +PROCESS_ALL=$(echo "$PROCESS"| awk {'print $2'} | awk '{ SUM += $1} END { print SUM }') +PROCESS_ROOT=$(echo "$PROCESS" | awk '/root/ { print $2}') +PROCESS_USER=$(echo "$PROCESS" | awk '!/root/ { SUM += $2} END { print SUM }') +# get processors +PROCESSOR_NAME=$(awk -F": " '/model name/ { print $2 }' /proc/cpuinfo | head -1) +PROCESSOR_COUNT=$(grep -ioPc 'processor\t:' /proc/cpuinfo) + +# colors +W="\e[0;39m" +G="\e[1;32m" +R="\e[1;31m" +dim="\e[2m" +undim="\e[0m" + +echo -e "${W}System info: +$W Hostname$dim····$undim: $W${HOSTNAME} +$W Distro$dim······$undim: $W$(grep "PRETTY_NAME" /etc/*release | cut -d "=" -f 2- | sed 's/"//g') +$W Kernel$dim······$undim: $W$(uname -sr) +$W Uptime$dim······$undim: $W$(uptime -p) +$W Load$dim········$undim: $G$LOAD1$W (1m), $G$LOAD5$W (5m), $G$LOAD15$W (15m) +$W Processes$dim···$undim: $G$PROCESS_ROOT$W (root), $G$PROCESS_USER$W (user), $G$PROCESS_ALL$W (total) +$W CPU$dim·········$undim: $W$PROCESSOR_NAME ($G$PROCESSOR_COUNT$W vCPU) +$W Memory$dim······$undim: $G$USED$W used, $G$AVAIL$W avail, $G$TOTAL$W total" + +# config +max_usage=90 +bar_width=50 + +# disk usage: ignore zfs, squashfs & tmpfs +printf "\nDisk usage:\n" + +while read line; do + # get disk usage + usage=$(echo "$line" | awk '{print $2}' | sed 's/%//') + used_width=$((($usage*$bar_width)/100)) + # color is green if usage < max_usage, else red + if [ "${usage}" -ge "${max_usage}" ]; then + color=$R + else + color=$G + fi + # print green/red bar until used_width + bar="[${color}" + for ((i=0; i<$used_width; i++)); do + bar+="=" + done + # print dimmmed bar until end + bar+="${W}${dim}" + for ((i=$used_width; i<$bar_width; i++)); do + bar+="·" + done + bar+="${undim}]" + # print usage line & bar + echo "${line}" | awk '{ printf("%-31s%+3s used out of %+4s\n", $1, $2, $3); }' | sed -e 's/^/ /' + echo -e "${bar}" | sed -e 's/^/ /' +done < <(df -H -x zfs -x squashfs -x tmpfs -x devtmpfs -x overlay -x nfs -x nfs4 -x cifs --output=target,pcent,size | tail -n+2) + +printf "\n" \ No newline at end of file diff --git a/02-prompt/banner b/02-prompt/banner new file mode 100644 index 0000000..02d5bbe --- /dev/null +++ b/02-prompt/banner @@ -0,0 +1,25 @@ + + _______ _ + |__ __| (_) + | | __ _ _ __ _ ___ + | |/ _` | '_ \| / __| + | | (_| | |_) | \__ \ + |_|\__,_| .__/|_|___/ + _____ | |_ _ __ __ _ + / ____| |_(_) | | | \/ | | | + | (___ __ _ _ _ __ | |_ __ | \ / | __ _ ___| | ___ _ _ + \___ \ / _` | | '_ \| __||__|| |\/| |/ _` |/ __| |/ _ \| | | | + ____) | (_| | | | | | |_ | | | | (_| | (__| | (_) | |_| | + |_____/ \__,_|_|_| |_|\__| |_| |_|\__,_|\___|_|\___/ \__,_| + +AVERTISSEMENT : L'accès à ce système est réservé aux utilisateurs +dûment autorisés. + +Toute tentative d'accès, d'accès à ce système sans autorisation ou +de maintien frauduleux dans ce système fera l'objet de poursuites +conformément à la politique de Tapis-Saint-Maclou. + +Tout utilisateur autorisé est informé et reconnaît que ses actions +peuvent être enregistrées, conservées et auditées conformément aux +chartes/politiques internes de aux chartes/politiques internes de +Tapis-Saint-Maclou. \ No newline at end of file diff --git a/10-Fail2ban/jail.local b/03-Fail2ban/defaults-debian-ssh.conf similarity index 100% rename from 10-Fail2ban/jail.local rename to 03-Fail2ban/defaults-debian-ssh.conf diff --git a/03-Fail2ban/jail.local b/03-Fail2ban/jail.local new file mode 100644 index 0000000..7f9ea3a --- /dev/null +++ b/03-Fail2ban/jail.local @@ -0,0 +1,7 @@ +[sshd] +enabled = true +port = 2222 +filter = sshd +logpath = /var/log/auth.log +maxretry = 3 +bantime = 3600 \ No newline at end of file diff --git a/10-Fail2ban/script.sh b/03-Fail2ban/script.sh similarity index 100% rename from 10-Fail2ban/script.sh rename to 03-Fail2ban/script.sh diff --git a/04-clamav/etc/panw/cortex.conf b/04-clamav/etc/panw/cortex.conf new file mode 100644 index 0000000..00191a9 --- /dev/null +++ b/04-clamav/etc/panw/cortex.conf @@ -0,0 +1,2 @@ +--distribution-id 896dc20f132a45369e53e479b245d244 +--distribution-server https://distributions.traps.paloaltonetworks.com/ \ No newline at end of file diff --git a/04-clamav/script.sh b/04-clamav/script.sh new file mode 100644 index 0000000..82de31c --- /dev/null +++ b/04-clamav/script.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# Pour installer Cortex sur un serveur Debian + +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NOCOLOR='\033[0m' + +echo "${YELLOW} ** ${NOCOLOR} Début du script : 03-cortex" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Création du dossier" +echo "${NOCOLOR}" + +mkdir -p /etc/panw >> /dev/null + +echo "${YELLOW} * ${NOCOLOR} Création du dossier : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Copie du fichier : cortex.conf" +echo "${NOCOLOR}" + +cp 03-cortex/etc/panw/cortex.conf /etc/panw/cortex.conf >> /dev/null + +echo "${YELLOW} * ${NOCOLOR} Copie du fichier : cortex.conf : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Installation iptables" +echo "${NOCOLOR}" + +apt install -y iptables >> /dev/null + +echo "${YELLOW} * ${NOCOLOR} Installation iptables : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Installation Cortex" +echo "${NOCOLOR}" + +dpkg -i 03-cortex/cortex-8.7.0.131661.deb + +echo "${YELLOW} * ${NOCOLOR} Installation Cortex : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} ** ${NOCOLOR} Fin du script : 03-cortex" +echo "${NOCOLOR}" \ No newline at end of file diff --git a/05-snmp/script.sh b/05-snmp/script.sh new file mode 100644 index 0000000..eb6b42e --- /dev/null +++ b/05-snmp/script.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# Pour la configuration SNMP + +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NOCOLOR='\033[0m' + +echo "${YELLOW} ** ${NOCOLOR} Début du script : 06-snmp" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Installation composant" +echo "${NOCOLOR}" + +apt install -y snmp snmpd >> /dev/null + +echo "${YELLOW} * ${NOCOLOR} Installation composant : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Copie du fichier : snmpd.conf" +echo "${NOCOLOR}" + +cp 06-snmp/snmpd.conf /etc/snmp/ >> /dev/null + +echo "${YELLOW} * ${NOCOLOR} Copie du fichier : snmpd.conf : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} * ${NOCOLOR} Relance de service" +echo "${NOCOLOR}" + +systemctl restart snmpd + +echo "${YELLOW} * ${NOCOLOR} Relance de service : ${GREEN} OK" +echo "${NOCOLOR}" + +echo "${YELLOW} ** ${NOCOLOR} Fin du script : 06-snmp" +echo "${NOCOLOR}" \ No newline at end of file diff --git a/05-snmp/snmpd.conf b/05-snmp/snmpd.conf new file mode 100644 index 0000000..8e0c616 --- /dev/null +++ b/05-snmp/snmpd.conf @@ -0,0 +1,6 @@ +rocommunity eveagroup 10.78.56.100 +rocommunity SUP-TSM-PRIV 10.78.56.16 +rocommunity public 10.78.56.100 +rocommunity SUP-TSM-PRIV 10.78.56.45 + +extend docker /etc/snmp/docker-stats.py \ No newline at end of file diff --git a/dsq b/dsq new file mode 100644 index 0000000..21120e3 --- /dev/null +++ b/dsq @@ -0,0 +1,562 @@ +#!/bin/bash + +# Global variables +VERSION="2.0" +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") + +# Function for logging +log() { + local message="$(date '+%Y-%m-%d %H:%M:%S'): $1" + echo "$message" | sudo tee -a "$LOG_FILE" + $VERBOSE && echo "$message" +} + +# Function for error handling +handle_error() { + log "Error: $1" + exit 1 +} + +# Function to install packages +install_package() { + log "Installing $1..." + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "$1" || handle_error "Failed to install $1" +} + +# Function to backup files +backup_files() { + sudo mkdir -p "$BACKUP_DIR" || handle_error "Failed to create backup directory" + + local files_to_backup=( + "/etc/default/grub" + "/etc/ssh/sshd_config" + "/etc/pam.d/common-password" + "/etc/login.defs" + "/etc/sysctl.conf" + ) + + for file in "${files_to_backup[@]}"; do + if [ -f "$file" ]; then + sudo cp "$file" "$BACKUP_DIR/" || log "Warning: Failed to backup $file" + else + log "Warning: $file not found, skipping backup" + fi + done + + log "Backup created in $BACKUP_DIR" +} + +# Function to restore from backup +restore_backup() { + if [ -d "$BACKUP_DIR" ]; then + for file in "$BACKUP_DIR"/*; do + sudo cp "$file" "$(dirname "$(readlink -f "$file")")" || log "Warning: Failed to restore $(basename "$file")" + done + log "Restored configurations from $BACKUP_DIR" + else + log "Backup directory not found. Cannot restore." + fi +} + +# Function to check permissions +check_permissions() { + if [ "$EUID" -ne 0 ]; then + echo "This script must be run with sudo privileges." + echo "Please run it again using: sudo $0" + exit 1 + fi +} + +# Function to display help +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 +} + +# Function to display version +display_version() { + echo "Enhanced Ubuntu Linux Security Hardening Script v$VERSION" + exit 0 +} + +# Function to check system requirements +check_requirements() { + if ! command -v lsb_release &> /dev/null; then + handle_error "lsb_release command not found. This script requires an Ubuntu-based system." + fi + + local os_name=$(lsb_release -si) + local os_version=$(lsb_release -sr) + + if [[ "$os_name" != "Ubuntu" && "$os_name" != "Debian" ]]; then + handle_error "This script is designed for Ubuntu or Debian-based systems. Detected OS: $os_name" + if [[ $(echo "$os_version < 18.04" | bc) -eq 1 ]]; then + handle_error "This script requires Ubuntu 18.04 or later. Detected version: $os_version" + elif [[ "$os_name" == "Debian" && $(echo "$os_version < 12.0" | bc) -eq 1 ]]; then + handle_error "This script requires Debian 12.0 or later. Detected version: $os_version" + fi + fi + + log "System requirements check passed. OS: $os_name $os_version" +} + +# Function to update system +update_system() { + log "Updating System..." + sudo apt-get update -y || handle_error "System update failed" + sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y || handle_error "System upgrade failed" +} + +# Function to setup firewall +setup_firewall() { + log "Installing and Configuring Firewall..." + install_package "ufw" + sudo ufw default deny incoming || handle_error "Failed to set UFW default incoming policy" + sudo ufw default allow outgoing || handle_error "Failed to set UFW default outgoing policy" + sudo ufw limit ssh comment 'Allow SSH with rate limiting' || handle_error "Failed to configure SSH in UFW" + sudo ufw allow 80/tcp comment 'Allow HTTP' || handle_error "Failed to allow HTTP in UFW" + sudo ufw allow 443/tcp comment 'Allow HTTPS' || handle_error "Failed to allow HTTPS in UFW" + + local apply_ipv6_rules + read -p "Do you want to apply IPv6-specific firewall rules? (y/N): " apply_ipv6_rules + case $apply_ipv6_rules in + [Yy]* ) + log "Applying IPv6-specific firewall rules..." + sudo ufw allow in on lo || handle_error "Failed to allow loopback traffic" + sudo ufw allow out on lo || handle_error "Failed to allow loopback traffic" + sudo ufw deny in from ::/0 || handle_error "Failed to deny all incoming IPv6 traffic" + sudo ufw allow out to ::/0 || handle_error "Failed to allow all outgoing IPv6 traffic" + log "IPv6 firewall rules applied" + ;; + * ) + log "Skipping IPv6-specific firewall rules" + ;; + esac + + sudo ufw logging on || handle_error "Failed to enable UFW logging" + sudo ufw --force enable || handle_error "Failed to enable UFW" + log "Firewall configured and enabled" +} + +# Function to setup Fail2Ban +setup_fail2ban() { + log "Installing and Configuring Fail2Ban..." + install_package "fail2ban" + sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local || handle_error "Failed to create Fail2Ban local config" + sudo sed -i 's/bantime = 10m/bantime = 1h/' /etc/fail2ban/jail.local || handle_error "Failed to set Fail2Ban bantime" + sudo sed -i 's/maxretry = 5/maxretry = 3/' /etc/fail2ban/jail.local || handle_error "Failed to set Fail2Ban maxretry" + sudo systemctl enable fail2ban || handle_error "Failed to enable Fail2Ban service" + sudo systemctl start fail2ban || handle_error "Failed to start Fail2Ban service" + log "Fail2Ban configured and started" +} + +# Function to setup ClamAV +setup_clamav() { + log "Installing and Updating ClamAV..." + install_package "clamav" + install_package "clamav-daemon" + sudo systemctl stop clamav-freshclam || log "Warning: Failed to stop clamav-freshclam" + sudo freshclam || log "Warning: ClamAV database update failed" + sudo systemctl start clamav-freshclam || handle_error "Failed to start clamav-freshclam" + sudo systemctl enable clamav-freshclam || handle_error "Failed to enable clamav-freshclam" + log "ClamAV installed and updated" +} + +# Function to disable root login +disable_root() { + log "Checking for non-root users with sudo privileges..." + + # Get the list of users with sudo privileges + sudo_users=$(getent group sudo | cut -d: -f4 | tr ',' '\n' | grep -v "^root$") + + # Check if there are any non-root users with sudo privileges + if [ -z "$sudo_users" ]; then + log "Warning: No non-root users with sudo privileges found. Skipping root login disable for safety." + echo "Please create a non-root user with sudo privileges before disabling root login." + return + fi + + log "Non-root users with sudo privileges found. Proceeding to disable root login..." + + # Disable root login + if sudo passwd -l root; then + log "Root login disabled successfully." + else + handle_error "Failed to lock root account" + fi + + # Disable root SSH login as an additional precaution + if grep -q "^PermitRootLogin" /etc/ssh/sshd_config; then + sudo sed -i 's/^PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config || handle_error "Failed to disable root SSH login in sshd_config" + else + echo "PermitRootLogin no" | sudo tee -a /etc/ssh/sshd_config > /dev/null || handle_error "Failed to add PermitRootLogin no to sshd_config" + fi + + # Restart SSH service to apply changes + sudo systemctl restart sshd || handle_error "Failed to restart SSH service" + + log "Root login has been disabled and SSH root login has been explicitly prohibited." +} + +# Function to remove unnecessary packages +remove_packages() { + log "Removing unnecessary packages..." + sudo DEBIAN_FRONTEND=noninteractive apt-get remove --purge -y telnetd nis yp-tools rsh-client rsh-redone-client xinetd || log "Warning: Failed to remove some packages" + sudo apt-get autoremove -y || log "Warning: autoremove failed" + log "Unnecessary packages removed" +} + +# Function to setup audit +setup_audit() { + log "Configuring audit rules..." + 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" | sudo tee -a /etc/audit/rules.d/audit.rules > /dev/null || handle_error "Failed to add audit rule: $rule" + done + + sudo systemctl enable auditd || handle_error "Failed to enable auditd service" + sudo systemctl start auditd || handle_error "Failed to start auditd service" + log "Audit rules configured and auditd started" +} + +# Function to disable unused filesystems +disable_filesystems() { + log "Disabling Unused Filesystems..." + 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 "Failed to disable filesystem: $fs" + done + + log "Unused filesystems disabled" +} + +# Function to secure boot settings +secure_boot() { + log "Securing Boot Settings..." + + # Secure GRUB configuration file + if [ -f /boot/grub/grub.cfg ]; then + sudo chown root:root /boot/grub/grub.cfg || handle_error "Failed to change ownership of grub.cfg" + sudo chmod 600 /boot/grub/grub.cfg || handle_error "Failed to change permissions of grub.cfg" + log "GRUB configuration file secured" + else + log "Warning: /boot/grub/grub.cfg not found. Skipping GRUB file permissions." + fi + + # Modify kernel parameters + if [ -f /etc/default/grub ]; then + # Backup original file + sudo cp /etc/default/grub /etc/default/grub.bak || handle_error "Failed to backup grub file" + + # Add or modify kernel parameters + 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" + + # Ask if user wants to disable SACK + local disable_sack + read -p "Do you want to disable TCP SACK? This is generally not recommended. (y/N): " disable_sack + case $disable_sack in + [Yy]* ) + kernel_params+=" net.ipv4.tcp_sack=0" + log "TCP SACK will be disabled" + ;; + * ) + log "TCP SACK will remain enabled" + ;; + esac + + sudo sed -i "s/GRUB_CMDLINE_LINUX=\"\"/GRUB_CMDLINE_LINUX=\"$kernel_params\"/" /etc/default/grub || handle_error "Failed to modify kernel parameters" + + # Update GRUB + if command -v update-grub &> /dev/null; then + sudo update-grub || handle_error "Failed to update GRUB" + elif command -v grub2-mkconfig &> /dev/null; then + sudo grub2-mkconfig -o /boot/grub2/grub.cfg || handle_error "Failed to update GRUB" + else + log "Warning: Neither update-grub nor grub2-mkconfig found. Please update GRUB manually." + fi + + log "Kernel parameters updated" + else + log "Warning: /etc/default/grub not found. Skipping kernel parameter modifications." + fi + + log "Boot settings secured" +} + +# Function to configure IPv6 +configure_ipv6() { + local disable_ipv6 + read -p "Do you want to disable IPv6? (y/N): " disable_ipv6 + case $disable_ipv6 in + [Yy]* ) + log "Disabling IPv6..." + echo "net.ipv6.conf.all.disable_ipv6 = 1" | sudo tee -a /etc/sysctl.conf || handle_error "Failed to disable IPv6 (all)" + echo "net.ipv6.conf.default.disable_ipv6 = 1" | sudo tee -a /etc/sysctl.conf || handle_error "Failed to disable IPv6 (default)" + echo "net.ipv6.conf.lo.disable_ipv6 = 1" | sudo tee -a /etc/sysctl.conf || handle_error "Failed to disable IPv6 (lo)" + sudo sysctl -p || handle_error "Failed to apply sysctl changes" + log "IPv6 has been disabled" + ;; + * ) + log "IPv6 will remain enabled" + ;; + esac +} + +# Function to setup AppArmor +setup_apparmor() { + log "Setting up AppArmor..." + + if ! command -v apparmor_status &> /dev/null; then + install_package "apparmor" + install_package "apparmor-utils" + else + log "AppArmor is already installed. Skipping installation." + fi + + sudo systemctl enable apparmor || handle_error "Failed to enable AppArmor service" + sudo systemctl start apparmor || handle_error "Failed to start AppArmor service" + + sudo aa-enforce /etc/apparmor.d/* || log "Warning: Failed to enforce some AppArmor profiles" + + log "AppArmor setup complete. All profiles are in enforce mode." + log "Monitor /var/log/syslog and /var/log/auth.log for any AppArmor-related issues." +} + +# Function to setup NTP +setup_ntp() { + log "Setting up time synchronization..." + + # Check if systemd-timesyncd is available (modern Ubuntu systems) + if systemctl list-unit-files | grep -q systemd-timesyncd.service; then + log "Using systemd-timesyncd for time synchronization" + sudo systemctl enable systemd-timesyncd.service || handle_error "Failed to enable systemd-timesyncd service" + sudo systemctl start systemd-timesyncd.service || handle_error "Failed to start systemd-timesyncd service" + log "systemd-timesyncd setup complete" + else + # Fall back to traditional NTP if systemd-timesyncd is not available + log "Using traditional NTP for time synchronization" + install_package "ntp" + sudo systemctl enable ntp || handle_error "Failed to enable NTP service" + sudo systemctl start ntp || handle_error "Failed to start NTP service" + log "NTP setup complete" + fi +} + +# Function to setup AIDE +setup_aide() { + log "Setting up AIDE..." + install_package "aide" + sudo aideinit || handle_error "Failed to initialize AIDE database" + sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db || handle_error "Failed to move AIDE database" + log "AIDE setup complete" +} + +# Function to configure sysctl +configure_sysctl() { + log "Configuring sysctl settings..." + + 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 "Failed to update sysctl.conf" + sudo sysctl -p || handle_error "Failed to apply sysctl changes" + log "sysctl settings configured" +} + +# Function for additional security measures +additional_security() { + log "Applying additional security measures..." + + # Disable core dumps + echo "* hard core 0" | sudo tee -a /etc/security/limits.conf || handle_error "Failed to disable core dumps" + + # Set proper permissions on sensitive files + sudo chmod 600 /etc/shadow || handle_error "Failed to set permissions on /etc/shadow" + sudo chmod 600 /etc/gshadow || handle_error "Failed to set permissions on /etc/gshadow" + + # Enable process accounting + install_package "acct" + sudo /usr/sbin/accton on || handle_error "Failed to enable process accounting" + + # Restrict SSH + sudo sed -i 's/^#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config || handle_error "Failed to disable root login via SSH" + sudo sed -i 's/^#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config || handle_error "Failed to disable password authentication for SSH" + sudo sed -i 's/^#Protocol.*/Protocol 2/' /etc/ssh/sshd_config || handle_error "Failed to set SSH protocol version" + sudo systemctl restart sshd || handle_error "Failed to restart SSH service" + + # Configure strong password policy + sudo sed -i 's/PASS_MAX_DAYS\t99999/PASS_MAX_DAYS\t90/' /etc/login.defs || handle_error "Failed to set password max days" + sudo sed -i 's/PASS_MIN_DAYS\t0/PASS_MIN_DAYS\t7/' /etc/login.defs || handle_error "Failed to set password min days" + sudo 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 "Failed to configure password policy" + + log "Additional security measures applied" +} + +# Function to setup automatic updates +setup_automatic_updates() { + log "Setting up automatic security updates..." + install_package "unattended-upgrades" + sudo dpkg-reconfigure -plow unattended-upgrades || handle_error "Failed to configure unattended-upgrades" + log "Automatic security updates configured" +} + +# Main function +main() { + local dry_run=false + + # Parse command line arguments + 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 "Unknown option: $1" + display_help + ;; + esac + done + + check_permissions + check_requirements + backup_files + + if $dry_run; then + log "Performing dry run. No changes will be made." + else + update_system + 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 "Enhanced Security Configuration executed! Script by captainzero93" + + if ! $dry_run; then + # Ask user if they want to restart + read -p "Do you want to restart the system now to apply all changes? (y/N): " restart_now + case $restart_now in + [Yy]* ) + log "Restarting system..." + sudo reboot + ;; + * ) + log "Please restart your system manually to apply all changes." + ;; + esac + fi +} + +# Run the main function +main "$@" diff --git a/script-global.sh b/script-global.sh new file mode 100644 index 0000000..e9d0634 --- /dev/null +++ b/script-global.sh @@ -0,0 +1,858 @@ +#!/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 "$@" diff --git a/script.sh b/script.sh index a8a970f..3187e0c 100644 --- a/script.sh +++ b/script.sh @@ -11,7 +11,7 @@ echo "${NOCOLOR}" chmod +x ./01-ssh/script.sh >> /dev/null chmod +x ./02-apt/script.sh >> /dev/null -chmod +x ./03-cortex/script.sh >> /dev/null +chmod +x ./03-antivirus/script.sh >> /dev/null chmod +x ./04-agent-glpi/script.sh >> /dev/null chmod +x ./05-manageengine/script.sh >> /dev/null chmod +x ./06-snmp/script.sh >> /dev/null @@ -41,12 +41,12 @@ echo "${NOCOLOR}" echo "${YELLOW} *** ${NOCOLOR} Fin du script : APT : ${GREEN} OK" echo "${NOCOLOR}" -echo "${YELLOW} *** ${NOCOLOR} Lancement du script : Cortex" +echo "${YELLOW} *** ${NOCOLOR} Lancement du script : Antivirus" echo "${NOCOLOR}" -./03-cortex/script.sh +./03-antivirus/script.sh -echo "${YELLOW} *** ${NOCOLOR} Fin du script : Cortex : ${GREEN} OK" +echo "${YELLOW} *** ${NOCOLOR} Fin du script : Antivirus : ${GREEN} OK" echo "${NOCOLOR}" echo "${YELLOW} *** ${NOCOLOR} Lancement du script : GLPI"