📍 Article principal de la série : VPS hardening sécurité 2026 : guide pratique
Cet article fait partie de la série « Sécurité VPS Linux ». Pour la vue d’ensemble, lire d’abord le guide général.
Introduction
En 2024, la CVE-2024-6387 (« regreSSHion ») touchait toutes les versions d’OpenSSH 8.5p1 à 9.7p1, soit la quasi-totalité des serveurs Linux exposés sur Internet à ce moment-là. Le correctif est sorti en quelques heures côté upstream OpenBSD. Mais sur les VPS où personne ne mettait à jour automatiquement, la fenêtre d’exposition s’est étendue à des semaines, voire des mois pour les serveurs négligés. La même histoire se répète chaque année : Heartbleed (2014), Shellshock (2014), Dirty COW (2016), Spectre/Meltdown (2018), Log4Shell (2021), regreSSHion (2024). Entre la publication d’une CVE critique et son exploitation massive par des botnets, la fenêtre de tir se mesure désormais en heures, pas en jours.
L’unique parade fiable consiste à automatiser l’application des mises à jour de sécurité, particulièrement sur les paquets exposés (openssh, openssl, bash, glibc, kernel, nginx, postgres). Sur Debian et Ubuntu, l’outil officiel s’appelle unattended-upgrades ; sur Rocky/AlmaLinux, c’est dnf-automatic. Ce tutoriel détaille la configuration recommandée 2026 pour un VPS de production : application automatique des seuls patches de sécurité (jamais des mises à jour fonctionnelles qui pourraient casser un service), redémarrage planifié hors heures ouvrables, notifications par email, et règles d’exclusion pour les paquets critiques. La méthode minimise le risque d’incident lié à une mise à jour ratée tout en garantissant que les correctifs de sécurité s’appliquent dans les 24 heures suivant leur publication.
Prérequis
- VPS Debian 11/12 ou Ubuntu 22.04/24.04 LTS pour la partie
unattended-upgrades - VPS Rocky Linux 9 ou AlmaLinux 9 pour la partie
dnf-automatic - Accès sudo / root
- Un domaine email fonctionnel avec SMTP relay configuré (Postfix → Brevo, Mailgun, SES) si l’on veut les notifications — sinon notifications locales via journald uniquement
- Snapshot ou backup VPS récent — toujours, avant toute config qui touche aux mises à jour automatiques
- Niveau attendu : intermédiaire
- Temps estimé : 20 à 30 minutes
Étape 1 — Installer unattended-upgrades sur Debian/Ubuntu
Sur Debian 12 et Ubuntu 22.04+, le paquet unattended-upgrades est généralement installé par défaut, mais désactivé ou configuré en mode « passif » (calcule mais n’applique pas). Il faut explicitement l’activer et configurer le périmètre des mises à jour appliquées. La première étape vérifie l’état actuel et installe ou met à jour le paquet si besoin.
# Vérifier la présence du paquet
sudo apt list --installed 2>/dev/null | grep unattended-upgrades
# Installation si absent
sudo apt update
sudo apt install -y unattended-upgrades apt-listchanges
# apt-listchanges est optionnel mais utile : il logge les changelogs des paquets mis à jour
# Vérifier que le service systemd est actif
sudo systemctl status unattended-upgrades
# Si désactivé, l'activer et le démarrer
sudo systemctl enable --now unattended-upgrades
Le service unattended-upgrades.service est piloté par un timer systemd qui le réveille typiquement deux fois par jour. La version actuelle (4.0+ sur Debian 12, 2.10+ sur Ubuntu 24.04) inclut les corrections les plus importantes des années précédentes (gestion correcte des transitions de versions, support de l’arrêt/redémarrage automatique, notifications fiables). Si vous voyez un état « inactive (dead) » mais que le timer est actif, c’est normal : le service ne tourne que quand le timer le déclenche.
Étape 2 — Configurer les sources de mise à jour
Le fichier principal de configuration est /etc/apt/apt.conf.d/50unattended-upgrades. Il définit quelles « origines » de paquets (security, updates, backports) sont éligibles à l’application automatique. La règle critique : ne jamais activer les origines générales (${distro_id}:${distro_codename}) sur un serveur de production — ces mises à jour peuvent inclure des changements fonctionnels et casser un service. On limite strictement aux origines « security ».
# /etc/apt/apt.conf.d/50unattended-upgrades — configuration recommandée production
Unattended-Upgrade::Allowed-Origins {
// Debian
"${distro_id}:${distro_codename}-security";
"Debian-Security:${distro_codename}";
// Ubuntu
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
"${distro_id}:${distro_codename}-security";
// NE PAS activer ces lignes en production sauf cas particulier :
// "${distro_id}:${distro_codename}";
// "${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-backports";
};
// Liste noire : paquets qu'on NE met JAMAIS à jour automatiquement
// (typiquement les paquets de base de données, les versions verrouillées par l'application)
Unattended-Upgrade::Package-Blacklist {
"linux-image*"; // Décommentez SI vous gérez le kernel manuellement
"postgresql-*"; // Mises à jour majeures Postgres = downtime planifié manuel
"mariadb-server*"; // Idem
};
// Politique de redémarrage automatique
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
// Email de notification (optionnel mais recommandé)
Unattended-Upgrade::Mail "ops@votre-entreprise.com";
Unattended-Upgrade::MailReport "on-change";
// Suppression des paquets devenus inutiles
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
// Délai max d'arrêt d'un service pour permettre le redémarrage propre
Unattended-Upgrade::MinimalSteps "true";
Unattended-Upgrade::InstallOnShutdown "false";
Trois choix structurants à comprendre. Allowed-Origins restreint aux dépôts de sécurité — c’est ce qui garantit qu’aucune mise à jour fonctionnelle ne sera appliquée. Package-Blacklist exclut les paquets dont la mise à jour automatique est risquée : Postgres et MariaDB en sont des exemples classiques car une mise à jour majeure (10.11 → 11) peut nécessiter une migration du schéma. Automatic-Reboot-Time « 03:00 » programme les redémarrages à 3h du matin (heure serveur), ce qui correspond à 1h du matin GMT au Sénégal/Côte d’Ivoire — heure creuse acceptable pour l’écrasante majorité des activités.
Étape 3 — Activer le scheduler de mise à jour
Le fichier /etc/apt/apt.conf.d/20auto-upgrades active le mécanisme et définit la cadence. Sans ce fichier, unattended-upgrades est installé mais ne tourne jamais. Sur les distributions modernes, ce fichier est généré par dpkg-reconfigure unattended-upgrades ou peut être créé manuellement.
# /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1"; // Met à jour la liste des paquets quotidiennement
APT::Periodic::Unattended-Upgrade "1"; // Applique les mises à jour de sécurité quotidiennement
APT::Periodic::AutocleanInterval "7"; // Nettoie le cache APT chaque semaine
APT::Periodic::Verbose "1"; // Logs détaillés dans /var/log/unattended-upgrades/
# Ou via la commande interactive :
sudo dpkg-reconfigure unattended-upgrades
# Répondre "Yes" à la question d'activation
La granularité réelle du déclenchement est gérée par le timer systemd apt-daily.timer et apt-daily-upgrade.timer. Les valeurs par défaut planifient une exécution avec randomisation : entre 6h00 et 7h00 pour la mise à jour de la liste, entre 6h00 et 7h00 (avec jitter aléatoire ~30 min) pour l’application. Cette randomisation évite que tous les VPS Hetzner d’un même bloc IP frappent les mirroirs Debian au même instant — utile pour les administrateurs de mirroirs, sans impact pratique pour vous.
Étape 4 — Tester la configuration en dry-run
Avant de laisser le mécanisme tourner en autonomie, faire un test en mode « dry-run » qui simule l’opération sans rien appliquer. Cette validation est cruciale pour confirmer que le périmètre est bien limité aux paquets de sécurité et que les exclusions sont prises en compte.
# Dry-run en mode debug : montre exactement ce qui serait fait
sudo unattended-upgrade --dry-run --debug
# Sortie attendue (extrait) :
# Initial blacklist : linux-image* postgresql-* mariadb-server*
# Allowed origins are: ['origin=Debian,codename=bookworm,label=Debian-Security']
# Checking: openssh-server (...)
# pkgs that look like they should be upgraded:
# openssh-server openssh-client ...
# Writing dpkg log to /var/log/unattended-upgrades/unattended-upgrades-dpkg.log
# Si la sortie contient des paquets non-sécurité, revoir Allowed-Origins
# Si la sortie est vide alors qu'une CVE récente est annoncée, vérifier que
# apt update a bien rafraîchi la liste : sudo apt update && sudo unattended-upgrade --dry-run
# Forcer une exécution réelle ponctuelle (pour la première fois)
sudo unattended-upgrade --debug
Si unattended-upgrade --dry-run retourne sans erreur et liste uniquement des paquets de sécurité légitimes, la configuration est validée. La première exécution réelle (--debug sans --dry-run) appliquera les patches en attente, redémarrera les services concernés, et — si Automatic-Reboot true et qu’un fichier /var/run/reboot-required existe — programmera le reboot à 3h. Ce premier passage peut prendre 5-15 minutes selon le nombre de patches en attente.
Étape 5 — Configuration équivalente sur Rocky/Alma Linux
Sur les distributions de la famille RHEL (Rocky Linux 9, AlmaLinux 9, CentOS Stream 9), l’outil officiel est dnf-automatic (anciennement yum-cron). Le principe est strictement identique : application automatique des seuls patches de sécurité, exclusion de paquets critiques, notifications, redémarrage programmé.
# Installation
sudo dnf install -y dnf-automatic
# Configuration : /etc/dnf/automatic.conf
sudo nano /etc/dnf/automatic.conf
# [commands]
# upgrade_type = security
# random_sleep = 360
# download_updates = yes
# apply_updates = yes
#
# [emitters]
# emit_via = email,stdio
#
# [email]
# email_from = root@votre-entreprise.com
# email_to = ops@votre-entreprise.com
# email_host = localhost
#
# [base]
# debuglevel = 1
# Activer le timer dédié (pas le service !)
sudo systemctl enable --now dnf-automatic.timer
# Vérifier
systemctl list-timers | grep dnf-automatic
# NEXT LEFT LAST PASSED UNIT ACTIVATES
# Mon ... 06:14 10h - - dnf-automatic.timer dnf-automatic.service
# Pour exclure des paquets : ajouter dans /etc/dnf/dnf.conf
# exclude=postgresql* mariadb-server* httpd*
Le critère upgrade_type = security est l’équivalent d’Allowed-Origins ...security chez Debian : seules les errata classifiés « Security » (RHSA dans la nomenclature Red Hat) sont éligibles. random_sleep = 360 introduit un jitter de 6 minutes pour étaler les requêtes vers les mirroirs CDN Rocky/Alma. Le redémarrage automatique sur Rocky/Alma se gère séparément avec needs-restarting -r dans un cron, ou via tracer.
Étape 6 — Notifications email et monitoring
Sans notifications, on ne sait pas si les mises à jour passent ou échouent. Sur un parc de plusieurs VPS, suivre les rapports devient l’unique moyen de détecter rapidement un VPS qui dérive. Les notifications par email peuvent transiter par un MTA local (Postfix, configuré comme relay vers Brevo, Mailgun, SES, ou Mailcow) ou directement vers un endpoint webhook (Slack, Mattermost, Discord, Microsoft Teams).
# Configuration Postfix minimale comme relay vers Brevo (ex-Sendinblue)
sudo apt install -y postfix mailutils
# Lors de la configuration, choisir "Internet site with smarthost"
# Smarthost: smtp-relay.brevo.com:587
# Auth: à configurer dans /etc/postfix/sasl_passwd
echo "[smtp-relay.brevo.com]:587 votre-login-brevo:votre-clé-smtp-brevo" | sudo tee /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
sudo chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
# Activer SASL et TLS dans /etc/postfix/main.cf
sudo postconf -e 'relayhost = [smtp-relay.brevo.com]:587'
sudo postconf -e 'smtp_sasl_auth_enable = yes'
sudo postconf -e 'smtp_sasl_security_options = noanonymous'
sudo postconf -e 'smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd'
sudo postconf -e 'smtp_tls_security_level = encrypt'
sudo systemctl restart postfix
# Tester
echo "Test depuis VPS-$(hostname)" | mail -s "Test mises à jour auto" ops@votre-entreprise.com
Une fois Postfix configuré, unattended-upgrades envoie ses rapports via mail à l’adresse spécifiée par Unattended-Upgrade::Mail. Les rapports incluent la liste des paquets mis à jour, le journal complet de l’opération, et les éventuelles erreurs. MailReport "on-change" limite les notifications aux jours où quelque chose a effectivement été modifié — sans cela, vous recevez un email vide chaque jour, ce qui finit par être ignoré.
Étape 7 — Vérification opérationnelle après quelques jours
Après avoir laissé le système tourner 3 à 7 jours, faire un audit pour confirmer que tout fonctionne. Trois éléments à vérifier : les logs locaux, les notifications reçues, et la fraîcheur des paquets installés.
# 1. Logs unattended-upgrades
sudo tail -100 /var/log/unattended-upgrades/unattended-upgrades.log
sudo tail -50 /var/log/unattended-upgrades/unattended-upgrades-dpkg.log
# 2. État du dernier passage
sudo journalctl -u unattended-upgrades.service --since "7 days ago"
# 3. Reboot pending ?
[ -f /var/run/reboot-required ] && cat /var/run/reboot-required.pkgs || echo "Pas de reboot requis"
# 4. Vérifier que le timer systemd est actif et programmé
systemctl list-timers --all | grep apt-daily
# 5. Audit fraîcheur : combien de paquets sécurité non encore appliqués ?
sudo apt list --upgradable 2>/dev/null | grep -i "security"
# Doit retourner 0 ou très peu (les patches du jour pas encore traités)
Si apt list --upgradable | grep security retourne plusieurs dizaines de paquets, c’est que unattended-upgrades n’a pas tourné ou que Allowed-Origins n’inclut pas le bon dépôt. Re-tester avec --dry-run --debug et corriger. Une heuristique simple : sur un VPS bien configuré, ce nombre devrait osciller entre 0 et 3, jamais plus de 5 sauf juste après l’annonce d’une CVE majeure (Debian publie typiquement les correctifs sous 24-72 heures).
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
| Aucune mise à jour appliquée alors que des CVE existent | Allowed-Origins ne mentionne pas le bon dépôt (faute de frappe sur codename, par ex. bookworm-security au lieu de ${distro_codename}-security) | Vérifier avec apt-cache policy et corriger 50unattended-upgrades |
| « Could not get lock /var/lib/dpkg/lock-frontend » | Une autre instance d’apt tourne au même moment (mise à jour manuelle, ou Snap qui rafraîchit) | Attendre la fin ; à défaut, augmenter random_sleep ou décaler le timer |
| VPS redémarre en plein milieu d’une journée | Automatic-Reboot-Time mal configuré ou fuseau horaire serveur incorrect | timedatectl set-timezone Africa/Dakar ; vérifier la config |
| Email « configfile change » qui demande validation manuelle | Conflit dpkg (config locale modifiée vs nouvelle version) | Ajouter Dpkg::Options { "--force-confdef"; "--force-confold"; } dans 50unattended-upgrades |
| Service web inaccessible après reboot auto | Service avec After=network.target seulement (pas network-online.target) | Ajouter After=network-online.target dans le unit du service |
| Disk full après plusieurs mois | Anciens noyaux non purgés malgré Remove-Unused-Kernel-Packages | Vérifier apt list --installed | grep linux-image ; nettoyer manuellement apt autoremove --purge |
Ce qu’il faut savoir avant de déployer en sous-région
Trois ajustements pratiques pour un VPS hébergeant des services pour une PME ouest-africaine. Premièrement, ajuster le fuseau horaire : par défaut, les VPS Hetzner sont en UTC (heure GMT). Pour que Automatic-Reboot-Time "03:00" corresponde bien à 3h du matin locale, soit ajuster avec timedatectl set-timezone Africa/Dakar (ou Africa/Abidjan, Africa/Bamako, Africa/Ouagadougou — toutes en GMT+0), soit garder UTC et ajuster le créneau (3h UTC = 3h locale dans la zone WAT/GMT, donc inchangé). C’est un faux problème pour l’Afrique de l’Ouest qui est sur GMT, mais devient critique pour une équipe au Cameroun (GMT+1) ou en Afrique de l’Est.
Deuxièmement, gérer la connectivité intermittente : si le VPS est hébergé en Afrique (CIRA, Tunis Cloud, ou un datacenter local) avec une connexion vers les mirroirs Debian/Ubuntu en Europe parfois saturée, augmenter le timeout APT : echo 'Acquire::http::Timeout "120";' | sudo tee /etc/apt/apt.conf.d/99-timeouts. Sinon, des erreurs de timeout dans les logs unattended-upgrades sans application réelle de patches. Pour les VPS Hetzner Helsinki/Falkenstein, le problème ne se pose pas — la latence vers les mirroirs européens est excellente.
Troisièmement, planifier les redémarrages stratégiquement : pour un site e-commerce ouest-africain, l’heure creuse réelle est entre 2h et 5h du matin locale. Les sites EdTech (Moodle) ou de réservation hôtelière connaissent peu d’activité avant 6h. Pour un site visant principalement la diaspora (audience France/Belgique/Canada), inverser le calcul et programmer les reboots à 1h-3h heure de Paris/Bruxelles, soit 0h-2h heure locale Afrique de l’Ouest. L’objectif est d’éviter qu’un reboot coïncide avec un pic de trafic — un downtime de 30-90 secondes vu par 0 visiteurs équivaut à pas de downtime du tout.
Tutoriels frères
- VPS SSH hardening complet : tutoriel 2026 — durcir l’accès SSH du VPS
- Fail2ban configuration anti-bruteforce — bannir les IP qui multiplient les échecs
- Firewall Hetzner Cloud — restreindre l’exposition réseau
- Audit Lynis du VPS — vérifier que le hardening est complet
FAQ
Faut-il activer Automatic-Reboot ou non ?
Oui dans 95 % des cas. Une CVE noyau ou glibc nécessite un redémarrage pour appliquer le correctif — un service redémarré sans reboot continue d’utiliser la libc en mémoire vulnérable. Les rares exceptions où désactiver le reboot auto : VPS hébergeant un service stateful sans cluster (base de données primaire sans réplica), ou service avec démarrage long et critique (10+ minutes pour récupérer son état). Dans ces cas, désactiver et appliquer manuellement avec downtime planifié.
Que se passe-t-il si une mise à jour casse un service ?
C’est rare quand on se limite à ${distro_codename}-security (les patches sécurité Debian/Ubuntu sont testés extensivement avant publication). Mais un cas peut arriver : la mise à jour OpenSSL force la rotation d’une dépendance qui casse une lib applicative. Mitigation : (1) snapshots VPS quotidiens chez l’hébergeur (Hetzner, OVH proposent ça), (2) monitoring externe (UptimeRobot, BetterStack, Pingdom) qui alerte immédiatement, (3) un runbook documenté pour rollback rapide via snapshot.
Et pour les conteneurs Docker, comment gérer ?
Les conteneurs ne sont pas concernés par unattended-upgrades du host — ils ont leur propre cycle de vie. Pour les images Docker maintenues par l’éditeur (officiel Postgres, Nginx, Redis), un mécanisme distinct : Watchtower (analyse et pull automatique des nouvelles tags) ou plus rigoureusement un workflow CI/CD qui rebuild les images via Renovate. Le host VPS reste à jour via unattended-upgrades pour le kernel, OpenSSH, OpenSSL et docker engine ; les services dans les conteneurs sont gérés à part.
Comment détecter qu’un VPS s’est mis à jour automatiquement ?
Plusieurs signaux. (1) Le mail envoyé via MailReport "on-change". (2) Le fichier /var/log/unattended-upgrades/unattended-upgrades.log avec une entrée datée. (3) Un script de monitoring qui surveille l’âge du dernier passage : stat -c %Y /var/log/unattended-upgrades/unattended-upgrades.log retourne le timestamp du dernier event ; alerter si supérieur à 48h. (4) Centralisation via Wazuh ou Loki/Promtail des logs, dashboards Grafana sur les VPS qui dérivent.
Lectures complémentaires
- 🔝 Retour au guide général : VPS hardening sécurité 2026 : guide pratique
- Documentation Debian Wiki : wiki.debian.org/UnattendedUpgrades
- Documentation Ubuntu Server Guide : ubuntu.com/server/docs/package-management
- Documentation dnf-automatic Red Hat : access.redhat.com/articles/15861
- Tutoriel suivant suggéré : configurer Fail2ban pour le bannissement automatique des bots
Mots-clés secondaires : unattended-upgrades, dnf-automatic, mises à jour de sécurité automatiques, Debian Ubuntu sécurité, RHSA Rocky Linux, hardening VPS, regreSSHion CVE-2024-6387, automatisation patches.
Vous cherchez un hébergement web sérieux et abordable ?
Hostinger offre des serveurs avec installation WordPress en un clic et un panel simple. Notre équipe l’utilise au quotidien.
Lien d affiliation. Si vous achetez via ce lien, le blog reçoit une petite commission sans surcoût pour vous.