Durcissez un serveur Linux : audit Lynis, permissions strictes via umask et ACL, kernel hardening sysctl, conformite CIS Benchmarks et auditd continu.
Pourquoi durcir Linux au-dela de SSH
Securiser SSH est la premiere etape, mais elle ne couvre qu'une seule porte d'entree. Un serveur Linux installe par defaut conserve des dizaines d'autres surfaces d'attaque : services ecoutant sur toutes les interfaces, permissions de fichiers trop permissives, parametres kernel laxistes, comptes utilisateurs heritage, logs incomplets. Le hardening systeme complete le hardening reseau pour offrir une defense en profondeur.
Un cas concret : une application web compromise via une faille XSS peut declencher l'execution de code via PHP. Si le serveur n'a pas durci ses permissions de fichiers ni son kernel, l'attaquant peut escalader rapidement vers root via une vulnerabilite locale (Dirty COW, PwnKit, etc.). Le hardening reduit chaque etape de la kill chain : meme si la premiere defense tombe, les suivantes tiennent.
- Audit systematique : Lynis et chkrootkit identifient les ecarts par rapport aux bonnes pratiques.
- Permissions strictes : umask serre, ACL ciblees, attributs immuables sur les fichiers critiques.
- Surface reduite : services inutiles desactives, ports d'ecoute minimises.
- Kernel durci : parametres sysctl pour TCP, ASLR, anti-spoofing, protections fs.
- Conformite mesurable : CIS Benchmarks niveau 1 ou 2 selon le contexte.
Le modele de securite par couches
Le hardening efficace suit le principe defense in depth (defense en profondeur). Chaque couche est independante des autres et chacune freine la progression d'un attaquant. La perte d'une couche n'expose pas immediatement la totalite du systeme.
| Couche | Objectif | Outils |
|---|---|---|
| Reseau | Filtrer les flux entrants/sortants | nftables, UFW, fail2ban |
| Authentification | Limiter l'acces aux comptes legitimes | SSH cles, PAM, sudo |
| Permissions | Restreindre les operations sur fichiers | umask, ACL, chattr |
| Services | Reduire la surface d'attaque | systemctl, masquage |
| Kernel | Empecher l'escalade locale | sysctl, ASLR, namespaces |
| Audit | Mesurer et detecter les ecarts | Lynis, OpenSCAP, auditd |
Audit initial avec Lynis et chkrootkit
Avant de modifier quoi que ce soit, mesurez l'etat de depart. Un audit donne une vision objective des points faibles et permet de prioriser les corrections. Lynis est l'outil de reference open source : il execute plus de 300 controles couvrant les configurations PAM, SSH, kernel, services, comptes utilisateurs, permissions et logs.
Installation de Lynis
# Met a jour les depots et installe Lynis depuis les paquets officiels
sudo apt update
sudo apt install lynis -y
# Verifie la version installee (recommandee : 3.0+)
lynis show version
# Met a jour les regles d'audit aux dernieres definitions
sudo lynis update info
Lancer un audit complet
# Lance un audit complet en mode systeme avec sortie detaillee
# --quick : execute sans demander de confirmation entre les sections
# --logfile : specifie l'emplacement du log detaille
sudo lynis audit system --quick
# Le rapport est ecrit dans deux fichiers
# Log lisible : /var/log/lynis.log
# Donnees machine-readable : /var/log/lynis-report.dat
# Affiche le score de hardening obtenu (Hardening index)
sudo grep "Hardening index" /var/log/lynis.log
Le score de Lynis est compris entre 0 et 100. Un serveur frais sans hardening obtient typiquement entre 55 et 65. L'objectif raisonnable pour un serveur de production est superieur a 85.
Lire les warnings et suggestions
# Liste tous les warnings (problemes critiques a corriger en priorite)
sudo grep "Warning" /var/log/lynis.log
# Liste toutes les suggestions (ameliorations recommandees)
sudo grep "Suggestion" /var/log/lynis.log
# Filtre les suggestions par categorie (exemple : authentification)
sudo grep "AUTH" /var/log/lynis-report.dat | head -20
Voici un extrait typique de sortie Lynis :
# Exemple de warnings frequents apres installation par defaut
[!] Suggestion: Set a password on GRUB boot loader to prevent altering boot configuration
[!] Suggestion: Configure a default UMASK in /etc/login.defs to improve user file permissions
[!] Suggestion: Enable process accounting (auditd)
[!] Suggestion: Install a file integrity tool to monitor changes to critical files (AIDE)
[!] Warning: Reboot of system is most likely needed (kernel update available)
# Hardening index : 67 / 100
# Tests performed : 264
# Plugins enabled : 0
Detection de rootkits avec chkrootkit
Lynis se concentre sur la configuration. chkrootkit complemente l'analyse en cherchant les signes d'une compromission active : fichiers modifies, processus caches, modules kernel suspects.
# Installe chkrootkit
sudo apt install chkrootkit -y
# Lance la detection de rootkits
# -q : mode silencieux (n'affiche que les detections positives)
sudo chkrootkit -q
# Pour un scan complet et verbeux
sudo chkrootkit
# Sortie attendue sur un systeme propre :
# rkhunter / chkrootkit : nothing found
# Si une detection positive remonte, lancez immediatement une investigation
Outil complementaire : rkhunter
# Installe Rootkit Hunter (alternative complementaire a chkrootkit)
sudo apt install rkhunter -y
# Met a jour la base de signatures
sudo rkhunter --update
# Lance un scan complet du systeme
# --skip-keypress : pas de confirmation entre sections
sudo rkhunter --check --skip-keypress
# Genere une baseline apres la premiere installation
# Toutes les modifications futures seront detectees comme suspectes
sudo rkhunter --propupd
Permissions strictes : umask, ACL, chattr
Les permissions Linux par defaut sont permissives : les nouveaux fichiers sont accessibles en lecture par les autres utilisateurs (umask 022). En production, cette permissivite est rarement justifiee. Le durcissement des permissions repose sur trois leviers : umask serre, ACL ciblees pour les exceptions legitimes, et attributs immuables (chattr) sur les fichiers critiques.
Configurer un umask plus strict
Le umask determine les permissions par defaut des nouveaux fichiers. Le umask classique 022 cree des fichiers en 644 (lecture pour tous). Un umask 027 cree des fichiers en 640 (lecture pour le proprietaire et le groupe seulement).
# Verifie le umask actuel pour l'utilisateur courant
umask
# Sortie typique : 0022
# Edite le fichier de configuration globale
sudo nano /etc/login.defs
# Cherche la ligne UMASK et modifie sa valeur
# UMASK 022 -> UMASK 027
# Pour les sessions interactives (bash), modifiez egalement
sudo nano /etc/profile.d/umask.sh
# Contenu a ajouter pour forcer umask 027 sur tous les shells
# (ne s'applique pas aux comptes systeme avec UID < 100)
if [ "$(id -u)" -ge 1000 ]; then
umask 027
fi
# Recharge les variables d'environnement
source /etc/profile
ACL : permissions fines au-dela de chmod
chmod gere les permissions classiques user/group/other. Les ACL (Access Control Lists) permettent d'accorder des permissions specifiques a un utilisateur ou groupe particulier sans modifier le proprietaire principal du fichier.
# Verifie que ACL est installe (souvent inclus par defaut)
sudo apt install acl -y
# Active les ACL sur le systeme de fichiers (si non actif)
# Verifiez d'abord avec : tune2fs -l /dev/sdaX | grep "Default mount options"
# Affiche les ACL actuels d'un fichier
getfacl /var/www/app/config.php
# Donne la lecture du fichier a un utilisateur specifique sans modifier le groupe
setfacl -m u:deployer:r /var/www/app/config.php
# Donne la lecture/ecriture a un groupe specifique
setfacl -m g:devops:rw /var/www/app/config.php
# Active les ACL par defaut pour les nouveaux fichiers d'un dossier
# Tous les nouveaux fichiers crees dans /var/log/myapp heriteront de cet ACL
setfacl -d -m g:admins:r /var/log/myapp
# Supprime un ACL specifique
setfacl -x u:deployer /var/www/app/config.php
# Supprime tous les ACL etendus
setfacl -b /var/www/app/config.php
chattr : attributs immuables
L'attribut `+i` (immuable) verrouille un fichier au niveau noyau : meme root ne peut pas le modifier, le supprimer ni le renommer sans avoir d'abord retire l'attribut. Utile pour les fichiers de configuration critiques que personne ne devrait modifier sans intention deliberee.
# Affiche les attributs etendus d'un fichier
lsattr /etc/passwd
# Sortie typique : --------------e----- /etc/passwd
# Rend /etc/passwd immuable (impossible a modifier, meme par root)
sudo chattr +i /etc/passwd
# Tentative de modification (echoue meme avec root)
sudo nano /etc/passwd
# Erreur : Operation not permitted
# Pour modifier le fichier, retirez d'abord l'attribut
sudo chattr -i /etc/passwd
# Fichiers critiques typiquement candidats a +i sur un serveur stable
sudo chattr +i /etc/passwd /etc/shadow /etc/group /etc/gshadow
sudo chattr +i /etc/sudoers /etc/ssh/sshd_config
# Attribut +a (append-only) : on peut ajouter mais pas modifier le contenu existant
# Utile pour les fichiers de log critiques
sudo chattr +a /var/log/critical-events.log
Desactiver les services inutiles
Une installation Linux par defaut active de nombreux services qui ne sont pas necessaires sur un serveur. Chaque service ecoute potentiellement sur un port, consomme des ressources et expose une surface d'attaque. La regle est simple : tout service qui n'est pas explicitement utile doit etre desactive et masque.
Inventorier les services actifs
# Liste tous les services systemd actifs sur la machine
systemctl list-units --type=service --state=running
# Liste tous les services configures (actifs et inactifs)
systemctl list-unit-files --type=service
# Filtre les services qui demarrent automatiquement au boot
systemctl list-unit-files --type=service --state=enabled
# Liste les ports en ecoute (necessite sudo)
sudo ss -tlnp
# Affichage alternatif avec netstat
sudo netstat -tlnp
Services frequemment desactivables sur un serveur
Voici les services typiques presents par defaut qui peuvent etre desactives sur un serveur web ou applicatif sans interface graphique :
| Service | Role | Necessaire sur un serveur ? |
|---|---|---|
| cups | Impression | Non (sauf serveur d'impression) |
| avahi-daemon | Decouverte zeroconf reseau | Non en production |
| bluetooth | Bluetooth | Non sur un VPS |
| ModemManager | Modems mobiles | Non |
| whoopsie | Rapport de crash Ubuntu | Non |
| apport | Rapport de bugs Ubuntu | Non |
| snapd | Gestionnaire snap | Optionnel (selon usage) |
Desactiver et masquer un service
# stop : arrete le service immediatement
sudo systemctl stop cups
# disable : empeche le demarrage automatique au boot
sudo systemctl disable cups
# mask : empeche definitivement tout demarrage (meme manuel ou via dependance)
# C'est l'option la plus stricte
sudo systemctl mask cups
# Verifie que le service est bien masque
systemctl is-enabled cups
# Sortie attendue : masked
# Pour reactiver un service masque (operation a deux etapes)
sudo systemctl unmask cups
sudo systemctl enable cups
sudo systemctl start cups
Script de durcissement par lot
#!/bin/bash
# /usr/local/sbin/disable-unused-services.sh
# Desactive et masque les services inutiles sur un serveur web Ubuntu/Debian
# Liste des services a desactiver
SERVICES=(
"cups"
"cups-browsed"
"avahi-daemon"
"bluetooth"
"ModemManager"
"whoopsie"
"apport"
)
# Boucle sur chaque service
for service in "${SERVICES[@]}"; do
# Verifie que le service existe avant d'agir
if systemctl list-unit-files | grep -q "^${service}.service"; then
echo "Desactivation et masquage de ${service}..."
sudo systemctl stop "${service}" 2>/dev/null
sudo systemctl disable "${service}" 2>/dev/null
sudo systemctl mask "${service}"
else
echo "Service ${service} non present, ignore."
fi
done
echo "Hardening services termine."
Kernel hardening avec sysctl
Le kernel Linux expose des centaines de parametres reglables a chaud via sysctl. Ces parametres controlent le comportement reseau (TCP, IP forwarding), la randomisation memoire (ASLR), les protections du systeme de fichiers et bien d'autres aspects de bas niveau. Un kernel bien regle bloque de nombreuses techniques d'attaque locale et reseau.
Inspecter les valeurs actuelles
# Affiche tous les parametres sysctl actuels (plusieurs centaines)
sudo sysctl -a | head -30
# Affiche un parametre specifique
sysctl net.ipv4.tcp_syncookies
# Recherche les parametres lies a IPv4
sudo sysctl -a | grep "net.ipv4"
Configuration de durcissement complete
Creez un fichier de configuration dedie au hardening kernel. Le placer dans `/etc/sysctl.d/` permet a systemd de le charger automatiquement au boot, sans modifier les fichiers fournis par les paquets.
# Cree le fichier de configuration de hardening
sudo nano /etc/sysctl.d/99-hardening.conf
# ========================================================
# /etc/sysctl.d/99-hardening.conf — Durcissement kernel
# ========================================================
# -------- Protection reseau (TCP/IP) --------
# Active les SYN cookies : protege contre les SYN flood DoS
# Permet d'accepter les connexions legitimes meme sous attaque
net.ipv4.tcp_syncookies = 1
# Reduit le nombre de SYN-ACK retransmis (limite l'amplification)
net.ipv4.tcp_synack_retries = 2
# Active la verification du chemin source (anti-spoofing)
# Rejette les paquets dont l'IP source est incoherente avec le routage
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Ignore les paquets ICMP redirect (potentiellement malveillants)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
# Refuse l'envoi de paquets ICMP redirect (utile uniquement pour les routeurs)
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# Ignore le source routing (anti-detournement de trafic)
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
# Log les paquets avec adresse source impossible (martians)
net.ipv4.conf.all.log_martians = 1
# Ignore les requetes ICMP echo broadcast (anti-amplification Smurf)
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Ignore les ICMP malformes (protection contre certains exploits)
net.ipv4.icmp_ignore_bogus_error_responses = 1
# -------- Protection memoire (ASLR) --------
# Active la randomisation complete de l'espace d'adressage virtuel
# 0 = desactive, 1 = partiel, 2 = complet (recommande)
kernel.randomize_va_space = 2
# Masque les adresses pointeurs kernel dans /proc (anti-info leak)
# 2 = masque toujours, 1 = masque pour les non-root, 0 = visible
kernel.kptr_restrict = 2
# Restreint l'acces aux logs kernel (dmesg) aux seuls comptes privileges
kernel.dmesg_restrict = 1
# Limite la creation de core dumps (peut contenir des secrets)
fs.suid_dumpable = 0
# -------- Protection systeme de fichiers --------
# Empeche les TOCTOU sur les hardlinks (race conditions exploitables)
fs.protected_hardlinks = 1
# Empeche les TOCTOU sur les symlinks
fs.protected_symlinks = 1
# Restreint la creation de fichiers FIFO et reguliers dans les dossiers monde-ecrivable
# Disponible sur kernel >= 4.19
fs.protected_fifos = 2
fs.protected_regular = 2
# -------- Protection ptrace (debugging) --------
# Restreint l'utilisation de ptrace : seul un parent peut tracer son enfant
# Empeche l'injection de code dans des processus tiers
kernel.yama.ptrace_scope = 1
# -------- Limites reseau supplementaires --------
# Active TCP keepalive plus rapide (detecte les connexions zombie)
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 5
# Reduit la fenetre TIME_WAIT pour liberer plus vite les sockets
net.ipv4.tcp_fin_timeout = 30
# Active la reutilisation rapide des sockets TIME_WAIT
net.ipv4.tcp_tw_reuse = 1
Appliquer la configuration
# Charge tous les fichiers /etc/sysctl.d/*.conf et applique les parametres
sudo sysctl --system
# Sortie attendue : affiche chaque ligne chargee depuis chaque fichier
# * Applying /etc/sysctl.d/99-hardening.conf ...
# net.ipv4.tcp_syncookies = 1
# net.ipv4.conf.all.rp_filter = 1
# ...
# Verifie qu'un parametre specifique est bien applique
sysctl kernel.randomize_va_space
# Sortie attendue : kernel.randomize_va_space = 2
# Test de robustesse : essaie de modifier un parametre verrouille (echoue si protected)
sudo sysctl -w kernel.kptr_restrict=0
# Tente la modification temporaire (effective jusqu'au reboot)
net.ipv4.tcp_tw_reuse peuvent affecter la compatibilite avec d'anciens load balancers. Testez en environnement de pre-production avant un rollout.
Conformite CIS Benchmarks Debian/Ubuntu
Les CIS Benchmarks (Center for Internet Security) sont des guides de configuration securisee maintenus par une communaute d'experts et adoptes comme standard de facto par les auditeurs et les organisations conformite (PCI-DSS, HIPAA, ISO 27001). Ils definissent des centaines de controles classes en deux niveaux :
- Niveau 1 (L1) : recommandations pratiques applicables a tout serveur de production sans impact fonctionnel majeur.
- Niveau 2 (L2) : recommandations strictes pour les environnements a forte sensibilite (donnees financieres, sante).
Installer OpenSCAP pour evaluer les benchmarks
# Installation des outils OpenSCAP et des contenus SCAP
sudo apt update
sudo apt install openscap-scanner ssg-debderived ssg-debian -y
# Verifie l'installation
oscap --version
# Liste les profils disponibles pour Debian
oscap info /usr/share/xml/scap/ssg/content/ssg-debian10-ds.xml
# Sortie typique : profils disponibles
# xccdf_org.ssgproject.content_profile_anssi_np_nt28_average
# xccdf_org.ssgproject.content_profile_anssi_np_nt28_high
# xccdf_org.ssgproject.content_profile_anssi_np_nt28_minimal
# xccdf_org.ssgproject.content_profile_cis_level1_server
# xccdf_org.ssgproject.content_profile_cis_level2_server
Lancer une evaluation CIS niveau 1
# Evalue le systeme contre le profil CIS L1 et genere un rapport HTML
sudo oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_cis_level1_server \
--results-arf /tmp/cis-arf.xml \
--report /tmp/cis-report.html \
/usr/share/xml/scap/ssg/content/ssg-debian10-ds.xml
# Le rapport HTML est ouvrable dans un navigateur
# Il liste chaque controle, son etat (pass/fail) et la procedure de remediation
# Pour transferer le rapport sur votre poste local
scp user@serveur:/tmp/cis-report.html ./cis-report.html
Generer un rapport synthetique avec Lynis
Lynis offre une lecture plus accessible des memes controles, sans la rigueur formelle d'OpenSCAP mais avec une couverture similaire et une remediation immediate.
# Lance Lynis avec le focus securite (subset de controles CIS)
sudo lynis audit system --pentest
# Compare le score avant/apres une session de hardening
# Avant : Hardening index : 65 / 100
# Apres : Hardening index : 88 / 100
Plan de remediation prioritaire
Sur un audit initial, les controles les plus frequemment en echec et les plus impactants sont :
| Controle | Impact | Remediation |
|---|---|---|
| GRUB sans mot de passe | Boot single-user accessible | grub-mkpasswd-pbkdf2 |
| auditd absent | Pas de journalisation appels systeme | apt install auditd |
| AIDE absent | Pas de detection modifications | apt install aide |
| UMASK 022 | Fichiers crees lisibles par tous | UMASK 027 dans /etc/login.defs |
| Mounts /tmp et /var laxistes | Execution depuis /tmp possible | Options `noexec,nosuid,nodev` |
| Comptes systeme avec shell | Surface d'attaque elargie | usermod -s /usr/sbin/nologin |
| Logs sans rotation | Saturation disque | logrotate configure |
Surveillance continue avec auditd
# Installe le daemon d'audit kernel
sudo apt install auditd audispd-plugins -y
# Active le service au demarrage
sudo systemctl enable --now auditd
# Ajoute des regles d'audit critiques (modification de fichiers sensibles)
sudo nano /etc/audit/rules.d/hardening.rules
# /etc/audit/rules.d/hardening.rules — Regles auditd
# Surveille les modifications des fichiers de comptes
-w /etc/passwd -p wa -k account_changes
-w /etc/shadow -p wa -k account_changes
-w /etc/group -p wa -k account_changes
-w /etc/sudoers -p wa -k privilege_changes
-w /etc/sudoers.d/ -p wa -k privilege_changes
# Surveille la modification des cles SSH autorisees
-w /root/.ssh/authorized_keys -p wa -k ssh_keys
# Surveille les modules kernel charges/decharges
-a always,exit -F arch=b64 -S init_module -S delete_module -k modules
# Surveille les changements d'horloge systeme
-a always,exit -F arch=b64 -S clock_settime -k time_changes
# Recharge les regles
sudo augenrules --load
# Affiche les regles actives
sudo auditctl -l
# Recherche les evenements detectes
sudo ausearch -k account_changes
Checklist de durcissement post-installation
Cette checklist condense les actions a executer dans l'ordre apres l'installation d'un serveur Linux. Chaque ligne correspond a une commande ou un ensemble de commandes documentees plus haut dans l'article.
Audit initial
- Lynis installe et premier audit lance (
lynis audit system). - Score de hardening de depart note (avant/apres).
- chkrootkit ou rkhunter execute, aucun positif detecte.
- Liste des warnings Lynis priorisee par criticite.
Permissions et utilisateurs
- UMASK 027 configure dans
/etc/login.defs. - Comptes systeme inutiles avec shell
/usr/sbin/nologin. - Fichiers critiques (
/etc/passwd,/etc/shadow) avec attribut+i. - ACL configures pour les acces fins legitimes.
Services
- cups, avahi-daemon, bluetooth, ModemManager masques.
- Aucun service ecoutant sur des ports inutiles (verification
ss -tlnp). - auditd installe et regles de hardening chargees.
- AIDE installe avec baseline initiale generee.
Kernel
/etc/sysctl.d/99-hardening.confdeploye et applique.kernel.randomize_va_space = 2verifie.- SYN cookies actives, anti-spoofing active.
- ptrace_scope restreint (1 ou superieur).
Conformite et audit continu
- OpenSCAP installe et premier scan CIS L1 execute.
- Cron hebdomadaire d'audit Lynis configure.
- Score de hardening final superieur a 85.
- Procedure de re-audit documentee pour les futures mises a jour.
Conclusion
Le hardening Linux est un processus structure plus qu'un evenement ponctuel. Il combine audit, durcissement, et surveillance continue pour reduire la surface d'attaque a son minimum operationnel. Les outils modernes — Lynis pour l'audit, OpenSCAP pour la conformite, sysctl pour le kernel, chattr et ACL pour les permissions — couvrent largement les besoins d'un serveur de production sans complexite excessive.
Le bon reflexe consiste a mesurer avant et apres chaque session de durcissement, a documenter les choix (en particulier les exceptions aux benchmarks CIS) et a planifier des audits reguliers. Un score Lynis qui descend brutalement entre deux audits est le meilleur indicateur d'une derive de configuration ou d'une compromission silencieuse.