Checklist Hardening Linux
Checklist complète pour sécuriser un serveur Linux en production.
1. Installation et Partitionnement
Partitions Séparées
- [ ]
/- Système racine - [ ]
/boot- Fichiers de boot (500 MB - 1 GB) - [ ]
/home- Données utilisateurs - [ ]
/var- Logs et données variables - [ ]
/var/log- Logs (séparé si possible) - [ ]
/tmp- Fichiers temporaires - [ ]
/var/tmp- Temporaires persistants - [ ]
swap- Espace d'échange
Options de Montage Sécurisées
# /etc/fstab - Options recommandées
/dev/mapper/vg-home /home ext4 defaults,nodev,nosuid 0 2
/dev/mapper/vg-tmp /tmp ext4 defaults,nodev,nosuid,noexec 0 2
/dev/mapper/vg-var /var ext4 defaults,nodev,nosuid 0 2
tmpfs /dev/shm tmpfs defaults,nodev,nosuid,noexec 0 0
| Option | Description |
|---|---|
nodev |
Pas de fichiers device |
nosuid |
Ignorer SUID/SGID |
noexec |
Pas d'exécution |
2. Mises à Jour
Système à Jour
- [ ] Tous les paquets mis à jour
- [ ] Mises à jour de sécurité automatiques configurées
- [ ] Kernel à jour
# RHEL/Rocky
sudo dnf update -y
sudo dnf install dnf-automatic
sudo systemctl enable --now dnf-automatic.timer
# Ubuntu
sudo apt update && sudo apt upgrade -y
sudo apt install unattended-upgrades
sudo dpkg-reconfigure unattended-upgrades
3. Comptes Utilisateurs
Politique de Mots de Passe
- [ ] Longueur minimale : 12 caractères
- [ ] Complexité requise
- [ ] Expiration configurée
- [ ] Historique des mots de passe
# /etc/security/pwquality.conf
minlen = 12
minclass = 3
maxrepeat = 3
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
# /etc/login.defs
PASS_MAX_DAYS 90
PASS_MIN_DAYS 7
PASS_WARN_AGE 14
Comptes
- [ ] Root désactivé pour login direct
- [ ] Comptes inutilisés supprimés/désactivés
- [ ] Shells appropriés (
/sbin/nologinpour services) - [ ] UID 0 uniquement pour root
# Vérifier les comptes avec UID 0
awk -F: '($3 == 0) {print}' /etc/passwd
# Verrouiller un compte
sudo usermod -L username
sudo passwd -l username
# Shell nologin pour service
sudo usermod -s /sbin/nologin serviceuser
Sudo
- [ ] Utilisateurs autorisés uniquement
- [ ] Logs sudo activés
- [ ] Timeout configuré
- [ ] Pas de NOPASSWD sauf nécessité absolue
# /etc/sudoers.d/hardening
Defaults logfile="/var/log/sudo.log"
Defaults log_input, log_output
Defaults timestamp_timeout=5
Defaults passwd_tries=3
4. SSH
Configuration sshd_config
- [ ] Port changé (optionnel mais recommandé)
- [ ] PermitRootLogin no
- [ ] PasswordAuthentication no
- [ ] Authentification par clé uniquement
- [ ] Protocole 2 uniquement
- [ ] AllowUsers/AllowGroups configuré
- [ ] MaxAuthTries limité
# /etc/ssh/sshd_config
Port 2222
Protocol 2
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3
MaxSessions 2
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers admin deploy
X11Forwarding no
PermitEmptyPasswords no
HostbasedAuthentication no
IgnoreRhosts yes
LoginGraceTime 60
Banner /etc/issue.net
# Algorithmes modernes
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
Clés SSH
- [ ] Clés Ed25519 ou RSA 4096 bits
- [ ] Passphrase sur les clés
- [ ] Permissions correctes sur ~/.ssh
# Générer clé sécurisée
ssh-keygen -t ed25519 -C "user@host"
# Permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys
5. Firewall
Configuration
- [ ] Firewall activé (firewalld ou ufw)
- [ ] Politique par défaut : DROP
- [ ] Seuls les ports nécessaires ouverts
- [ ] Règles spécifiques par source IP si possible
# firewalld (RHEL/Rocky)
sudo firewall-cmd --set-default-zone=drop
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" port port="22" protocol="tcp" accept' --permanent
sudo firewall-cmd --reload
# ufw (Ubuntu)
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 10.0.0.0/8 to any port 22
sudo ufw enable
Fail2ban
- [ ] Installé et configuré
- [ ] Protection SSH activée
- [ ] Temps de ban approprié
# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 3
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
6. SELinux / AppArmor
SELinux (RHEL/Rocky)
- [ ] Mode Enforcing
- [ ] Booleans configurés
- [ ] Contextes corrects
# Vérifier
getenforce
sestatus
# Activer
sudo setenforce 1
# /etc/selinux/config → SELINUX=enforcing
# Booleans courants
sudo setsebool -P httpd_can_network_connect on
sudo setsebool -P httpd_can_network_connect_db on
AppArmor (Ubuntu)
- [ ] Activé
- [ ] Profils en mode enforce
7. Services
Minimisation
- [ ] Services inutiles désactivés
- [ ] Ports d'écoute vérifiés
# Lister les services actifs
systemctl list-units --type=service --state=running
# Services à désactiver (si non utilisés)
sudo systemctl disable --now cups
sudo systemctl disable --now avahi-daemon
sudo systemctl disable --now bluetooth
sudo systemctl disable --now rpcbind
# Vérifier les ports ouverts
ss -tuln
8. Permissions Fichiers
Fichiers Critiques
- [ ] /etc/passwd : 644
- [ ] /etc/shadow : 000 ou 600
- [ ] /etc/group : 644
- [ ] /etc/gshadow : 000 ou 600
- [ ] /etc/ssh/sshd_config : 600
- [ ] Clés SSH privées : 600
chmod 644 /etc/passwd
chmod 600 /etc/shadow
chmod 644 /etc/group
chmod 600 /etc/gshadow
chmod 600 /etc/ssh/sshd_config
SUID/SGID
- [ ] Fichiers SUID/SGID audités
- [ ] Fichiers world-writable audités
# Trouver les SUID
find / -perm -4000 -type f 2>/dev/null
# Trouver les SGID
find / -perm -2000 -type f 2>/dev/null
# Trouver les world-writable
find / -type f -perm -0002 2>/dev/null
find / -type d -perm -0002 2>/dev/null
9. Paramètres Kernel (sysctl)
# /etc/sysctl.d/99-hardening.conf
# Réseau
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_syncookies = 1
# IPv6 (si non utilisé)
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
# Kernel
kernel.randomize_va_space = 2
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
kernel.yama.ptrace_scope = 1
fs.suid_dumpable = 0
# Appliquer
sudo sysctl --system
10. Audit et Logging
Auditd
- [ ] Installé et activé
- [ ] Règles configurées pour fichiers critiques
# /etc/audit/rules.d/hardening.rules
# Fichiers d'authentification
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
# SSH
-w /etc/ssh/sshd_config -p wa -k sshd
# Commandes privilégiées
-a always,exit -F path=/usr/bin/sudo -F perm=x -F apts auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/su -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
# Modules kernel
-w /sbin/insmod -p x -k modules
-w /sbin/rmmod -p x -k modules
-w /sbin/modprobe -p x -k modules
Logging
- [ ] rsyslog ou journald configuré
- [ ] Logs envoyés vers serveur central (optionnel)
- [ ] Rotation des logs configurée
# Vérifier journald
journalctl --disk-usage
# /etc/systemd/journald.conf
[Journal]
Storage=persistent
Compress=yes
SystemMaxUse=500M
MaxFileSec=1month
11. Bannières
- [ ] Bannière de connexion configurée
- [ ] Avertissement légal
# /etc/issue.net (SSH)
# /etc/issue (console)
******************************************************************
* AUTHORIZED ACCESS ONLY *
* *
* This system is for authorized users only. All activities are *
* logged and monitored. Unauthorized access is prohibited. *
******************************************************************
# Activer dans sshd_config
Banner /etc/issue.net
12. Désactiver les Fonctionnalités Inutiles
# Core dumps
echo "* hard core 0" >> /etc/security/limits.conf
echo "fs.suid_dumpable = 0" >> /etc/sysctl.d/99-hardening.conf
# USB storage (si non nécessaire)
echo "install usb-storage /bin/false" >> /etc/modprobe.d/disable-usb.conf
echo "blacklist usb-storage" >> /etc/modprobe.d/disable-usb.conf
# Protocoles réseau inutiles
echo "install dccp /bin/false" >> /etc/modprobe.d/disable-protocols.conf
echo "install sctp /bin/false" >> /etc/modprobe.d/disable-protocols.conf
echo "install rds /bin/false" >> /etc/modprobe.d/disable-protocols.conf
echo "install tipc /bin/false" >> /etc/modprobe.d/disable-protocols.conf
13. Backup et Recovery
- [ ] Stratégie de backup documentée
- [ ] Backups testés régulièrement
- [ ] Plan de disaster recovery
# Backup de configuration
tar -czvf /backup/etc-$(date +%Y%m%d).tar.gz /etc
# Liste des paquets installés
rpm -qa > /backup/packages-$(date +%Y%m%d).txt # RHEL
dpkg --get-selections > /backup/packages-$(date +%Y%m%d).txt # Ubuntu
14. Scan de Sécurité
OpenSCAP
# Installation
sudo dnf install openscap-scanner scap-security-guide
# Scan CIS
sudo oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_cis \
--results scan-results.xml \
--report scan-report.html \
/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
Lynis
15. Vérification Finale
#!/bin/bash
# Script de vérification basique
echo "=== Vérification Hardening ==="
echo -n "SELinux/AppArmor: "
if command -v getenforce &>/dev/null; then
getenforce
elif command -v aa-status &>/dev/null; then
aa-status --enabled && echo "Enabled"
fi
echo -n "Firewall: "
systemctl is-active firewalld 2>/dev/null || systemctl is-active ufw 2>/dev/null
echo -n "SSH Root Login: "
grep "^PermitRootLogin" /etc/ssh/sshd_config
echo -n "SSH Password Auth: "
grep "^PasswordAuthentication" /etc/ssh/sshd_config
echo -n "Fail2ban: "
systemctl is-active fail2ban
echo -n "Auditd: "
systemctl is-active auditd
echo -n "Kernel Hardening: "
sysctl kernel.randomize_va_space
echo "=== Ports ouverts ==="
ss -tuln
echo "=== Mises à jour disponibles ==="
dnf check-update 2>/dev/null | head -5 || apt list --upgradable 2>/dev/null | head -5
Ressources
- CIS Benchmarks : cisecurity.org
- NIST : nist.gov
- ANSSI : ssi.gouv.fr
- OpenSCAP : open-scap.org
Retour au : Programme de la Formation