Durcir le noyau Linux de son NAS selon les normes CIS Level 2

Durcir le noyau Linux de son NAS selon les normes CIS Level 2

·7 min de lecture·Mis à jour le 27 janvier 2026

Au-delà du simple pare-feu

Un pare-feu et fail2ban ne couvrent que la surface. Le noyau Linux lui-même, avec ses paramètres par défaut permissifs, ses modules inutiles chargés en mémoire et ses points de montage sans restrictions, reste une passoire — et ces vecteurs d'attaque sont tous documentés et exploitables.

Les CIS benchmarks (Center for Internet Security) proposent deux niveaux : Level 1 pour les serveurs standard, Level 2 pour les environnements sensibles. Pour un NAS qui stocke photos de famille, backups et données domotiques, c'est Level 2. Configuration de référence ici : TerraMaster F4-424 sous Debian 13 (Trixie).

La collection devsec.hardening

Appliquer 200+ recommandations CIS à la main n'a pas de sens quand la collection Ansible devsec.hardening le fait déjà, maintenue et validée par la communauté.

L'organisation retenue découpe ça en rôles CIS spécialisés — cis_permissions, cis_accounts, cis_cron, cis_sudo, cis_tcpwrappers, cis_logging, cis_services, cis_ntp — chacun taggé et indépendant. N'exécuter que le logging tient en une commande Ansible.

Plus de 40 paramètres sysctl

Le fichier /etc/sysctl.d/99-hardening.conf concentre l'essentiel.

Protections mémoire et noyau

# Désactiver io_uring (vecteur d'attaque fréquent)
kernel.io_uring_disabled = 2

# Interdire le chargement dynamique de noyaux (kexec)
kernel.kexec_load_disabled = 1

# ASLR complet (randomisation de l'espace d'adressage)
kernel.randomize_va_space = 2

# Restreindre l'accès aux pointeurs noyau dans les logs
kernel.kptr_restrict = 2

# Restreindre dmesg aux utilisateurs root
kernel.dmesg_restrict = 1

# Interdire les core dumps pour les programmes SUID
fs.suid_dumpable = 0

# Restreindre l'accès aux événements perf
kernel.perf_event_paranoid = 3

# Désactiver les vsyscalls (vecteur ROP)
# (configuré via GRUB: vsyscall=none)

Protections réseau

# Reverse path filtering (anti-spoofing)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Ignorer les redirections ICMP
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

# Ignorer les requêtes ICMP broadcast
net.ipv4.icmp_echo_ignore_broadcasts = 1

# Protection contre les SYN flood
net.ipv4.tcp_syncookies = 1

# Interdire le routage source
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0

# Désactiver le forwarding IPv6 (le NAS n'est pas un routeur)
net.ipv6.conf.all.forwarding = 0

# Logging des paquets martiens
net.ipv4.conf.all.log_martians = 1

Une quarantaine de paramètres au total, chacun documenté dans le benchmark CIS et fermant un vecteur précis.

GRUB : les paramètres de boot

Certains durcissements doivent être appliqués au chargement du noyau :

GRUB_CMDLINE_LINUX="slab_nomerge pti=on randomize_kstack_offset=on vsyscall=none debugfs=off"
  • slab_nomerge : empêche la fusion des caches slab, ce qui limite les attaques par confusion de types
  • pti=on : Page Table Isolation, la mitigation contre Spectre et Meltdown
  • randomize_kstack_offset : la pile noyau est randomisée à chaque syscall
  • vsyscall=none : élimine un gadget ROP connu
  • debugfs=off : ferme le filesystem de debug du kernel

Blacklister les modules inutiles

Dans /etc/modprobe.d/hardening.conf :

# Systèmes de fichiers exotiques
install cramfs /bin/true
install freevxfs /bin/true
install jffs2 /bin/true
install hfs /bin/true
install hfsplus /bin/true
install squashfs /bin/true
install udf /bin/true

# Protocoles réseau rarement utilisés
install dccp /bin/true
install sctp /bin/true
install rds /bin/true
install tipc /bin/true

# USB storage (désactivé sur un NAS headless)
install usb-storage /bin/true

L'astuce install <module> /bin/true est plus solide qu'un simple blacklist : un blacklist peut être contourné par des dépendances, alors que « installe /bin/true » ne fait rien, silencieusement. Un blacklist squashfs seul laisse le module se charger quand même.

Durcissement des points de montage

Dans /etc/fstab :

tmpfs  /tmp      tmpfs  defaults,noexec,nosuid,nodev  0 0
tmpfs  /dev/shm  tmpfs  defaults,noexec,nosuid,nodev  0 0
  • noexec : aucun binaire ne peut s'exécuter, donc pas de payload déposé puis lancé
  • nosuid : bits SUID/SGID ignorés
  • nodev : création de fichiers device interdite

Pour /proc, hidepid=2 empêche les utilisateurs lambda de voir les processus des autres :

proc  /proc  proc  defaults,hidepid=2  0 0

AppArmor en mode enforce

AppArmor fournit du MAC (Mandatory Access Control) : même compromis, un processus ne peut toucher qu'à ce que son profil autorise. Sur Debian 13, AppArmor est activé par défaut mais souvent en mode « complain » (log uniquement). Le hardening le passe en enforce :

aa-enforce /etc/apparmor.d/*

Une commande, mais c'est la différence entre « on sait ce qui s'est passé » et « on empêche que ça se passe ».

Politiques de mots de passe (NIST SP 800-63B)

# /etc/security/pwquality.conf
minlen = 15          # 15 caractères minimum
minclass = 3         # Au moins 3 classes de caractères
maxrepeat = 3        # Max 3 caractères identiques consécutifs
# /etc/login.defs
PASS_MAX_DAYS  365   # Expiration à 365 jours
PASS_MIN_DAYS  1     # 1 jour minimum entre les changements
LOGIN_RETRIES  3     # 3 tentatives de login
LOGIN_TIMEOUT  60    # Timeout de 60 secondes
UMASK          077   # Permissions restrictives par défaut

Plus le verrouillage de compte après 3 échecs avec un délai de 15 minutes via PAM (pam_faillock), et les core dumps globalement désactivés dans /etc/security/limits.conf.

Mises à jour automatiques

unattended-upgrades applique les correctifs de sécurité quotidiennement, avec reboot automatique à 4 h du matin si nécessaire :

# /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";

Un NAS non patché finira compromis. Le créneau de 4 h évite de couper un usage réel.

AIDE : surveiller l'intégrité des fichiers

AIDE (Advanced Intrusion Detection Environment) compare l'état du système à une baseline et signale tout ce qui a changé :

# Initialisation de la base
aide --init
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# Vérification quotidienne (via cron)
aide --check

Si un binaire système change sans raison légitime — et il y en a peu — AIDE le voit.

Audit logging avec auditd

auditd trace les événements de sécurité, ici avec plus de 40 règles :

# /etc/audit/rules.d/hardening.rules

# Surveillance des changements d'authentification
-w /etc/passwd -p wa -k auth_changes
-w /etc/shadow -p wa -k auth_changes
-w /etc/group -p wa -k auth_changes

# Surveillance de sudo
-w /etc/sudoers -p wa -k sudo_changes
-w /etc/sudoers.d/ -p wa -k sudo_changes

# Chargement de modules noyau
-a always,exit -F arch=b64 -S init_module -S delete_module -k modules

# Changements réseau
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k network

# Surveillance des packages
-w /usr/bin/dpkg -p x -k packages
-w /usr/bin/apt -p x -k packages

# Surveillance de systemd
-w /etc/systemd/ -p wa -k systemd
-w /usr/lib/systemd/ -p wa -k systemd

Ces logs sont ce qui permet, après coup, de savoir qui a fait quoi, quand et avec quel outil — le point de départ de toute investigation.

Ce qu'il faut retenir

CIS Level 2 sur un NAS domestique peut sembler excessif, mais chaque paramètre ferme un vecteur réel et documenté. Grâce à devsec.hardening et aux rôles Ansible, l'application tient en une commande et se maintient sans effort. Le vrai travail est de comprendre ce que chaque règle fait : appliquer un benchmark sans le lire ne protège pas grand-chose.

PartagerLinkedInXBluesky

Articles similaires