Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English
Read in English

sysctl : durcir le noyau et la pile réseau Linux

Par mis à jour le

Améliorer cette page

sysctl règle les paramètres du noyau Linux à chaud : comment la pile réseau traite les paquets, ce que le noyau expose aux processus, comment le système de fichiers se protège. Par défaut, plusieurs de ces réglages favorisent la compatibilité plutôt que la sécurité. Ce guide montre comment établir une baseline, appliquer un jeu de durcissement aligné sur les CIS Benchmarks et ANSSI-BP-028 v2.0 de façon persistante, vérifier son effet, et éviter les pièges (un paramètre mal posé peut couper le réseau). Le jeu proposé couvre plusieurs recommandations ANSSI : R9 (noyau, dont l'ASLR), R11 (LSM Yama/ptrace), R12 (réseau IPv4), R13 (IPv6) et R14 (systèmes de fichiers). La R8 (options mémoire) se pose, elle, sur la ligne de commande du noyau, pas avec sysctl. Public visé : administrateurs qui durcissent un serveur exposé.

  • Lire et modifier un paramètre noyau (sysctl -n, -w, sysctl.d)
  • Capturer une baseline avant de toucher quoi que ce soit
  • Appliquer un jeu de durcissement réseau, noyau et fichiers, persistant au reboot
  • Vérifier l'effet réel (et pourquoi certains réglages exigent une VM)
  • Éviter les réglages qui cassent le routage ou un nœud Kubernetes

sysctl est l'interface qui lit et écrit les variables du noyau exposées sous /proc/sys/. Chaque variable a un nom hiérarchique (net.ipv4.ip_forward) qui correspond à un fichier (/proc/sys/net/ipv4/ip_forward).

ActionCommandePersistance
Lire une valeursysctl -n net.ipv4.ip_forwardSans objet
Modifier à chaudsysctl -w net.ipv4.ip_forward=0Perdu au reboot
Rendre persistantFichier dans /etc/sysctl.d/ + sysctl --systemSurvit au reboot

Certains réglages ne passent pas par sysctl du tout : ils doivent être posés avant le démarrage du noyau, sur sa ligne de commande. C'est le cas de audit=1 ou de plusieurs options de sécurité mémoire, traitées dans Passer des paramètres au noyau au démarrage.

Pour le durcissement pilotable à chaud, on écrit toujours dans un fichier de /etc/sysctl.d/ : les modifications à la volée (-w) servent au test mais disparaissent au redémarrage.

  • Un serveur Linux (Debian, Ubuntu, RHEL, AlmaLinux, Rocky) ou une VM
  • Un accès root (ou sudo)
  • Idéalement une VM de test : certains réglages réseau peuvent couper une connexion mal anticipée

Avant de durcir, mesurez l'existant. Les valeurs par défaut varient selon la distribution et la version, donc ne supposez rien.

Fenêtre de terminal
for k in net.ipv4.conf.all.accept_redirects net.ipv4.conf.all.send_redirects \
net.ipv4.conf.all.rp_filter net.ipv4.conf.all.log_martians \
kernel.kptr_restrict kernel.yama.ptrace_scope; do
printf "%-42s = %s\n" "$k" "$(sysctl -n $k)"
done

Sur une Debian 12 fraîche, plusieurs réglages sensibles sont peu sûrs par défaut (valeurs du noyau Debian, que la distribution ne retouche pas) :

net.ipv4.conf.all.accept_redirects = 1
net.ipv4.conf.all.send_redirects = 1
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.all.log_martians = 0
kernel.kptr_restrict = 0
kernel.yama.ptrace_scope = 0

Ce sont précisément ces valeurs que le durcissement va corriger. D'autres (comme kernel.randomize_va_space = 2 ou fs.protected_symlinks = 1) sont souvent déjà correctes, mais on les fige quand même pour éviter toute dérive. Sur Debian 13, le fichier /usr/lib/sysctl.d/50-default.conf livré par systemd pose rp_filter = 2 sur chaque interface mais exclut explicitement conf.all, qui reste à la valeur du noyau.

Placez la configuration dans /etc/sysctl.d/99-hardening.conf. Deux règles de précédence à connaître : à nom de fichier identique, le répertoire gagne (/etc > /run > /usr/lib) ; à noms différents, c'est le nom le plus grand en ordre lexical qui l'emporte. Le préfixe 99- garantit donc que votre fichier est lu en dernier et prime sur les valeurs posées par la distribution ; sysctl --system lit enfin /etc/sysctl.conf tout à la fin.

  1. Créer le fichier de durcissement

    /etc/sysctl.d/99-hardening.conf
    # --- Reseau : routage et redirections (paires all + default) ---
    net.ipv4.ip_forward = 0
    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
    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.ipv6.conf.all.accept_source_route = 0
    # --- Reseau : anti-spoofing et journalisation ---
    net.ipv4.conf.all.rp_filter = 1
    net.ipv4.conf.default.rp_filter = 1
    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.tcp_syncookies = 1
    net.ipv4.tcp_rfc1337 = 1
    net.ipv6.conf.all.accept_ra = 0
    net.ipv6.conf.default.accept_ra = 0
    # --- Noyau : exposition d'informations et eBPF ---
    kernel.kptr_restrict = 2
    kernel.dmesg_restrict = 1
    kernel.randomize_va_space = 2
    kernel.yama.ptrace_scope = 1
    kernel.unprivileged_bpf_disabled = 2
    net.core.bpf_jit_harden = 2
    kernel.kexec_load_disabled = 1
    # --- Systeme de fichiers ---
    fs.protected_hardlinks = 1
    fs.protected_symlinks = 1
    fs.protected_fifos = 2
    fs.protected_regular = 2
    fs.suid_dumpable = 0
  2. Appliquer la configuration

    Fenêtre de terminal
    sudo sysctl --system
    * Applying /etc/sysctl.d/99-hardening.conf ...

    sysctl --system recharge tous les fichiers sysctl.d dans l'ordre.

C'est le piège qui ruine un durcissement sans que personne ne s'en aperçoive. Contrairement à ce qu'on attend, sysctl --system ne signale pas un paramètre inexistant : il implique l'option -e, qui supprime justement ces erreurs.

Mesuré sur AlmaLinux 10 puis sur Debian 13 (procps-ng 4.0.4) avec une clé volontairement fautive : sysctl --system n'affiche aucun message la concernant et sort en code 0. Vous croyez avoir durci la machine, et vous ne l'avez pas fait.

Pour voir l'erreur, il faut viser le fichier explicitement :

Fenêtre de terminal
sudo sysctl -p /etc/sysctl.d/99-hardening.conf
sysctl: cannot stat /proc/sys/kernel/parametre_inexistant: No such file or directory

Prenez donc l'habitude de valider chaque fichier avec sysctl -p <fichier> après l'avoir écrit, puis de contrôler la valeur réellement appliquée, qui seule fait foi :

Fenêtre de terminal
sysctl -n kernel.kptr_restrict

Le fichier ci-dessus empile une trentaine de lignes, et les appliquer sans les comprendre revient à recopier une recette. Les six familles ci-dessous disent chacune contre quoi elles protègent, et à quel prix.

  • redirections et source route : un attaquant sur le réseau ne peut plus détourner votre trafic via des redirections ICMP ou un routage forcé.
  • rp_filter : le reverse path filtering strict jette les paquets dont l'adresse source est incohérente avec la route, un anti-spoofing de base.
  • kptr_restrict et dmesg_restrict : on cache les adresses noyau et les journaux kernel, qui servent à fiabiliser un exploit.
  • ptrace_scope : un processus ne peut plus en espionner un autre hors de sa descendance, par le LSM Yama, qui doit être chargé.
  • unprivileged_bpf_disabled et bpf_jit_harden : on ferme l'eBPF aux comptes non privilégiés et on durcit le JIT, une surface noyau notoire. La valeur 2, déjà le défaut sur Debian 12, reste réversible ; 1 verrouille jusqu'au redémarrage.
  • kexec_load_disabled = 1, règle ANSSI R9, interdit de charger un noyau de remplacement à chaud. La contrepartie est lourde : cela désactive kdump, qui repose sur kexec, donc ne le posez pas si vous capturez des vidages mémoire.

Relisez les valeurs ciblées : elles doivent avoir basculé. Chacune doit afficher la valeur posée dans le fichier, preuve que le noyau l'a prise.

Fenêtre de terminal
sysctl net.ipv4.conf.all.rp_filter kernel.kptr_restrict kernel.yama.ptrace_scope
net.ipv4.conf.all.rp_filter = 1
kernel.kptr_restrict = 2
kernel.yama.ptrace_scope = 1

Pour une preuve concrète, regardez l'effet de kptr_restrict = 2 sur les adresses des symboles du noyau :

Fenêtre de terminal
head -2 /proc/kallsyms
0000000000000000 A fixed_percpu_data
0000000000000000 A __per_cpu_start

Les adresses réelles sont masquées (remplacées par des zéros), même pour root : un exploit local ne peut plus les lire pour contourner l'ASLR du noyau. Les trois niveaux : 0 les expose selon le contexte, 1 les cache aux processus non privilégiés, 2 les cache à tous, root compris.

C'est la limite à connaître avant de penser durcir « partout ». Dans un conteneur Docker non privilégié, /proc/sys est monté en lecture seule : même les net.*, pourtant isolés par le noyau, se refusent depuis l'intérieur. Mesuré avec Docker 29.1.3 sur une image Debian 13 :

Fenêtre de terminal
# Dans un conteneur Docker
sysctl -w kernel.kptr_restrict=2
# sysctl: permission denied on key "kernel.kptr_restrict"
sysctl -w net.ipv4.conf.all.rp_filter=1
# sysctl: permission denied on key "net.ipv4.conf.all.rp_filter"
# Depuis l'hôte, au lancement : accepté pour net.*
docker run --rm --sysctl net.ipv4.conf.all.rp_filter=1 \
debian:13-slim@sha256:020c0d20b9880058cbe785a9db107156c3c75c2ac944a6aa7ab59f2add76a7bd \
cat /proc/sys/net/ipv4/conf/all/rp_filter
# 1
FamilleConteneur Docker non privilégiéVM / physique
kernel.* (hors IPC), fs.*Refusé, partagé avec l'hôteModifiable
kernel.* IPC (shm*, msg*, sem)Isolé par IPC ns, posé par --sysctlModifiable
net.*Isolé par netns, posé par --sysctlModifiable

Concrètement : un durcissement noyau complet ne s'applique qu'au niveau de l'hôte (ou d'une VM), pas depuis un conteneur applicatif. Les conteneurs héritent du noyau durci de l'hôte.

Certains réglages cassent des cas légitimes. Adaptez avant d'appliquer en masse :

  • ip_forward = 0 coupe le routage. Un routeur, une passerelle NAT, un nœud Kubernetes ou un hôte Docker ont besoin de ip_forward = 1. Ne durcissez ce paramètre que sur un serveur applicatif simple.
  • rp_filter = 1 (strict) casse le routage asymétrique et les hôtes multi-homés. En cas de doute, utilisez la valeur 2 (mode lâche). Subtilité : le noyau applique max(conf.all, conf.<interface>), donc poser all = 0 ne désactive pas le filtrage si une interface a une valeur plus haute ; et default ne s'applique qu'aux interfaces créées ensuite. CIS et ANSSI veulent 1, là où systemd/Debian retiennent souvent 2 par défaut, exprès.
  • accept_ra = 0 suppose une IPv6 configurée statiquement. Sur un réseau qui distribue les préfixes par Router Advertisement, gardez-le activé.
  • Désactiver IPv6 (ANSSI R13, net.ipv6.conf.all.disable_ipv6 = 1) est un choix, pas un défaut : si sshd ou Postfix écoutent sur ::1, ils peuvent refuser de démarrer (prévoyez AddressFamily inet / inet_protocols = ipv4). La forme radicale est ipv6.disable=1 sur la ligne de commande GRUB.
  • Gare aux gestionnaires réseau : NetworkManager et systemd-networkd reposent leurs valeurs par interface après systemd-sysctl. Si un réglage par interface ne tient pas, corrigez-le côté gestionnaire (IPv4ReversePathFilter= pour networkd) plutôt qu'en empilant des fichiers sysctl.
  • Yama doit être chargé pour que kernel.yama.ptrace_scope existe : vérifiez avec cat /sys/kernel/security/lsm (sinon, ajoutez yama à lsm= au boot).
  • Toujours tester sur une VM ou via une console de secours (KVM/IPMI) : un mauvais réglage réseau appliqué à distance peut vous couper l'accès.

Pour industrialiser ces réglages sur un parc, le module ansible.posix.sysctl applique et rend persistants ces paramètres de façon idempotente.

Ces cinq symptômes partagent un trait : aucun ne pointe le fichier fautif. Un permission denied, une valeur qui revient à l'ancienne ou une clé silencieusement ignorée disent seulement que le réglage n'a pas pris, jamais pourquoi. Les trois premiers viennent du mécanisme, conteneur, -w ou ordre de lecture, les deux derniers du contenu du fichier.

SymptômeCause probableSolution
permission denied on key kernel.*Exécution dans un conteneurAppliquer sur l'hôte ou une VM
Le réglage revient à l'ancienne valeur après rebootModifié avec -w au lieu d'un fichier sysctl.dÉcrire dans /etc/sysctl.d/ puis sysctl --system
Une valeur de sysctl.d est ignoréeUn fichier au préfixe plus élevé la réécritVérifier l'ordre avec sysctl --system ; nommer en 99-
Perte de connectivité après applicationip_forward=0 ou rp_filter=1 sur un routeur/multi-homéRestaurer via console, ajuster (ip_forward=1, rp_filter=2)
cannot stat /proc/sys/... avec sysctl -p <fichier>Paramètre absent sur ce noyau (que sysctl --system tait)Retirer la ligne, ou charger le module qui crée la clé

Un durcissement sysctl ne vaut que s'il tient après redémarrage. Ce lab vous fait écrire un jeu de paramètres dans /etc/sysctl.d/, l'appliquer avec sysctl --system et prouver que les valeurs survivent au reboot de la VM.

  • sysctl règle le noyau à chaud ; pour durcir, on écrit dans /etc/sysctl.d/ (le 99- prime)
  • Capturez une baseline d'abord : les défauts varient selon la distribution
  • Cibles clés : redirections, rp_filter, kptr_restrict, ptrace_scope (Yama), eBPF, protections fs (ANSSI R9/R11/R12/R14)
  • kptr_restrict = 2 masque les adresses noyau à tous, root compris (vérifiable dans /proc/kallsyms)
  • En conteneur, seuls les net.* et l'IPC namespacé sont isolés, et Docker les pose au lancement (--sysctl) : le durcissement noyau se fait sur l'hôte/VM
  • Attention à ip_forward et rp_filter (sémantique max(all, iface)) : ils cassent routeurs et hôtes multi-homés

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn