Sicherheitsupdates automatisieren, ohne die Kontrolle zu verlieren
Ungepatchte Server sind das häufigste Einfallstor für Angriffe, aber vollautomatische Updates ohne Kontrolle bergen ein eigenes Risiko. Dieser Artikel zeigt, wie unattended-upgrades Sicherheitspatches zuverlässig einspielt, Fehler per E-Mail meldet und Reboots in ein planbares Wartungsfenster verschiebt, statt den Betrieb unvorhersehbar zu unterbrechen.
Inhaltsverzeichnis
- 1. Der Zielkonflikt: gepatcht bleiben vs. Kontrolle behalten
- 2. Installation und Grundkonfiguration
- 3. Nur Sicherheitsupdates: Origins-Pattern richtig setzen
- 4. Zeitplan: von der Cron-Datei zum systemd-Timer
- 5. E-Mail-Benachrichtigungen bei Fehlern konfigurieren
- 6. Pakete gezielt ausschließen und Versionssperren setzen
- 7. Reboots in ein kontrolliertes Wartungsfenster legen
- 8. Logging, Trockenlauf und laufende Kontrolle
- 9. Automatisierungsgrade im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Der Zielkonflikt: gepatcht bleiben vs. Kontrolle behalten
Die Mehrzahl erfolgreicher Server-Kompromittierungen nutzt keine Zero-Day-Lücken, sondern längst bekannte Schwachstellen, für die seit Wochen oder Monaten ein Patch verfügbar ist. Wer Updates nur manuell einspielt, verschiebt das Patchen fast zwangsläufig, weil andere Aufgaben Vorrang bekommen. Unattended Upgrades lösen genau dieses Problem: Sicherheitspatches werden automatisch heruntergeladen und installiert, ohne dass ein Administrator jeden einzelnen Server einzeln pflegen muss.
Der Preis für diese Automatisierung ist ein reales Risiko: Ein fehlerhaftes Update kann einen Dienst destabilisieren, eine Konfigurationsdatei überschreiben oder einen unerwarteten Neustart eines Kernel-Pakets auslösen. Die Lösung ist nicht, auf Automatisierung zu verzichten, sondern sie gezielt einzugrenzen: nur Security-Repositories automatisch patchen, Fehler sofort per E-Mail melden und Neustarts in ein planbares Wartungsfenster verschieben. So bleibt der Server aktuell, ohne dass ein Update um drei Uhr morgens unbemerkt einen Produktionsdienst lahmlegt.
Dieser Artikel behandelt die Konfiguration von unattended-upgrades auf Debian- und Ubuntu-basierten Systemen, von der Grundinstallation über die Beschränkung auf sicherheitsrelevante Pakete bis zur sauberen Trennung von automatischem Patchen und kontrolliertem Reboot.
2. Installation und Grundkonfiguration
Das Paket unattended-upgrades ist auf Ubuntu-Servern meist bereits vorinstalliert, auf Debian muss es explizit nachinstalliert werden. Nach der Installation aktiviert dpkg-reconfigure im interaktiven Modus die automatischen Updates und legt die Basiskonfiguration in /etc/apt/apt.conf.d/20auto-upgrades an. Diese Datei steuert zwei grundlegende Schalter: ob apt-get update täglich automatisch läuft und ob unattended-upgrade anschließend Pakete installiert.
Die eigentliche Logik steckt in /etc/apt/apt.conf.d/50unattended-upgrades. Diese Datei ist von Haus aus umfangreich kommentiert, aber die Standardwerte sind für Produktionsserver zu großzügig: Ohne Anpassung installiert das Paket unter Umständen auch Updates aus dem regulären -updates-Repository, nicht nur aus -security. Wer die Datei einmal grundlegend versteht, kann sie danach gezielt auf den eigenen Risikoappetit zuschneiden, statt sich auf Distributionsvoreinstellungen zu verlassen.
#!/usr/bin/env bash
# Install and enable unattended-upgrades on a fresh Debian/Ubuntu server
set -euo pipefail
apt-get update
apt-get install -y unattended-upgrades apt-listchanges
# Enable the daily systemd timer / cron entry
dpkg-reconfigure -plow unattended-upgrades
# Verify the base toggle file was written correctly
cat /etc/apt/apt.conf.d/20auto-upgrades
# APT::Periodic::Update-Package-Lists "1";
# APT::Periodic::Unattended-Upgrade "1";
# Confirm the service and timer are active
systemctl status unattended-upgrades.service --no-pager
systemctl list-timers apt-daily-upgrade.timer
Ein Detail, das häufig übersehen wird: apt-listchanges zeigt vor jedem Upgrade eine Zusammenfassung der Changelog-Eintraege betroffener Pakete an. In Kombination mit unattended-upgrades landet diese Zusammenfassung automatisch in der E-Mail-Benachrichtigung aus Abschnitt 5, was die Nachvollziehbarkeit erheblich verbessert. Ohne dieses Paket sieht man im Log nur Paketnamen und Versionsnummern, aber keinen Hinweis darauf, welches konkrete Sicherheitsproblem behoben wurde.
3. Nur Sicherheitsupdates: Origins-Pattern richtig setzen
Der Kern der Risikobegrenzung liegt im Block Unattended-Upgrade::Origins-Pattern in 50unattended-upgrades. Standardmäßig enthält diese Liste bei manchen Distributionen bereits mehr als nur Security-Updates. Für einen konservativen Ansatz, der ausschließlich sicherheitsrelevante Patches automatisch einspielt, muss die Liste auf die -security-Suite reduziert werden. Auf Debian-Systemen lautet das relevante Origin-Muster origin=Debian,codename=${distro_codename}-security, auf Ubuntu origin=Ubuntu,archive=${distro_codename}-security.
Wichtig ist, alle anderen Zeilen mit -updates, -proposed oder -backports auszukommentieren, wenn wirklich nur Security-Patches automatisch laufen sollen. Feature-Updates aus dem regulären -updates-Kanal können neue Funktionsversionen oder Verhaltensänderungen mitbringen, die man bewusst und manuell testen möchte, bevor sie auf Produktionssystemen landen. Diese Trennung ist der wichtigste einzelne Konfigurationsschritt, um den Zielkonflikt aus Abschnitt 1 aufzulösen.
// /etc/apt/apt.conf.d/50unattended-upgrades
// Restrict automatic installs to security-only origins
Unattended-Upgrade::Origins-Pattern {
"origin=Debian,codename=${distro_codename}-security";
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
// Regular point releases stay disabled, test manually first
// "origin=Debian,codename=${distro_codename}-updates";
// "origin=Debian,codename=${distro_codename}-proposed-updates";
};
// Remove unused dependencies after a successful upgrade run
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
// Keep at most 2 old kernel versions on disk
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
4. Zeitplan: von der Cron-Datei zum systemd-Timer
Auf aktuellen Debian- und Ubuntu-Versionen wird unattended-upgrades nicht mehr über eine klassische Crontab gesteuert, sondern über den systemd-Timer apt-daily-upgrade.timer, der wiederum den Service apt-daily-upgrade.service auslöst. Dieser Timer ist standardmäßig auf einen zufälligen Zeitpunkt pro Tag mit einem RandomizedDelaySec gesetzt, damit nicht alle Server einer Flotte gleichzeitig auf dieselben Paketspiegel zugreifen. Für einzelne Server ist das unproblematisch, in größeren Umgebungen mit gemeinsamem Spiegel-Server verhindert die Randomisierung Lastspitzen.
Wer den Zeitpunkt präziser steuern will, etwa um Patch-Läufe außerhalb der Hauptgeschäftszeiten zu erzwingen, überschreibt den Timer mit einer Drop-in-Datei statt die Systemdatei direkt zu editieren. Das korrekte Pattern dafür ist systemctl edit apt-daily-upgrade.timer, das automatisch eine Override-Datei unter /etc/systemd/system/apt-daily-upgrade.timer.d/ anlegt und beim nächsten Paket-Update nicht überschrieben wird.
# /etc/systemd/system/apt-daily-upgrade.timer.d/override.conf
# Created via: systemctl edit apt-daily-upgrade.timer
# Pin the upgrade run to a fixed early-morning slot instead of a random one
[Timer]
OnCalendar=
OnCalendar=*-*-* 04:15:00
RandomizedDelaySec=300
Persistent=true
5. E-Mail-Benachrichtigungen bei Fehlern konfigurieren
Automatisierung ohne Rückmeldung ist blindes Vertrauen. Der Block Unattended-Upgrade::Mail in 50unattended-upgrades sendet standardmäßig gar keine E-Mail, es sei denn, man trägt eine Adresse ein. Mit Unattended-Upgrade::MailOnlyOnError "true" beschränkt man den Versand auf fehlgeschlagene Läufe, statt täglich eine Erfolgsmeldung zu bekommen, die nach wenigen Tagen ohnehin ignoriert wird. Diese Kombination ist der Sweet Spot: Stille bedeutet Erfolg, eine E-Mail bedeutet sofortigen Handlungsbedarf.
Voraussetzung ist ein funktionierender Mail-Transport auf dem Server. Ein minimaler msmtp- oder postfix-Relay reicht aus, damit /usr/sbin/sendmail tatsächlich zustellt. Ein häufiger Fehler in der Praxis: Die Konfiguration sieht korrekt aus, aber der Server hat gar keinen funktionierenden Mailversand, und Fehler verpuffen unbemerkt. Ein Testlauf mit absichtlich blockiertem Paket deckt das zuverlässig auf, bevor man sich auf die Benachrichtigung verlässt.
// /etc/apt/apt.conf.d/50unattended-upgrades
// Send mail only when something actually goes wrong
Unattended-Upgrade::Mail "ops-alerts@mironsoft.de";
Unattended-Upgrade::MailOnlyOnError "true";
Unattended-Upgrade::Sender "root@$(hostname -f)";
// Verbosity of the report attached to failure mails
Unattended-Upgrade::Verbose "true";
Unattended-Upgrade::Debug "false";
#!/usr/bin/env bash
# Force a dry-run failure to verify the mail pipeline actually delivers
set -euo pipefail
# Simulate an upgrade run without installing anything
unattended-upgrade --dry-run --debug 2>&1 | tee /tmp/uu-dryrun.log
# Send a manual test mail through the same transport used by cron/systemd
echo "Test: unattended-upgrades mail delivery" | \
mail -s "[TEST] unattended-upgrades on $(hostname -f)" ops-alerts@mironsoft.de
# Check the mail queue for delivery problems
mailq
6. Pakete gezielt ausschließen und Versionssperren setzen
Manche Pakete sollen selbst bei einem als sicherheitsrelevant eingestuften Update niemals automatisch aktualisiert werden, etwa die Datenbank-Engine oder der PHP-Interpreter, wenn eine Major-Version-Kompatibilität zu einer produktiven Anwendung besteht. Unattended-Upgrade::Package-Blacklist akzeptiert Regex-Muster und schließt passende Pakete vollständig von automatischen Updates aus, unabhängig vom Origin. Das ist bewusst grob: Ein einmal geblacklistetes Paket muss danach manuell gepflegt werden, sonst häufen sich unbemerkt offene Sicherheitslücken an.
Eine feinere Alternative ist APT Pinning über /etc/apt/preferences.d/, das statt eines kompletten Ausschlusses eine maximale Versionsgrenze setzt. Damit lassen sich Patch-Level-Updates innerhalb einer Major-Version weiterhin automatisch einspielen, während ein Versionssprung, der Breaking Changes mitbringen könnte, blockiert bleibt. Diese Kombination aus Blacklist für kritische Kernkomponenten und Pinning für alles andere ist in produktiven Umgebungen der robusteste Ansatz.
// /etc/apt/apt.conf.d/50unattended-upgrades
// Never auto-update the database engine or the active PHP runtime
Unattended-Upgrade::Package-Blacklist {
"mysql-server-*";
"mariadb-server-*";
"php8.3-*";
};
# /etc/apt/preferences.d/pin-nginx.pref
# Allow patch-level updates, block the next major version jump
Package: nginx nginx-common nginx-core
Pin: version 1.24.*
Pin-Priority: 1001
7. Reboots in ein kontrolliertes Wartungsfenster legen
Kernel-Updates, glibc-Patches und einige OpenSSL-Aktualisierungen erfordern einen Neustart, damit die neue Version tatsächlich aktiv wird. Der schlimmste Fall ist ein Server, der wochenlang mit installiertem, aber nicht aktivem Sicherheitspatch läuft, weil niemand den fälligen Reboot bemerkt. Der zweitschlimmste Fall ist ein Server, der automatisch um eine unvorhersehbare Uhrzeit neu startet und dabei aktive Nutzersitzungen oder laufende Batch-Jobs unterbricht. Die Lösung ist, den Reboot zwar zu automatisieren, aber strikt an ein festes Wartungsfenster zu binden.
Die Optionen Unattended-Upgrade::Automatic-Reboot und Unattended-Upgrade::Automatic-Reboot-Time steuern genau das: Ein Reboot wird nur ausgeführt, wenn /var/run/reboot-required existiert, und zwar erst zum konfigurierten Zeitpunkt, nicht sofort nach dem Update. Zusätzlich lohnt sich ein eigener systemd-Timer, der unabhängig vom Update-Lauf prüft, ob ein Reboot aussteht, und diesen kontrolliert mit Vorwarnzeit für angemeldete Nutzer durchführt. So bleibt der Automatisierungsgrad hoch, ohne die Vorhersehbarkeit für den Betrieb zu opfern.
// /etc/apt/apt.conf.d/50unattended-upgrades
// Reboot only when actually required, and only inside the maintenance window
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-WithUsers "false";
Unattended-Upgrade::Automatic-Reboot-Time "04:30";
#!/usr/bin/env bash
# maintenance-reboot.sh: independent check, run inside a fixed window
set -euo pipefail
if [[ ! -f /var/run/reboot-required ]]; then
echo "[OK] No reboot pending, nothing to do"
exit 0
fi
echo "[INFO] Reboot required, packages:"
cat /var/run/reboot-required.pkgs 2>/dev/null || true
# Warn logged-in users 5 minutes ahead, then reboot
wall "Maintenance reboot for security updates in 5 minutes."
sleep 300
systemctl reboot
8. Logging, Trockenlauf und laufende Kontrolle
Jeder Lauf von unattended-upgrades schreibt ein detailliertes Protokoll nach /var/log/unattended-upgrades/unattended-upgrades.log sowie eine kompakte Zusammenfassung installierter Pakete nach unattended-upgrades-dpkg.log. Diese beiden Dateien sind die erste Anlaufstelle bei der Fehlersuche, wenn eine E-Mail-Benachrichtigung eingegangen ist oder ein Dienst nach einem nächtlichen Update unerwartetes Verhalten zeigt. Da beide Logs mit der Zeit wachsen, gehört eine logrotate-Konfiguration mit Kompression und einer sinnvollen Aufbewahrungsfrist zur Grundausstattung, nicht erst nach dem ersten vollgelaufenen /var/log.
Vor jeder Änderung an der Konfiguration lohnt sich ein Trockenlauf mit unattended-upgrade --dry-run --debug, der exakt zeigt, welche Pakete anhand der aktuellen Origins-Pattern und Blacklist tatsächlich aktualisiert würden, ohne etwas zu installieren. Dieser Befehl ist auch das richtige Werkzeug, um nach einer Anpassung der Security-Only-Filterung aus Abschnitt 3 zu verifizieren, dass wirklich nur die gewünschten Pakete erfasst werden, bevor der nächste automatische Lauf startet.
# /etc/logrotate.d/unattended-upgrades
# Keep six months of compressed history for audit and incident review
/var/log/unattended-upgrades/*.log {
monthly
rotate 6
compress
delaycompress
missingok
notifempty
create 0640 root adm
}
9. Automatisierungsgrade im direkten Vergleich
Zwischen komplett manuellem Patchen und vollautomatischen Updates ohne jede Einschränkung liegt ein breites Spektrum an Konfigurationsoptionen. Die folgende Übersicht stellt die gängigen Automatisierungsgrade gegenüber und zeigt, welcher Ansatz für Produktionsserver empfehlenswert ist.
| Ansatz | Risiko | Empfehlung | Begründung |
|---|---|---|---|
| Rein manuelles Patchen | Patches bleiben wochenlang aus | Nicht empfohlen | Bekannte Lücken bleiben offen, weil Zeit fehlt |
| Alle Repositories automatisch | Feature-Updates ohne Test | Nicht empfohlen | Breaking Changes landen ungeplant in Produktion |
| Security-only, ohne Mail | Fehlgeschlagene Updates unbemerkt | Bedingt geeignet | Kein Feedback-Kanal bei Problemen |
| Security-only + Mail bei Fehlern | Gering | Empfohlen | Automatisch gepatcht, Fehler sofort sichtbar |
| + festes Reboot-Wartungsfenster | Sehr gering | Best Practice | Patches aktiv, Neustarts planbar statt überraschend |
In der Praxis ist die Kombination aus Security-only-Filterung, fehlerbasierter E-Mail-Benachrichtigung und einem festen Reboot-Fenster der Ansatz, der Automatisierungsgrad und Kontrolle am besten ausbalanciert. Wer diese drei Bausteine konsequent kombiniert, reduziert sowohl das Risiko ungepatchter Lücken als auch das Risiko unkontrollierter Ausfälle durch fehlerhafte Updates auf ein Minimum.
Mironsoft
Server-Hardening, Patch-Management und Linux-Betrieb für Magento-Infrastruktur
Server zuverlässig patchen, ohne Überraschungen?
Wir richten unattended-upgrades produktionstauglich ein: Security-only-Filterung, Fehlerbenachrichtigung per Mail und ein festes Wartungsfenster für Reboots, abgestimmt auf eure Magento- und Infrastruktur-Landschaft.
Patch-Audit
Bestehende Update-Konfiguration prüfen und Lücken identifizieren
Automatisierung
Security-only-Updates, Blacklist und Mail-Alerts produktionsreif konfigurieren
Wartungsfenster
Kontrollierte Reboot-Fenster in bestehende Deployment-Prozesse integrieren
10. Zusammenfassung
Unattended Upgrades lösen den Zielkonflikt zwischen konstant gepatchten Servern und der Angst vor unkontrollierten Nebenwirkungen durch gezielte Eingrenzung statt durch Verzicht auf Automatisierung. Die Beschränkung auf -security-Origins in Unattended-Upgrade::Origins-Pattern verhindert, dass ungetestete Feature-Updates automatisch installiert werden. MailOnlyOnError sorgt dafür, dass Stille Erfolg bedeutet und jede E-Mail sofortigen Handlungsbedarf signalisiert. Eine Package-Blacklist schützt kritische Kernkomponenten wie Datenbank und Laufzeitumgebung vor automatischen Eingriffen.
Reboots gehören strikt in ein festes Wartungsfenster, gesteuert über Automatic-Reboot-Time oder einen eigenen systemd-Timer mit Vorwarnzeit für Nutzer. So bleibt der Server durchgehend gepatcht, ohne dass ein Neustart unvorhersehbar mitten am Tag passiert. Regelmäßige Trockenläufe mit --dry-run --debug und eine saubere Logrotate-Konfiguration runden die Konfiguration ab und machen jeden Update-Lauf nachvollziehbar.
Unattended Upgrades automatisieren: Das Wichtigste auf einen Blick
Security-only patchen
Origins-Pattern auf -security beschränken, -updates und -backports auskommentieren.
Fehler per Mail melden
MailOnlyOnError "true" plus funktionierender Mail-Transport, verifiziert mit einem Testlauf.
Kritische Pakete ausschließen
Package-Blacklist für Datenbank und Laufzeitumgebung, APT Pinning für alles andere.
Reboots im Wartungsfenster
Automatic-Reboot-Time auf ein festes, ruhiges Zeitfenster setzen, Nutzer vorwarnen.