durcit le serveur : pare-feu nftables, SSH par clé, fail2ban, chrony, mises à jour de sécurité

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-10-07 10:32:09 +02:00
parent b7e866f868
commit f5a5e8d8a9
13 changed files with 377 additions and 0 deletions

View file

@ -0,0 +1,3 @@
// Géré par Ansible (rôle durcissement) — ne pas modifier à la main.
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

View file

@ -0,0 +1,4 @@
// Géré par Ansible (rôle durcissement) — ne pas modifier à la main.
// Un redémarrage est une opération à risque (règle 3 du prompt de déploiement) :
// il doit toujours être décidé et déclenché par Adam, jamais automatiquement.
Unattended-Upgrade::Automatic-Reboot "false";

View file

@ -0,0 +1,15 @@
#!/bin/bash
# Géré par Ansible (rôle durcissement) — filet de sécurité anti-coupure SSH.
#
# Déclenché par un timer systemd transient ({{ durcissement_delai_filet_secondes }} s)
# programmé juste avant de modifier le pare-feu ou SSH. Si la vérification depuis
# le Mac échoue, ce script remet le serveur dans l'état d'avant durcissement
# (pare-feu complètement ouvert, pas de restriction SSH). Si tout va bien, le
# timer est annulé avant de se déclencher et ce script ne s'exécute jamais.
set -e
nft flush ruleset
rm -f /etc/ssh/sshd_config.d/99-durcissement.conf
systemctl reload ssh || systemctl restart ssh
logger -t durcissement-rollback "Rollback automatique déclenché : pare-feu et SSH remis à l'état d'avant durcissement."

View file

@ -0,0 +1,18 @@
# Géré par Ansible (rôle durcissement) — ne pas modifier à la main.
[DEFAULT]
bantime = 1h
findtime = 10m
# 10, pas 5 : nos propres vérifications de durcissement (tentative mot de passe
# refusée, tentative root refusée) comptent comme des échecs. À 5, on s'est
# banni nous-mêmes dès le 2e ou 3e passage du playbook en quelques minutes
# (voir docs/postmortems/2026-10-07-fail2ban-auto-ban.md). 10 reste largement
# suffisant contre un bruteforce réel.
maxretry = 10
backend = systemd
# Le serveur n'a pas iptables installé (seulement nftables) : il faut le dire
# explicitement à fail2ban, sinon son action par défaut échoue.
banaction = nftables-multiport
banaction_allports = nftables-allports
[sshd]
enabled = true

View file

@ -0,0 +1,29 @@
#!/usr/sbin/nft -f
# Géré par Ansible (rôle durcissement) — ne pas modifier à la main.
# Politique : tout est refusé en entrée sauf loopback, trafic déjà établi,
# ICMP, et les ports {{ durcissement_ports_ouverts | join(', ') }}.
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
ct state invalid drop
ip protocol icmp accept
meta l4proto ipv6-icmp accept
tcp dport { {{ durcissement_ports_ouverts | join(', ') }} } accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}

View file

@ -0,0 +1,8 @@
# Géré par Ansible (rôle durcissement) — ne pas modifier à la main.
# Lu en premier (Include est la première ligne de sshd_config), donc ces valeurs
# l'emportent sur les réglages par défaut du fichier principal.
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
X11Forwarding no