20 - Securiser un serveur Linux
Ce que tu vas apprendre
- Désactiver la connexion root par SSH et forcer les clés SSH
- Configurer un pare-feu avec ufw pour exposer le minimum de ports
- Installer et configurer fail2ban contre le brute force
- Activer les mises à jour de sécurité automatiques
- Auditer un serveur avec rkhunter et lynis
- Appliquer le principe du moindre privilege
Prerequisites
Savoir gerer les utilisateurs et sudo, comprendre SSH et les logs.
Quand j'ai mis mon premier serveur en ligne, j'ai regarde les logs SSH au bout de 24 heures. Des centaines de tentatives de connexion en root avec des mots de passe bidons. Des bots du monde entier testaient des combinaisons sans relache. Mon serveur avait un mot de passe solide, mais ca m'a quand meme fait froid dans le dos. Ce jour-la, j'ai appris qu'un serveur expose sur Internet se fait attaquer immédiatement. Pas dans une semaine. Immediatement.
Désactiver la connexion root par SSH
C'est la première chose a faire sur tout serveur :
bash# Editer la configuration SSH
sudo nano /etc/ssh/sshd_config
# Changer ou ajouter ces lignes :
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
# Redemarrer le service SSH
sudo systemctl restart sshd
PermitRootLogin no interdit la connexion en root. PasswordAuthentication no force l'utilisation de clés SSH. Plus de mots de passe qui transitent sur le réseau, plus de brute force possible.
Avant de désactiver les mots de passe, assure-toi que ta clé SSH fonctionne. Sinon tu te retrouves enferme dehors. Teste dans une deuxieme session SSH avant de fermer la première.
bash# Verifier que ta cle est bien dans le serveur
cat ~/.ssh/authorized_keys
# Tester la connexion depuis un autre terminal
ssh -i ~/.ssh/ma_cle deploy@mon-serveur
Limiter les ports avec ufw
Chaque port ouvert est une surface d'attaque. Ouvre uniquement ce qui est nécessaire :
bash# Installer ufw (Uncomplicated Firewall)
sudo apt install ufw
# Politique par defaut : tout bloquer en entree
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Ouvrir SSH (fais-le AVANT d'activer ufw)
sudo ufw allow 22/tcp
# Ouvrir HTTP et HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Activer le pare-feu
sudo ufw enable
# Verifier les regles
sudo ufw status verbose
# Supprimer une regle
sudo ufw delete allow 80/tcp
# Autoriser une IP specifique
sudo ufw allow from 192.168.1.100 to any port 5432
Sur paltemps.fr, j'ouvre trois ports : 22, 80 et 443. Le serveur de base de donnees écoûte uniquement sur localhost. Si tu dois exposer un port pour un service interne, limite l'acces a des IPs spécifiques.
fail2ban : bloquer les brute force
fail2ban surveille les logs et bloque les IPs qui echouent trop de fois :
bash# Installer
sudo apt install fail2ban
# Creer une configuration locale (ne pas modifier jail.conf)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Configuration dans /etc/fail2ban/jail.local :
ini[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 24h
Avec cette configuration, 3 échecs SSH en 10 minutes = ban de 24 heures.
bash# Demarrer fail2ban
sudo systemctl enable --now fail2ban
# Voir le statut
sudo fail2ban-client status
# Voir les IPs bannies pour SSH
sudo fail2ban-client status sshd
# Debannir une IP
sudo fail2ban-client set sshd unbanip 1.2.3.4
Tu peux ajouter des jails pour d'autres services :
ini[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
Mises à jour automatiques de sécurité
On a vu unattended-upgrades dans l'article sur les paquets. Voici le minimum a configurer :
bashsudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
Verifie que les mises à jour de sécurité fonctionnent :
bash# Simuler une mise a jour
sudo unattended-upgrades --dry-run
# Voir les logs
cat /var/log/unattended-upgrades/unattended-upgrades.log
Ne pas appliquer les correctifs de sécurité, c'est laisser la porte ouverte. La majorite des compromissions de serveurs exploitent des vulnérabilités connues et corrigees depuis des mois.
rkhunter : détecter les rootkits
rkhunter scanne le système a la recherche de rootkits et de fichiers suspects :
bash# Installer
sudo apt install rkhunter
# Mettre a jour la base de donnees
sudo rkhunter --update
# Sauvegarder les proprietes actuelles des fichiers
sudo rkhunter --propupd
# Scanner le systeme
sudo rkhunter --check
# Scanner sans interaction
sudo rkhunter --check --skip-keypress
rkhunter généré des faux positifs. La première fois que tu le lances, tu auras probablement des warnings. Verifie chacun manuellement, et une fois que tu sais que le système est sain, mets à jour la base de référencé avec --propupd.
lynis : audit de sécurité complet
lynis est un outil d'audit qui analyse la configuration du système et donne des recommandations :
bash# Installer
sudo apt install lynis
# Lancer un audit complet
sudo lynis audit system
lynis vérifié des dizaines de points : configuration SSH, permissions des fichiers, services inutiles, configuration du kernel, etc. A la fin, il donne un score et une liste de suggestions.
bash# Voir seulement les warnings
sudo lynis audit system | grep -A 2 "Warning"
# Voir les suggestions
sudo lynis audit system --quick 2>/dev/null | grep "Suggestion"
Je lance lynis sur chaque nouveau serveur avant de le mettre en production. Ca prend cinq minutes et ca attrape souvent des oublis.
Le principe du moindre privilege
Au-dela des outils, la sécurité est un état d'esprit :
bash# Chaque service a son propre utilisateur
sudo useradd -r -s /usr/sbin/nologin mon-app
sudo chown -R mon-app:mon-app /opt/mon-app
# Le service tourne sous cet utilisateur, pas root
# Dans le fichier systemd :
# User=mon-app
# Group=mon-app
# Les fichiers sensibles sont lisibles uniquement par leur proprietaire
chmod 600 /opt/mon-app/.env
chmod 700 /opt/mon-app/scripts
# sudo est limite aux commandes necessaires
# /etc/sudoers.d/deploy
# deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart mon-app
Les regles que j'applique systématiquement :
- Pas de connexion root par SSH
- Pas de mot de passe, uniquement des clés SSH
- Pare-feu : tout ferme par défaut, ouvrir seulement le nécessaire
- Chaque service a son propre utilisateur non-root
- Les mises à jour de sécurité sont automatiques
- Les fichiers contenant des secrets ont des permissions restrictives
Résumé
- Desactive root SSH et les mots de passe immédiatement
ufwpour n'ouvrir que les ports nécessaires (22, 80, 443)fail2banpour bloquer les tentatives de brute forceunattended-upgradespour les correctifs de sécurité automatiquesrkhunterpour détecter les rootkits,lynispour auditer la configuration- Chaque service tourne sous son propre utilisateur avec le minimum de droits
Article précédent : Les conteneurs sans Docker Article suivant : Performance et diagnostic