SUDO : Maîtrise et Sécurisation

SUDO : Maîtrise et Sécurisation

Introduction

Dans un contexte de durcissement et de sécurisation des systèmes d'information, sudo demeure un pilier incontournable. Bien qu'omniprésent dans les infrastructures Linux/Unix, cet outil est fréquemment mal configuré, créant des vecteurs d'attaque exploitables par des acteurs malveillants. Cet article couvre les aspects fondamentaux, les configurations multi-distributions, et surtout, les bonnes pratiques de sécurisation que doit maîtriser tout administrateur système responsable d'une infrastructure résiliente.

Depuis sa création en 1980 à l'Université de Californie à Berkeley, sudo (Substitute User DO) a résolu un problème critique : permettre aux utilisateurs non-root d'exécuter des commandes avec privilèges élevés sans exposer le compte root. Aujourd'hui, il reste le mécanisme de délégation privilèges préféré par les recommandations officielles, dont celles de l'ANSSI.

Fondamentaux : Pourquoi SUDO plutôt que ROOT

Le partage du compte root entre administrateurs présente des risques structurels :

  • Absence de traçabilité : Impossible de déterminer qui a fait quoi
  • Exposition du mot de passe root : Chaque administrateur connaît le même mot de passe
  • Absence de granularité : L'utilisateur root peut tout faire, partout

Sudo résout ces problèmes en implémentant le principe du moindre privilège (Principle of Least Privilege - PoLP) :

  • Chaque utilisateur dispose de son propre mot de passe
  • Seules les commandes strictement nécessaires sont autorisées
  • Chaque action est enregistrée dans les journaux systèmes
  • Les privilèges sont temporaires et limités dans le temps

Architecture et Mécanisme de Sudo

Quand un utilisateur exécute sudo commande, le flux est le suivant :

  1. Vérification des permissions → Consultation du fichier /etc/sudoers
  2. Validation de l'hôte → Vérification que la règle s'applique à cette machine
  3. Authentification → Demande du mot de passe utilisateur (non root)
  4. Décision d'accès → Autorisation ou refus
  5. Exécution → Lancement de la commande avec privilèges élevés
  6. Logging → Enregistrement de l'action

Contrairement à su - (qui charge l'environnement root complètement), sudo préserve l'environnement utilisateur et ajoute des variables SUDO_*.

Installation et Vérification Multi-Distributions

L'installation diffère selon la distribution, mais le principe reste identique. Avant de commencer, vérifiez que sudo est installé :

which sudo
sudo -V | head -n 1

Debian / Ubuntu

apt-get update
apt-get install sudo

Ajout d'un utilisateur au groupe sudo :

usermod -aG sudo username

RHEL / CentOS / Fedora

dnf install sudo

Ajout d'un utilisateur au groupe wheel :

usermod -aG wheel username

Note critique : Debian/Ubuntu utilise le groupe sudo, tandis que Red Hat/Fedora utilise wheel. Cette différence est fréquemment cause d'erreur lors de migrations.

Vérification des permissions actuelles

sudo -l              # Liste les permissions de l'utilisateur courant
sudo -l -U username  # Liste les permissions d'un autre utilisateur
id username          # Affiche les groupes de l'utilisateur

Configuration du Fichier /etc/sudoers

Le fichier /etc/sudoers est la clé de voûte de la sécurité sudo. Toujours l'éditer avec visudo, jamais avec un éditeur de texte classique.

sudo visudo          # Mode par défaut (éditeur vi)
sudo EDITOR=vim visudo  # Force vim
sudo visudo -f /etc/sudoers.d/ADMINS  # Édite un fichier spécifique

Syntaxe fondamentale

WHO HOSTS=(USERS:GROUPS) [OPTIONS] COMMANDS

Exemple basique :

# Utilisateur spécifique
username ALL=(ALL:ALL) ALL

# Groupe (préfixe %)
%wheel ALL=(ALL:ALL) ALL

# Commande limitée
itconnect ALL=(ALL) /usr/bin/apt update, /usr/bin/apt upgrade

# Sans mot de passe (DANGEREUX)
%sysadmins ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx

Utilisation des alias pour la granularité

Les alias rendent les configurations scalables et maintenables :

# Alias utilisateurs
User_Alias ADMINS = alice, bob, charlie
User_Alias DEVEL = david, emma

# Alias machines (utile en infrastructure distribuée)
Host_Alias SERVERS = server1, server2, 192.168.1.0/24
Host_Alias WORKSTATIONS = workstation1, workstation2

# Alias commandes
Cmnd_Alias APT_MANAGE = /usr/bin/apt update, /usr/bin/apt upgrade, /usr/bin/apt install
Cmnd_Alias REBOOT_SRV = /usr/sbin/shutdown, /usr/sbin/reboot
Cmnd_Alias LOGS = /usr/bin/tail -f /var/log/*, /usr/bin/journalctl -f

# Application des alias
ADMINS ALL=(ALL:ALL) APT_MANAGE
DEVEL SERVERS=(ALL) /usr/bin/python3, /usr/bin/git
%devops ALL=(root) NOPASSWD: REBOOT_SRV

Sécurisation Avancée : Options Defaults

Les directives Defaults s'appliquent globalement ou spécifiquement à des utilisateurs/groupes. Voici les configurations essentielles pour le durcissement :

1. PATH sécurisé et variables d'environnement

# Forcer un PATH sûr (prévient injection de chemin)
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# Réinitialiser l'environnement (supprime les variables utilisateur)
Defaults env_reset

# Whitelist des variables à préserver
Defaults env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"

2. Authentification et gestion du timeout

# Exiger un vrai TTY (prévient les exploitations depuis cron/CGI)
Defaults requiretty

# Timeout du timestamp (en minutes) - 0 = à chaque fois
Defaults timestamp_timeout=5

# Demander le mot de passe à chaque commande
Defaults:critical_users timestamp_timeout=0

# Afficher les astérisques lors de la saisie du mot de passe
Defaults pwfeedback

# Nombre de tentatives de mot de passe
Defaults passwd_tries=3

3. Exécution sécurisée en pseudo-terminal

# Allouer un pseudo-TTY pour chaque commande
# Prévient les attaques où un malware créerait un processus détaché
Defaults use_pty

# Obligatoire si log_input ou log_output est activé
Defaults log_input, log_output

# Répertoire personnalisé pour les logs I/O
Defaults iolog_dir="/var/log/sudo-io/%{seq}"

4. Logging et auditing

# Fichier de log personnalisé (en addition de syslog)
Defaults logfile="/var/log/sudo.log"
Defaults log_host, log_year  # Ajouter hostname et année

# Afficher toujours les lectures (même si autorisé)
Defaults lecture="always"

# Message personnalisé en cas d'erreur
Defaults badpass_message="Authentification échouée. Incident signalé."

Configuration Complète de Durcissement

Voici un fichier /etc/sudoers complet et sécurisé pour une infrastructure durcie :

#
# /etc/sudoers - Hardened Configuration
# Always edit with: visudo
#

# Default options - HARDENED
Defaults use_pty
Defaults requiretty
Defaults env_reset
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults logfile="/var/log/sudo.log"
Defaults log_host, log_year
Defaults log_input, log_output
Defaults iolog_dir="/var/log/sudo-io/%{seq}"
Defaults passwd_tries=3
Defaults pwfeedback
Defaults lecture="always"

# Timestamp management
Defaults timestamp_timeout=5
Defaults:root timestamp_timeout=0

# User specifications
root ALL=(ALL:ALL) ALL

# Aliases
User_Alias SYSADMINS = alice, bob
User_Alias DBADMINS = dba_prod, dba_staging
Host_Alias PROD_SERVERS = prod01, prod02, prod03
Host_Alias TEST_SERVERS = test01, test02

Cmnd_Alias PKG_UPDATE = /usr/bin/apt update, /usr/bin/apt upgrade, \
                        /usr/bin/apt autoremove, /usr/bin/apt autoclean
Cmnd_Alias SVC_MGMT = /usr/bin/systemctl restart, /usr/bin/systemctl start, \
                      /usr/bin/systemctl stop, /usr/bin/systemctl reload
Cmnd_Alias USER_MGMT = /usr/sbin/useradd, /usr/sbin/userdel, /usr/sbin/usermod
Cmnd_Alias READLOGS = /usr/bin/journalctl, /usr/bin/tail -f /var/log/*

# Permissions granulaires
SYSADMINS PROD_SERVERS=(ALL:ALL) PKG_UPDATE, SVC_MGMT
SYSADMINS TEST_SERVERS=(ALL:ALL) PKG_UPDATE, SVC_MGMT, USER_MGMT
DBADMINS PROD_SERVERS=(mysql:mysql) /usr/bin/mysql -u root
SYSADMINS ALL=(ALL) READLOGS

# Auditing group
%sudo ALL=(ALL:ALL) ALL

# Include custom configurations from sudoers.d
#includedir /etc/sudoers.d

Prévention des Exploitations via GTFOBins

GTFOBins est une base de données listant les binaires Unix pouvant être détournés pour escalader les privilèges. C'est le principal vecteur d'attaque post-compromission.

Scénario d'attaque courant

Si un utilisateur dispose de :

developer ALL=(ALL) NOPASSWD: /usr/bin/vim

L'attaquant peut alors :

sudo vim /etc/shadow
:!/bin/bash    # Obtient un shell root depuis vim

Autres binaires exploitables courants :

  • awk, sed, nano, less, more, rsync, nmap, find, chmod, chown

Stratégies de prévention

1. Lister les binaires dangereux

grep -i "sudo.*vim\|sudo.*nano\|sudo.*awk" /etc/sudoers /etc/sudoers.d/*

2. Auditer les binaires SUID

find / -perm -4000 2>/dev/null | while read binary; do
  echo "=== $binary ==="
  sudo -l -U user | grep "$binary"
done

3. Bonnes pratiques à appliquer

# ❌ À ÉVITER
user ALL=(ALL) NOPASSWD: /usr/bin/vim

# ✅ À FAIRE
# Spécifier le fichier exact si possible
user ALL=(ALL) /usr/bin/vi /etc/hosts

# Ou utiliser un script wrapper à la place d'un éditeur interactif
user ALL=(ALL) /usr/local/bin/edit-hosts.sh

# Pour des outils comme awk, les restreindre au maximum
developer ALL=(ALL) /usr/bin/awk 'NR==1,NR==10 {print}' /var/log/app.log

Audit et Monitoring : Traçabilité Complète

L'audit des actions sudo est critique pour détecter les abus ou les tentatives de compromission.

Vérifier que le logging est actif

# Vérifier la syntaxe et les settings
sudo -l

# Consulter les logs syslog
tail -f /var/log/auth.log  # Debian/Ubuntu
tail -f /var/log/secure    # RHEL/Fedora

# Rechercher les tentatives échouées
grep "sudo:" /var/log/auth.log | grep "INVALID"
grep "sudo:" /var/log/auth.log | grep "denied"

Configurer un logging centralisé

Pour les infrastructures distribuées, envoyer les logs vers un SIEM :

# Dans /etc/sudo-io/config
log_servers = siem.example.com:514
log_protocol = udp

Analyse avancée

# Tous les appels sudo réussis
sudo grep "sudo: .* TTY=" /var/log/auth.log | awk '{print $6, $7, $(NF-1), $NF}'

# Identificat un utilisateur suspect
sudo grep "^sudo: username" /var/log/auth.log

# Commandes échouées
sudo grep "sudo:.*COMMAND=" /var/log/auth.log | grep -i "denied\|invalid"

# Tentatives sans mot de passe (NOPASSWD)
sudo grep "sudo.*NOPASSWD" /var/log/sudoers /var/log/auth.log 2>/dev/null

Gestion Multi-Distributions et Cohérence

Avec une infrastructure hétérogène (Debian, Ubuntu, RHEL, CentOS), maintenir la cohérence requiert un effort. Voici comment :

1. Utiliser Ansible ou Terraform pour standardiser

# Synchroniser les sudoers via Ansible
ansible all -m copy -a "src=sudoers dest=/etc/sudoers owner=root group=root mode=0440" \
  --become --become-method=sudo

2. Script de validation multi-distro

#!/bin/bash
# validate_sudoers.sh

DISTROS=("debian" "ubuntu" "rhel" "fedora")
SUDO_FILE="/etc/sudoers"

for distro in "${DISTROS[@]}"; do
  echo "Validating sudoers for $distro..."
  
  # Utiliser visudo pour valider syntaxe
  sudo visudo -c -f "$SUDO_FILE" 2>/dev/null || {
    echo "❌ Erreur de syntaxe dans $SUDO_FILE"
    exit 1
  }
  
  # Vérifier les groupes existants
  if grep -q "%wheel" "$SUDO_FILE" && ! getent group wheel > /dev/null; then
    echo "⚠️  Groupe 'wheel' référencé mais n'existe pas"
  fi
done

echo "✅ Validation réussie"

3. Checklist multi-distros

Aspect Debian/Ubuntu RHEL/Fedora Validation
Groupe sudoers sudo wheel getent group sudo / getent group wheel
Fichier default /etc/sudoers /etc/sudoers visudo -c
Logs syslog /var/log/auth.log /var/log/secure tail -f
Package manager apt dnf Inclure dans aliases
Service manager systemctl systemctl Identique

Vulnérabilités Récentes et Correctifs

CVE-2025-32463 : Escalade Locale

Affectée : sudo < 1.9.17p1

Impact : Un utilisateur non-privilégié peut utiliser des défauts de parsing des alias hôtes pour escalader les privilèges.

Correction:

# Vérifier la version
sudo -V | grep "Sudo version"

# Mettre à jour
apt-get install --only-upgrade sudo
dnf update sudo

# Vérifier après mise à jour
sudo -V | grep "Sudo version"

Mitigations temporaires :

  • Auditer tous les Host_Alias dans /etc/sudoers
  • Éviter les wildcards dans les alias d'hôtes
  • Revoir les configurations LDAP pour les règles sudo

Bonnes pratiques contre les vulnérabilités futures

  1. Maintenir sudo à jour (cycle mensuel minimum)
  2. Monitoring du CVE : S'abonner aux alertes CISA/NVD
  3. Testing en staging : Tester tous les changements sudo avant production
  4. Audit régulier : Réviser /etc/sudoers et /etc/sudoers.d/* tous les trimestres

Conclusion et Checklist de Sécurisation

SUDO est puissant mais demande une rigueur absolue. Chaque configuration mal pensée peut ouvrir une porte aux attaquants.

Checklist de mise en conformité

☐ CONFIGURATION
  ☐ Éditer /etc/sudoers UNIQUEMENT avec visudo
  ☐ Vérifier syntaxe : sudo visudo -c
  ☐ Définir secure_path avec chemin absolu
  ☐ Activer use_pty et requiretty par défaut
  ☐ Timeout ≤ 5 minutes pour utilisateurs normaux
  ☐ Timeout = 0 pour utilisateurs sensibles

☐ PERMISSIONS
  ☐ Principle of Least Privilege : une seule commande par règle si possible
  ☐ Audit GTFOBins : refuser vim, nano, awk avec NOPASSWD
  ☐ Limiter les User_Alias et Cmnd_Alias
  ☐ Utiliser /etc/sudoers.d/ pour modularité

☐ AUDIT & LOGGING
  ☐ Activer log_input et log_output
  ☐ Configurer logfile="/var/log/sudo.log"
  ☐ Surveiller /var/log/auth.log pour tentatives échouées
  ☐ Centraliser les logs sur SIEM si infrastructure distribuée

☐ MAINTENANCE
  ☐ Revoir sudoers tous les 90 jours
  ☐ Supprimer les utilisateurs inactifs
  ☐ Tester les migrations de distros en staging
  ☐ Maintenir sudo à jour (cycle mensuel)
  ☐ Documenter chaque règle avec commentaire

☐ DÉTECTION D'INCIDENTS
  ☐ Alertes sur commandes sensibles (reboot, userdel, chmod)
  ☐ Alertes sur modifications de /etc/sudoers
  ☐ Alertes sur sudo sans mot de passe (NOPASSWD)
  ☐ Alertes sur tentatives répétées échouées

Ressources officielles

  • Man pages : man sudoers, man visudo, man sudo
  • ANSSI : Recommandations de sécurité relatives à un système GNU/Linux
  • GTFOBins : https://gtfobins.github.io
  • NVD/CISA : Surveillance des CVE sudo