infra / linux-bash
Sécurité et hardening (sudo, SELinux/AppArmor)
Explication
Chaque utilisateur ou processus ne devrait avoir accès qu'au strict nécessaire pour faire son travail, rien de plus : c'est le principe du moindre privilège, qui gouverne toute la sécurité système sur un serveur exposé.
Ce que vous allez apprendre
- Configurer
sudopour n'autoriser qu'une commande précise plutôt qu'un accès root total - Installer
fail2banpour bannir automatiquement les IP après trop d'échecs d'authentification - Comprendre ce qu'apporte un confinement de processus (SELinux, AppArmor) par rapport à
sudoseul - Distinguer le fonctionnement d'AppArmor (par chemin) et de SELinux (par contexte)
- Éviter le réflexe dangereux de désactiver une protection au lieu de corriger sa configuration
Dans quel contexte ?
Un serveur web fraîchement provisionné et exposé sur Internet reçoit, dès les premières heures, des centaines de tentatives de connexion SSH automatisées avec des mots de passe devinés au hasard. Sans protection, ces attaques finiront par trouver une faille ou saturer les logs d'authentification. Un administrateur système doit mettre en place plusieurs couches de défense qui se complètent : sudo restreint, fail2ban contre le brute-force, et un confinement par profil pour limiter les dégâts si un service comme nginx est un jour compromis.
Une fois ce principe posé, il faut se défendre contre les attaques automatisées
fail2ban surveille les logs d'authentification, détecte ces échecs répétés depuis une même IP, et la bannit automatiquement pendant un temps donné.
Bonne pratique
Configure sudo pour n'autoriser qu'une commande précise plutôt qu'un accès root total : %devs ALL=(root) NOPASSWD: /usr/bin/systemctl restart mon-app permet à l'équipe de redémarrer UN service précis sans jamais avoir besoin du mot de passe root complet.
Il reste un scénario que sudo et fail2ban ne couvrent pas
Même avec ces protections, un logiciel légitime comme nginx peut être compromis via une faille. La question devient alors : que peut faire un attaquant une fois entré dans ce programme précis ?
Voici comment SELinux et AppArmor répondent à cette question
Ces deux systèmes de confinement définissent un profil strict pour chaque programme : quels fichiers il a le droit de lire, quels ports il peut ouvrir. Si nginx est piraté, l'attaquant reste enfermé dans ce périmètre limité, même s'il obtient un contrôle total du processus.
| Système | Distribution | Fonctionne par | Mode test |
|---|---|---|---|
| AppArmor | Debian, Ubuntu | Chemin de fichier | complain (journalise sans bloquer) |
| SELinux | RHEL, Fedora, CentOS | Contexte de sécurité | Permissive |
Piège dangereux
Désactiver SELinux ou AppArmor pour "faire disparaître" une erreur (setenforce 0) supprime une couche de défense entière au lieu de corriger le vrai problème — presque toujours une règle de profil trop stricte à ajuster (ausearch -m avc) plutôt qu'à contourner en désactivant toute la protection.
Maintenant que la machine elle-même est durcie, la prochaine leçon s'attaque au trafic réseau qui y entre et en sort, avec le pare-feu.
Commandes & code
Sécurité et hardening
# --- sudo : principe du moindre privilège ---
sudo visudo
# Autoriser un groupe précis à agir sur un service précis, sans mot de passe :
# %devs ALL=(root) NOPASSWD: /usr/bin/systemctl restart mon-app
# Interdire explicitement des commandes dangereuses :
# ned ALL=(ALL) ALL, !/usr/bin/passwd root, !/bin/su
sudo -l # ce que l'utilisateur courant peut faire
journalctl _COMM=sudo # audit de toutes les commandes sudo exécutées
# --- Durcissement SSH (rappel, complète la leçon SSH avancé) ---
# /etc/ssh/sshd_config
# PermitRootLogin no
# PasswordAuthentication no
# MaxAuthTries 3
# ClientAliveInterval 300
# ClientAliveCountMax 2
# --- fail2ban : bannit automatiquement les IP après trop d'échecs ---
sudo apt install fail2ban
sudo systemctl enable --now fail2ban
fail2ban-client status sshd # voir les IP actuellement bannies
fail2ban-client set sshd unbanip 203.0.113.7 # débannir manuellement
# --- AppArmor (Debian/Ubuntu) : confinement par profil ---
sudo aa-status # profils chargés, en mode enforce ou complain
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx # applique strictement le profil
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx # mode "log only", ne bloque pas
# --- SELinux (RHEL/CentOS/Fedora) : équivalent plus strict ---
getenforce # Enforcing / Permissive / Disabled
sudo setenforce 1 # active enforcing (temporaire, jusqu'au reboot)
sestatus # état détaillé
ls -lZ /var/www/html # affiche le contexte SELinux d'un fichier
sudo semanage port -a -t http_port_t -p tcp 8443 # autorise un port custom pour un service
sudo restorecon -Rv /var/www/html # remet les contextes SELinux par défaut
ausearch -m avc -ts recent # cherche les refus SELinux récents
# --- Audit et surveillance des accès ---
last # historique des connexions
lastb # tentatives de connexion échouées
who # utilisateurs actuellement connectés
w # idem + ce qu'ils font
# --- Checklist de durcissement d'un serveur fraîchement provisionné ---
sudo apt update && sudo apt full-upgrade -y
sudo timedatectl set-ntp true # horloge synchronisée (essentiel pour les logs/TLS)
sudo ufw default deny incoming # voir la leçon pare-feu pour aller plus loin
sudo passwd -l root # verrouille le compte root local
# Créer un utilisateur nominatif avec sudo plutôt que de travailler en rootRésumé
sudodoit rester ciblé (visudo, commandes précises) plutôt qu'un accès root total permanent.fail2banbannit automatiquement les IP après trop d'échecs d'authentification (SSH, HTTP, etc).- SELinux (RHEL) et AppArmor (Debian/Ubuntu) confinent un processus même s'il est compromis.
Exercices pratiques
Mission : durcir un serveur web fraîchement exposé
Objectif : Restreindre sudo, réagir au brute-force SSH et raisonner sur les limites du confinement par profil.
Contexte
Un serveur web tout juste provisionné reçoit déjà des centaines de tentatives de connexion SSH automatisées. Tu dois mettre en place plusieurs couches de défense complémentaires sans jamais désactiver une protection existante par facilité.