| name | linux-security-hardener |
| description | Durcissement sécurité Linux — SSH, fail2ban, SELinux, audit, gestion des utilisateurs et mises à jour. Se déclenche avec "sécurité Linux", "hardening Linux", "SSH sécurisé", "fail2ban", "SELinux", "audit Linux". Also triggers on "harden a Linux server", "SSH hardening", "fail2ban and SELinux". |
Linux Security Hardener
Étape 1 — Audit initial (baseline)
Avant toute modification, mesurer l'état de sécurité actuel.
lynis audit system --quick 2>/dev/null | grep -E "Hardening index|Warning|Suggestion"
ss -tulnp
awk -F: '$7 ~ /bash|sh|zsh/ && $3 >= 1000' /etc/passwd
systemctl list-units --type=service --state=running
find / -xdev \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null | sort
Critère de décision : Lynis score < 65 = hardening prioritaire. Score 65-80 = corrections ciblées. > 80 = maintenance continue.
Étape 2 — Durcissement SSH
Toujours garder une session SSH ouverte avant de modifier sshd_config.
Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
AllowUsers deployer ops-user
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
Banner /etc/ssh/banner.txt
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256,diffie-hellman-group16-sha512
sshd -t && systemctl reload sshd
Étape 3 — fail2ban
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 4
backend = systemd
[sshd]
enabled = true
port = 2222
logpath = %(sshd_log)s
[nginx-http-auth]
enabled = true
fail2ban-client status sshd
fail2ban-client banned
fail2ban-client set sshd unbanip 1.2.3.4
Étape 4 — Gestion utilisateurs et privilèges
usermod -L -e 1 ancien-user
minlen = 14
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
maxrepeat = 3
chage -M 90 -W 14 -I 30 username
chage -l username
deployer ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx
Étape 5 — SELinux / AppArmor
SELinux (RHEL/CentOS/Fedora)
sestatus
setenforce 1
ausearch -m AVC -ts recent | audit2why
ausearch -m AVC -ts recent | audit2allow -M mypolicy
semodule -i mypolicy.pp
AppArmor (Debian/Ubuntu)
aa-status
aa-enforce /etc/apparmor.d/*
aa-logprof
Critère : Toujours enforcing en prod. complain uniquement pendant le test d'un nouveau service.
Étape 6 — auditd (traçabilité)
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/ssh/sshd_config -p wa -k sshd_config
-a always,exit -F arch=b64 -S execve -F euid=0 -k root_commands
-a always,exit -F arch=b64 -S open,openat -F exit=-EACCES -k access_denied
augenrules --load
auditctl -l
ausearch -k sudoers -ts today
aureport --summary
Étape 7 — Firewall (nftables / firewalld)
nft add table inet filter
nft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'
nft add rule inet filter input iif lo accept
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input tcp dport 2222 ct state new limit rate 5/minute accept
nft list ruleset > /etc/nftables.conf
Étape 8 — Mises à jour automatiques
apt install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades
dnf install dnf-automatic
systemctl enable --now dnf-automatic-install.timer
Garde-fous et anti-patterns
| Piège | Conséquence | Solution |
|---|
setenforce 0 pour débloquer un service | Désactive toute isolation SELinux | Utiliser audit2allow pour créer une politique ciblée |
PermitRootLogin yes "temporairement" | Oubli fréquent, vecteur d'attaque majeur | Créer un compte dédié avec sudo limité |
Modifier sshd_config sans session ouverte | Exclusion complète du serveur | Garder 2 sessions actives, valider avec sshd -t |
NOPASSWD: ALL dans sudoers | Escalade de privilèges triviale | Lister les commandes exactes autorisées |
Désactiver auditd pour les perfs | Aucune traçabilité forensique | Tuner backlog_limit dans /etc/audit/auditd.conf |
fail2ban sans backend = systemd | Faux négatifs si journald utilisé | Toujours préciser le backend |
| Oublier les mises à jour du noyau | Vulnérabilités persistantes | needrestart -r a post-upgrade, planifier reboot maintenance |
Checklist finale
lynis audit system --quick | grep "Hardening index"
sshd -T | grep -E "permitrootlogin|passwordauthentication|port"
fail2ban-client status
sestatus || aa-status
auditctl -l | wc -l
ss -tulnp | grep -v "127.0.0.1\|::1"
awk -F: '$2 == "" {print $1}' /etc/shadow