sudo est la porte d'élévation de privilèges de vos serveurs : c'est à la
fois un point de contrôle et une cible. Mal configuré, il accorde trop, journalise
trop peu, et laisse passer des contournements. Ce guide montre comment
journaliser sudo de façon exploitable (avec enregistrement de session
rejouable), durcir les Defaults sans casser l'automatisation, et limiter
les privilèges proprement. L'approche suit la section sudo des CIS Benchmarks
(5.2/5.3 selon la version) et les recommandations R38 à R44
d'ANSSI-BP-028 v2.0.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Journaliser sudo dans un fichier dédié et enregistrer les sessions
- Éditer sudoers en sécurité avec
visudo - Durcir les
Defaults(use_pty,!visiblepw, délais) sans footgun - Limiter les privilèges : groupe dédié, négations bannies, arguments précisés
- Rejouer une session sudo avec
sudoreplaypour l'investigation
Pourquoi durcir sudo
Section intitulée « Pourquoi durcir sudo »Chaque règle sudoers est une délégation de pouvoir. Deux risques :
- Trop de privilèges : un
ALL=(ALL) ALLou des commandes mal cadrées permettent une élévation complète, parfois par contournement (un éditeur autorisé qui lance un shell, une négation!contournable). - Pas de traçabilité : par défaut, sudo ne consigne que dans syslog. Sans journal dédié ni enregistrement, vous ne savez pas qui a fait quoi lors d'un incident.
Durcir sudo, c'est donc réduire ce qui est accordé et rendre tout traçable.
Prérequis
Section intitulée « Prérequis »- Un serveur Linux (Debian, Ubuntu, RHEL, AlmaLinux, Rocky)
- Un accès root (ou un sudo fonctionnel) et un second accès de secours
- De préférence une VM de test : une erreur sudoers peut couper l'accès admin
Établir une baseline
Section intitulée « Établir une baseline »Regardez les Defaults déjà en place :
sudo grep -hE '^Defaults' /etc/sudoers /etc/sudoers.d/* 2>/dev/nullSur une Debian 12, vous trouverez en général :
Defaults env_resetDefaults mail_badpassDefaults secure_path="..."Defaults use_ptySur Debian 12 (sudo 1.9.13p3), use_pty, mail_badpass (alerte mail en
cas d'échec d'authentification) et secure_path (PATH fixe, anti détournement de
binaire lancé via sudo) sont déjà posés. Attention toutefois : use_pty n'est
le défaut upstream qu'à partir de sudo 1.9.14 ; Debian et Ubuntu l'activent via
un correctif distributeur, mais une RHEL/Rocky plus ancienne peut ne pas l'avoir
(vérifiez avec sudo --version). Mauvaise nouvelle commune : aucun journal
dédié n'est configuré, sudo ne consigne que dans syslog.
Journaliser sudo et enregistrer les sessions
Section intitulée « Journaliser sudo et enregistrer les sessions »C'est le cœur du durcissement : rendre chaque usage de sudo exploitable.
Créez /etc/sudoers.d/10-hardening :
-
Définir un journal dédié et l'enregistrement de session
Defaults logfile="/var/log/sudo.log"Defaults log_input, log_outputDefaults iolog_dir="/var/log/sudo-io" -
Valider puis poser les bons droits
Fenêtre de terminal sudo visudo -cf /etc/sudoers.d/10-hardeningsudo chmod 0440 /etc/sudoers.d/10-hardening -
Vérifier que tout est capturé
Après une commande
sudo idlancée par un utilisateur, le journal dédié contient l'essentiel :Jun 25 07:34:44 : alice : PWD=/home/alice ; USER=root ; TSID=000001 ;COMMAND=/usr/bin/idEt la session complète est enregistrée :
Fenêtre de terminal sudo ls /var/log/sudo-io/sudo sudoreplay -l # lister les sessions et leurs TSIDsudo sudoreplay 000001 # rejouer la session par son TSIDLe TSID est un identifiant de 6 caractères (ici
000001) ;sudoreplay -lvous le donne pour chaque session.
sudoreplay rejoue la session à l'identique (frappes et sortie), un atout
majeur pour l'investigation après incident.
Renforcer les Defaults
Section intitulée « Renforcer les Defaults »Ajoutez au même fichier les options qui réduisent les abus :
Defaults use_ptyDefaults !visiblepwDefaults passwd_tries=3Defaults passwd_timeout=1Defaults timestamp_timeout=5| Option | Effet |
|---|---|
use_pty | Exécute la commande dans un pseudo-terminal : empêche une tâche lancée via sudo de détourner le terminal réel |
!visiblepw | Refuse sudo si la saisie du mot de passe serait visible (terminal sans masquage) |
passwd_tries | Nombre d'essais de mot de passe autorisés (défaut 3) avant échec |
passwd_timeout | Délai (minutes) pour saisir le mot de passe |
timestamp_timeout | Durée (minutes) avant de redemander le mot de passe. Défaut 15 ; 5 est plus strict, 0 redemande à chaque sudo |
Limiter les privilèges
Section intitulée « Limiter les privilèges »Au-delà des Defaults (que l'ANSSI regroupe sous R39), ce sont les règles
qui comptent. Le découpage R40 à R44 vise à n'accorder que le strict
nécessaire.
-
Un groupe dédié (ANSSI R38) : accordez sudo via un groupe (
%sudosur Debian,%wheelsur RHEL), jamais à des utilisateurs en direct.%sudo ALL=(ALL:ALL) ALL -
Cibler un compte non privilégié (R40) : quand une commande n'exige pas root, imposez l'utilisateur cible.
alice ALL=(www-data) /usr/bin/...vaut mieux qu'un(root)réflexe qui rouvre la porte de l'élévation complète. -
Bannir les négations (R42) : une règle du type
ALL, !/bin/suest contournable (chemins alternatifs, copies du binaire). Listez ce qui est autorisé, pas ce qui est interdit. -
Préciser les arguments (R43) :
alice ALL=(root) /usr/bin/systemctl restart nginxest bien plus sûr que/usr/bin/systemctltout court, qui permettraitsystemctl editet donc un shell root. Méfiez-vous des jokers : une règle commecat /var/log/messages*laisse lire/etc/shadowvia un chemin remontant (../../etc/shadow). Un*dans un chemin est presque toujours une faille. -
Éviter les commandes qui ouvrent un shell (R41) :
vi,less,find,awkautorisés sans restriction permettent de sortir vers un shell root (la référence des évasions est GTFOBins). Forcez la directiveNOEXEC, qui empêche la commande de lancer un sous-processus :%ops ALL=(root) NOEXEC: /usr/bin/less -
Éditer un fichier sans shell root (R44) : pour laisser modifier une configuration, utilisez
sudoedit(aliassudo -e) plutôt qu'un éditeur lancé en root.sudoeditcopie le fichier, l'édite sous l'identité de l'utilisateur, puis le réinstalle : l'éditeur ne tourne jamais avec les privilèges root.alice ALL=(root) sudoedit /etc/nginx/nginx.conf
Patcher sudo : durcir ne dispense pas de mettre à jour
Section intitulée « Patcher sudo : durcir ne dispense pas de mettre à jour »Aucun Defaults ne protège d'une faille dans sudo lui-même. Deux
vulnérabilités majeures le rappellent :
- CVE-2021-3156 « Baron Samedit » (CVSS 7.8) : un débordement de tas exploitable par n'importe quel utilisateur local pour devenir root, sans même figurer dans sudoers. Versions touchées : sudo 1.8.2 à 1.8.31p2 et 1.9.0 à 1.9.5p1, corrigé en 1.9.5p2.
- CVE-2023-22809 (CVSS 7.8) : un contournement de
sudoeditvia un séparateur--injecté dans$EDITOR/$SUDO_EDITORpermettait d'éditer un fichier hors périmètre (jusqu'à/etc/shadow). Corrigé en 1.9.12p2.
Vérifiez votre version et tenez-la à jour :
sudo --version | head -1La leçon est constante en durcissement : réduire les privilèges et appliquer les correctifs sont deux chantiers complémentaires, jamais l'un sans l'autre.
Vérifier
Section intitulée « Vérifier »Quelques contrôles rapides :
# La configuration globale est-elle valide ?sudo visudo -c
# Quelles règles s'appliquent à un utilisateur ?sudo -lU alice
# Le journal dédié grossit-il à chaque sudo ?sudo tail -f /var/log/sudo.logSécurité et points de vigilance
Section intitulée « Sécurité et points de vigilance »- Garder un accès de secours : avant de durcir, gardez une session root ou une console ouverte. Une erreur sudoers se corrige depuis cet accès.
- Protéger les journaux :
/var/log/sudo.loget/var/log/sudo-iodoivent être en accès root uniquement, et idéalement déportés vers un collecteur (un attaquant qui obtient root effacerait les logs locaux). - Tracer les changements de sudoers : couplez avec
auditd, qui surveille
/etc/sudoerset/etc/sudoers.d/(cléscope). - Revoir régulièrement :
sudo -lU <user>pour auditer les droits réels, pas seulement la théorie des fichiers.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
| Plus aucun sudo ne fonctionne | Erreur de syntaxe écrite sans visudo | Corriger depuis l'accès root de secours, valider avec visudo -c |
| Le cron ou un script sudo échoue | requiretty posé | Retirer requiretty, garder use_pty |
Rien dans /var/log/sudo.log | logfile absent ou fichier non rechargé | Vérifier /etc/sudoers.d/, droits 0440, relancer une commande |
sudoreplay ne trouve rien | log_output non activé | Ajouter log_input, log_output et iolog_dir |
| Une règle « tout sauf X » est contournée | Usage de négations ! | Lister les commandes autorisées explicitement |
À retenir
Section intitulée « À retenir »- Toujours
visudo: jamais d'édition directe de sudoers - Journal dédié (
logfile) + enregistrement de session (log_input/log_output) rejouable avecsudoreplay use_pty(souvent déjà par défaut) et!visiblepw; jamaisrequiretty(casse le non-interactif)- Groupe dédié (R38), compte cible non privilégié (R40), pas de négations (R42), arguments précisés (R43),
NOEXEC(R41),sudoedit(R44) - Mettre à jour sudo : durcir ne remplace pas le patch (Baron Samedit, contournement
sudoedit) - Protéger les journaux sudo (root only, déportés) car ils contiennent des traces sensibles
- Référentiels : section sudo des CIS Benchmarks (5.2/5.3 selon version) et ANSSI-BP-028 R38 à R44