Cybersécurité

VPS mises à jour sécurité automatiques : tutoriel 2026

15 min de lecture

📍 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

ErreurCauseSolution
Aucune mise à jour appliquée alors que des CVE existentAllowed-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éeAutomatic-Reboot-Time mal configuré ou fuseau horaire serveur incorrecttimedatectl set-timezone Africa/Dakar ; vérifier la config
Email « configfile change » qui demande validation manuelleConflit dpkg (config locale modifiée vs nouvelle version)Ajouter Dpkg::Options { "--force-confdef"; "--force-confold"; } dans 50unattended-upgrades
Service web inaccessible après reboot autoService avec After=network.target seulement (pas network-online.target)Ajouter After=network-online.target dans le unit du service
Disk full après plusieurs moisAnciens noyaux non purgés malgré Remove-Unused-Kernel-PackagesVé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

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

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.

Découvrir Hostinger →

Lien d affiliation. Si vous achetez via ce lien, le blog reçoit une petite commission sans surcoût pour vous.

Partager