Un serveur Linux en production exposé à Internet sans durcissement, c’est une porte ouverte. Pas une question de si il sera attaqué, mais de quand. Les scans automatisés frappent chaque IP publique en quelques minutes après sa mise en ligne. En 2026, avec la montée en puissance des attaques automatisées par IA et le renforcement des exigences réglementaires suisses (nLPD), sécuriser un serveur Linux en production n’est plus optionnel — c’est un prérequis absolu.
Cette checklist couvre chaque couche de défense, du SSH au kernel, avec des commandes concrètes et testées. Pas de raccourcis en sécurité.
1. Durcissement SSH — la première ligne de défense
#SSH est le vecteur d’attaque numéro un sur un serveur Linux. Les bots tentent des milliers de combinaisons par heure. Voici comment verrouiller l’accès.
Désactiver l’authentification par mot de passe
#L’authentification par clé publique est non négociable en production :
1
2
3
4
5
| # Générer une paire de clés Ed25519 (côté client)
ssh-keygen -t ed25519 -a 100 -C "admin@devopslab.ch"
# Copier la clé publique sur le serveur
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
|
Configurer sshd_config
# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo tee /etc/ssh/sshd_config.d/hardening.conf << 'EOF'
# Authentification
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
KbdInteractiveAuthentication no
PermitEmptyPasswords no
MaxAuthTries 3
MaxSessions 3
# Protocole
Protocol 2
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
PermitTunnel no
# Utilisateurs autorisés (adapter à votre setup)
AllowUsers deploy admin
# Timeouts
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 30
# Algorithmes modernes uniquement
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256
# Logging
LogLevel VERBOSE
EOF
|
Changer le port SSH (optionnel mais efficace)
#Ça n’arrêtera pas un attaquant déterminé, mais ça élimine 99 % du bruit :
1
2
3
4
5
| # Ajouter dans /etc/ssh/sshd_config.d/hardening.conf
echo "Port 2222" | sudo tee -a /etc/ssh/sshd_config.d/hardening.conf
# Valider la configuration avant de redémarrer
sudo sshd -t && sudo systemctl restart sshd
|
Important : testez toujours votre accès SSH dans une seconde session avant de fermer la première. Se verrouiller dehors n’est pas un plan de reprise d’activité.
2. Firewall — ufw et nftables
#Un firewall correctement configuré est la base du périmètre réseau. Sur les distributions modernes, nftables remplace iptables. Pour les cas simples, ufw reste un excellent front-end.
Configuration ufw (Ubuntu/Debian)
# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # Politique par défaut : tout bloquer en entrée
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Autoriser SSH (adapter le port si modifié)
sudo ufw allow 2222/tcp comment 'SSH'
# Autoriser HTTP/HTTPS si serveur web
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
# Activer le firewall
sudo ufw enable
sudo ufw status verbose
|
Configuration nftables (avancée)
#Pour un contrôle granulaire, nftables offre plus de flexibilité :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| sudo tee /etc/nftables.conf << 'EOF'
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Loopback
iif "lo" accept
# Connexions établies
ct state established,related accept
# Drop invalid
ct state invalid drop
# ICMP rate-limited
ip protocol icmp limit rate 5/second accept
ip6 nexthdr icmpv6 limit rate 5/second accept
# SSH rate-limited
tcp dport 2222 ct state new limit rate 5/minute accept
# HTTP/HTTPS
tcp dport { 80, 443 } accept
# Log les drops
log prefix "[nftables-drop] " flags all counter drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
EOF
sudo nft -f /etc/nftables.conf
sudo systemctl enable nftables
|
3. Fail2ban — bloquer les brute-force
#Fail2ban surveille les logs et bannit automatiquement les IP suspectes. Indispensable même avec une authentification par clé.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| sudo apt install fail2ban -y
sudo tee /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
banaction = nftables-multiport
banaction_allports = nftables-allports
ignoreip = 127.0.0.1/8 ::1
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
[sshd-aggressive]
enabled = true
port = 2222
filter = sshd[mode=aggressive]
logpath = /var/log/auth.log
maxretry = 1
bantime = 604800
findtime = 86400
EOF
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
|
Vérification et monitoring
#1
2
3
4
5
| # Voir les IP bannies
sudo fail2ban-client status sshd
# Débannir manuellement si nécessaire
sudo fail2ban-client set sshd unbanip 203.0.113.42
|
4. Mises à jour automatiques — pas de serveur obsolète
#Un serveur non patché est un serveur compromis en sursis. Les mises à jour de sécurité doivent s’appliquer automatiquement.
Ubuntu/Debian — unattended-upgrades
# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| sudo apt install unattended-upgrades apt-listchanges -y
sudo tee /etc/apt/apt.conf.d/50unattended-upgrades << 'EOF'
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
Unattended-Upgrade::Mail "ops@devopslab.ch";
Unattended-Upgrade::MailReport "on-change";
EOF
sudo tee /etc/apt/apt.conf.d/20auto-upgrades << 'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
EOF
# Tester
sudo unattended-upgrades --dry-run --debug
|
RHEL/AlmaLinux — dnf-automatic
#1
2
3
4
5
6
| sudo dnf install dnf-automatic -y
sudo sed -i 's/apply_updates = no/apply_updates = yes/' /etc/dnf/automatic.conf
sudo sed -i 's/upgrade_type = default/upgrade_type = security/' /etc/dnf/automatic.conf
sudo systemctl enable --now dnf-automatic-install.timer
|
5. AppArmor et SELinux — confinement des processus
#Le contrôle d’accès obligatoire (MAC) limite les dégâts en cas de compromission d’un service. Un processus compromis ne peut accéder qu’aux ressources explicitement autorisées.
AppArmor (Ubuntu/Debian)
# 1
2
3
4
5
6
7
8
9
10
11
| # Vérifier le statut
sudo aa-status
# Installer les profils supplémentaires
sudo apt install apparmor-profiles apparmor-profiles-extra -y
# Mettre un profil en mode enforce
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
# Lister les profils en mode complain (à passer en enforce après validation)
sudo aa-status | grep complain
|
SELinux (RHEL/AlmaLinux)
# 1
2
3
4
5
6
7
8
9
10
| # Vérifier le mode
getenforce
# Passer en mode enforcing
sudo setenforce 1
sudo sed -i 's/SELINUX=permissive/SELINUX=enforcing/' /etc/selinux/config
# Diagnostiquer les blocages
sudo ausearch -m AVC -ts recent
sudo sealert -a /var/log/audit/audit.log
|
Règle d’or : ne jamais désactiver AppArmor ou SELinux en production. Si un service est bloqué, corrigez le profil — ne supprimez pas la protection.
6. Audit logs — tout tracer, rien oublier
#L’audit système est essentiel pour la détection d’intrusion et la conformité réglementaire. Le framework auditd permet de tracer chaque action critique.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
| sudo apt install auditd audispd-plugins -y
sudo tee /etc/audit/rules.d/hardening.rules << 'EOF'
# Supprimer les règles existantes
-D
# Buffer
-b 8192
# Échec = panique (mode strict)
-f 1
# Surveillance des fichiers sensibles
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
-w /etc/ssh/sshd_config -p wa -k sshd_config
# Surveillance des commandes d'administration
-a always,exit -F arch=b64 -S execve -F euid=0 -k root_commands
# Modifications de date/heure
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time_change
# Montages de systèmes de fichiers
-a always,exit -F arch=b64 -S mount -k mounts
# Suppressions de fichiers
-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -k delete
# Chargement de modules kernel
-w /sbin/insmod -p x -k modules
-w /sbin/rmmod -p x -k modules
-w /sbin/modprobe -p x -k modules
# Rendre les règles immuables (nécessite un reboot pour modifier)
-e 2
EOF
sudo systemctl enable --now auditd
sudo augenrules --load
|
Centraliser les logs
#En production, les logs doivent être externalisés. Un attaquant qui compromet le serveur peut effacer les logs locaux :
1
2
3
| # Exemple avec rsyslog vers un serveur centralisé
echo '*.* @@logserver.devopslab.ch:514' | sudo tee -a /etc/rsyslog.d/50-remote.conf
sudo systemctl restart rsyslog
|
Pour une stack moderne, privilégiez Loki + Promtail ou un SIEM comme Wazuh.
7. Kernel hardening — sécuriser le noyau
#Le kernel est la surface d’attaque ultime. Ces paramètres sysctl réduisent drastiquement les vecteurs d’exploitation.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| sudo tee /etc/sysctl.d/99-hardening.conf << 'EOF'
# Désactiver le routage IP
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0
# Protection contre le spoofing
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Ignorer les redirections ICMP
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# Ignorer les requêtes ICMP broadcast
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Protection SYN flood
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 4096
# Désactiver les source routes
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
# Log des paquets martiens
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# Restriction dmesg
kernel.dmesg_restrict = 1
# Restriction ptrace
kernel.yama.ptrace_scope = 2
# ASLR maximum
kernel.randomize_va_space = 2
# Restriction accès kernel pointers
kernel.kptr_restrict = 2
# Désactiver SysRq (sauf sync + reboot)
kernel.sysrq = 4
# Protections BPF
kernel.unprivileged_bpf_disabled = 1
net.core.bpf_jit_harden = 2
# Désactiver les user namespaces non-privilégiés (si non nécessaire)
kernel.unprivileged_userns_clone = 0
EOF
sudo sysctl --system
|
Désactiver les modules kernel inutiles
# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| sudo tee /etc/modprobe.d/hardening.conf << 'EOF'
# Protocoles réseau rarement nécessaires
install dccp /bin/true
install sctp /bin/true
install rds /bin/true
install tipc /bin/true
# Systèmes de fichiers exotiques
install cramfs /bin/true
install freevxfs /bin/true
install jffs2 /bin/true
install hfs /bin/true
install hfsplus /bin/true
install squashfs /bin/true
install udf /bin/true
# USB storage (si non nécessaire)
install usb-storage /bin/true
EOF
|
8. DNS sécurisé — résolution de confiance
#Un DNS non sécurisé permet des attaques de type DNS spoofing ou exfiltration de données par tunnel DNS.
Configurer DNS-over-TLS avec systemd-resolved
# 1
2
3
4
5
6
7
8
9
10
11
| sudo tee /etc/systemd/resolved.conf.d/dns-tls.conf << 'EOF'
[Resolve]
DNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net
FallbackDNS=1.1.1.2#security.cloudflare-dns.com
DNSOverTLS=yes
DNSSEC=yes
Domains=~.
EOF
sudo systemctl restart systemd-resolved
sudo resolvectl status
|
Pourquoi Quad9 ? Serveurs en Suisse (Zurich), conformes RGPD, filtrage malware intégré. Choix logique pour un serveur hébergé sur territoire suisse.
Vérifier le fonctionnement
#1
2
3
| # Tester la résolution DNSSEC
resolvectl query sigok.verteiltesysteme.net
resolvectl query sigfail.verteiltesysteme.net # Doit échouer
|
9. TLS — chiffrement moderne obligatoire
#Chaque service exposé doit utiliser TLS 1.3 au minimum. TLS 1.0 et 1.1 sont morts depuis 2021 — TLS 1.2 reste toléré mais doit être configuré strictement.
Certificats Let’s Encrypt avec certbot
#1
2
3
4
5
6
7
8
| sudo apt install certbot -y
# Pour Nginx
sudo apt install python3-certbot-nginx -y
sudo certbot --nginx -d server.devopslab.ch --no-eff-email --agree-tos -m ops@devopslab.ch
# Renouvellement automatique
sudo systemctl enable --now certbot.timer
|
Configuration TLS durcie pour Nginx
# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| sudo tee /etc/nginx/conf.d/tls-hardening.conf << 'EOF'
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
# HSTS — attention, irréversible une fois déployé
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# Headers de sécurité
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
EOF
sudo nginx -t && sudo systemctl reload nginx
|
Vérifier la configuration TLS
#1
2
3
4
5
| # Test local rapide
openssl s_client -connect server.devopslab.ch:443 -tls1_3
# Test complet (externe)
# Utiliser https://www.ssllabs.com/ssltest/ — viser le grade A+
|
10. Mesures complémentaires
#Comptes utilisateurs et privilèges
# 1
2
3
4
5
6
7
8
9
10
11
12
13
| # Créer un utilisateur dédié aux opérations (jamais root directement)
sudo adduser --disabled-password deploy
sudo usermod -aG sudo deploy
# Restreindre sudo avec un fichier dédié
echo 'deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/journalctl' | \
sudo tee /etc/sudoers.d/deploy
sudo chmod 440 /etc/sudoers.d/deploy
sudo visudo -cf /etc/sudoers.d/deploy
# Verrouiller les comptes inutilisés
sudo passwd -l games
sudo usermod -s /usr/sbin/nologin games
|
Permissions fichiers critiques
#1
2
3
4
5
| sudo chmod 600 /etc/ssh/sshd_config
sudo chmod 600 /etc/shadow
sudo chmod 644 /etc/passwd
sudo chmod 700 /root
sudo chmod 600 /boot/grub/grub.cfg
|
Bannière d’avertissement légale
#1
2
3
4
5
6
7
8
9
| sudo tee /etc/issue.net << 'EOF'
*********************************************************************
AVERTISSEMENT : Accès réservé aux personnes autorisées.
Toute activité est journalisée et surveillée.
Tout accès non autorisé sera poursuivi conformément au droit suisse.
*********************************************************************
EOF
echo "Banner /etc/issue.net" | sudo tee -a /etc/ssh/sshd_config.d/hardening.conf
|
Scan de vulnérabilités régulier
#1
2
3
4
5
6
7
| # Installer Lynis pour l'audit de sécurité
sudo apt install lynis -y
sudo lynis audit system --quick
# Planifier un audit hebdomadaire
echo '0 2 * * 0 root /usr/sbin/lynis audit system --cronjob --quiet' | \
sudo tee /etc/cron.d/lynis-audit
|
11. Conformité LPD / RGPD — obligations suisses
#Depuis le 1er septembre 2023, la nouvelle Loi fédérale sur la Protection des Données (nLPD) impose des exigences strictes aux entreprises traitant des données personnelles en Suisse. Si vos serveurs traitent également des données de résidents de l’UE, le RGPD s’applique en parallèle.
Exigences techniques à implémenter
#Chiffrement des données au repos et en transit :
1
2
3
4
5
| # Vérifier que les partitions sensibles utilisent LUKS
sudo cryptsetup luksDump /dev/sda3
# Chiffrement des backups
gpg --symmetric --cipher-algo AES256 backup-2026-03-19.tar.gz
|
Journalisation conforme :
Les logs d’accès aux données personnelles doivent être conservés et protégés. auditd (section 6) couvre cette exigence — assurez-vous que les règles incluent les fichiers et bases de données contenant des données personnelles.
Droit à l’effacement :
Documentez la procédure technique de suppression des données. Assurez-vous que les backups et réplicas sont inclus dans le processus.
Checklist conformité serveur
#| Exigence | Solution technique | Section |
|---|
| Chiffrement en transit | TLS 1.3, SSH Ed25519 | §1, §9 |
| Chiffrement au repos | LUKS, GPG pour backups | §11 |
| Contrôle d’accès | SSH clés + sudo restreint | §1, §10 |
| Journalisation | auditd + centralisation | §6 |
| Intégrité des données | AIDE/Tripwire, checksums | §10 |
| Minimisation des données | Rétention logs configurée | §6 |
| Notification de violation | Monitoring + alerting | §6 |
| Localisation des données | Hébergement en Suisse (Infomaniak, Exoscale, etc.) | — |
Points spécifiques à la Suisse
#- Hébergement : privilégiez les datacenters suisses. Infomaniak, Exoscale (CloudStack, Zurich/Genève), ou Green.ch offrent des garanties de localisation des données.
- Transfert hors Suisse : si vous utilisez des services cloud étrangers (AWS, GCP), un contrat de sous-traitance conforme à l’art. 9 nLPD est obligatoire.
- PFPDT : le Préposé fédéral à la protection des données (PFPDT) peut exiger un audit. Vos logs et procédures doivent être prêts.
- Délai de notification : en cas de violation, notification « dans les meilleurs délais » au PFPDT (nLPD) et sous 72 heures à l’autorité de contrôle (RGPD).
12. Automatiser avec un script de vérification
#Pour ne rien oublier, un script de vérification rapide :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
| #!/bin/bash
# verify-hardening.sh — Vérification post-hardening
set -euo pipefail
echo "=== Vérification du durcissement serveur ==="
check() {
if eval "$2" &>/dev/null; then
echo "✅ $1"
else
echo "❌ $1"
fi
}
check "SSH: root login désactivé" \
"! grep -qE '^\s*PermitRootLogin\s+yes' /etc/ssh/sshd_config*"
check "SSH: password auth désactivé" \
"! grep -qE '^\s*PasswordAuthentication\s+yes' /etc/ssh/sshd_config*"
check "Firewall actif" \
"sudo ufw status | grep -q 'Status: active' || sudo nft list ruleset | grep -q 'filter'"
check "Fail2ban actif" \
"systemctl is-active fail2ban"
check "Unattended-upgrades actif" \
"systemctl is-active unattended-upgrades || systemctl is-active dnf-automatic-install.timer"
check "AppArmor/SELinux actif" \
"aa-status 2>/dev/null | grep -q 'profiles are in enforce' || getenforce 2>/dev/null | grep -q 'Enforcing'"
check "Auditd actif" \
"systemctl is-active auditd"
check "DNS-over-TLS actif" \
"resolvectl status | grep -q 'DNSOverTLS: yes'"
check "Kernel ASLR activé" \
"[ \$(sysctl -n kernel.randomize_va_space) -eq 2 ]"
check "SYN cookies activés" \
"[ \$(sysctl -n net.ipv4.tcp_syncookies) -eq 1 ]"
echo ""
echo "=== Vérification terminée ==="
|
Conclusion
#Sécuriser un serveur Linux en production est un processus continu, pas un one-shot. Cette checklist couvre les fondamentaux pour 2026, mais la sécurité ne s’arrête pas à la configuration initiale :
- Auditez régulièrement avec Lynis ou OpenSCAP
- Surveillez activement vos logs avec un SIEM
- Testez vos défenses avec des scans de vulnérabilité périodiques
- Documentez tout — pour la conformité LPD/RGPD et pour votre équipe
- Patchez sans délai — chaque CVE non corrigée est une dette de sécurité
En Suisse, la rigueur n’est pas un luxe. C’est un standard. Appliquez-le à vos serveurs.
Checklist testée sur Ubuntu 24.04 LTS et AlmaLinux 9. Adaptez les commandes à votre distribution. Pour toute question, contactez-nous.