Automatische Sicherheitsupdates unter Debian/Ubuntu mit unattended-upgrades richtig konfigurieren
Wie du unattended-upgrades auf Debian- und Ubuntu-Servern so konfigurierst, dass nur Security-Pakete automatisch eingespielt werden – mit eigener Konfigurationsdatei, Package-Blacklist für Datenbanken und Reverse-Proxy, E-Mail bei Fehlern und kontrollierten Reboots im Wartungsfenster.

Ungepatchte Sicherheitslücken sind einer der häufigsten Angriffsvektoren auf Linux-Server – besonders in KMU, wo kein dediziertes Patching-Team vorhanden ist. unattended-upgrades ist das Standardwerkzeug unter Debian und Ubuntu, um Sicherheitsaktualisierungen vollautomatisch und ohne manuellen Eingriff einzuspielen. Richtig konfiguriert ist es das Linux-Äquivalent zu WSUS: nur geprüfte Security-Origins, heikle Dienste per Blacklist ausgenommen, Reboots ausschließlich im definierten Wartungsfenster, E-Mail bei Fehlern. Diese Anleitung zeigt dir den gesamten Weg – von der Installation bis zur Logauswertung.
Voraussetzungen
- Debian (Bookworm / Bullseye) oder Ubuntu (22.04 LTS / 24.04 LTS) Server
- Root- oder sudo-Zugriff auf den Server
- Paket
unattended-upgradesinstalliert (auf Ubuntu oft vorinstalliert) - Konfigurierter MTA (
postfixals Relay odermsmtp) für E-Mail-Benachrichtigungen - Gültige E-Mail-Adresse für Fehlerbenachrichtigungen
- Bekanntes Wartungsfenster (Uhrzeit) für Updates und Reboots
- Liste der Dienste/Pakete, die von automatischen Updates ausgenommen werden sollen
Schritt 1: Paket installieren und Grundkonfiguration aktivieren
Auf Debian-Servern ist unattended-upgrades nicht immer vorinstalliert. Installiere das Paket zusammen mit apt-listchanges, das Changelog-Einträge vor dem Update anzeigen kann:
sudo apt update && sudo apt install unattended-upgrades apt-listchanges
Den interaktiven Einrichtungsassistenten rufst du so auf:
sudo dpkg-reconfigure -plow unattended-upgrades
Der Assistent erzeugt oder überschreibt /etc/apt/apt.conf.d/20auto-upgrades mit den Grundeinstellungen. Passe diese Datei anschließend manuell an:
# /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
Der Wert "1" bedeutet täglich. AutocleanInterval "7" bereinigt den APT-Cache wöchentlich und verhindert, dass heruntergeladene Pakete die Festplatte füllen. Den Wert "0" setzt du, um eine Funktion zu deaktivieren.
Schritt 2: Die eigene Konfigurationsdatei anlegen (52unattended-upgrades-local)
Hier liegt einer der wichtigsten Grundsätze: Bearbeite niemals /etc/apt/apt.conf.d/50unattended-upgrades direkt. Diese Datei gehört dem Paket und wird bei jedem Update überschrieben. APT liest Konfigurationsdateien in lexikalischer Reihenfolge – Dateien mit höherem Präfix überschreiben frühere Einstellungen. Erstelle stattdessen:
sudo nano /etc/apt/apt.conf.d/52unattended-upgrades-local
Wichtig bei Listen wie Package-Blacklist oder Origins-Pattern: APT kumuliert Listen statt sie zu ersetzen. Willst du die Original-Liste komplett neu definieren, stelle ein #clear voran:
#clear Unattended-Upgrade::Origins-Pattern;
Die vollständige Konfiguration für Debian-Server:
# /etc/apt/apt.conf.d/52unattended-upgrades-local
// --- Nur Security-Origins (Debian) ---
// #clear leert die aus 50unattended-upgrades geerbte Liste
#clear Unattended-Upgrade::Origins-Pattern;
Unattended-Upgrade::Origins-Pattern {
"origin=Debian,codename=${distro_codename},label=Debian-Security";
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
};
// --- Blacklist fuer heikle Dienste ---
Unattended-Upgrade::Package-Blacklist {
"nginx$";
"nginx-";
"mysql-server";
"mysql-client";
"mariadb-server";
"mariadb-client";
"postgresql";
"postgresql-";
"redis-server";
"haproxy";
};
// --- E-Mail bei Fehlern ---
Unattended-Upgrade::Mail "admin@example.com";
Unattended-Upgrade::MailReport "only-on-error";
// Optional: Unattended-Upgrade::Sender "server@example.com";
// --- Automatischer Neustart im Wartungsfenster ---
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-WithUsers "false";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
// --- Aufraeumen nach Updates ---
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
Für Ubuntu-Server verwendest du statt Origins-Pattern den historisch gewachsenen Schlüssel Allowed-Origins (beide Schlüssel funktionieren auf beiden Systemen, aber die Ubuntu-Standarddatei verwendet Allowed-Origins):
// --- Nur Security-Origins (Ubuntu) ---
#clear Unattended-Upgrade::Allowed-Origins;
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
};
Die ESM-Zeilen sind nur relevant bei Ubuntu Pro / Ubuntu Advantage. Auf Standard-Ubuntu ohne Pro-Abonnement kannst du sie weglassen.
Schritt 3: Debian vs. Ubuntu – Unterschiede auf einen Blick
| Eigenschaft | Debian (Bookworm/Bullseye) | Ubuntu (22.04/24.04 LTS) |
|---|---|---|
| Origins-Schlüssel | Origins-Pattern | Allowed-Origins (historisch) |
| Security-Origin-Format | origin=Debian,codename=...,label=Debian-Security | ${distro_id}:${distro_codename}-security |
| Security-Quellen | Zwei Einträge nötig (codename + codename-security) | Ein Eintrag + optional ESM für Ubuntu Pro |
| Vorinstalliert | Nein, manuell installieren | Ja, seit Ubuntu 16.04 |
| needrestart auf 24.04 | Normales Verhalten | Ubuntu-Mode kann 'a' ignorieren (Bug #2068543) |
Schritt 4: Package-Blacklist korrekt mit Regex-Ankern definieren
Die Package-Blacklist verwendet Python Regular Expressions. Ein häufiger Fehler ist das Weglassen von Ankern: Das Muster mysql ohne Anker trifft auch libmysqlclient-dev oder php8.2-mysql. Verwende immer Anker:
mysql-server$– trifft genau das Paketmysql-servermysql-– trifft alle Pakete, die mitmysql-beginnenpostgresql$– trifft genaupostgresqlpostgresql-– trifft alle versionierten Pakete wiepostgresql-16
Den Origin-Wert einer eigenen Paketquelle (PPA, Drittanbieter) ermittelst du so:
# Beispiel fuer nginx aus dem offiziellen nginx.org-Repo
apt-cache policy nginx
# Ausgabe auswerten: o=Origin l=Label
# 500 http://nginx.org/packages/debian bookworm/nginx amd64 Packages
# release o=nginx, l=nginx, a=stable, n=bookworm, ...
# -> Pattern: "origin=nginx,label=nginx";
Schritt 5: Wartungsfenster per systemd-Timer-Override setzen
Zwei systemd-Timer steuern den Ablauf: apt-daily.timer lädt die Paketlisten herunter, apt-daily-upgrade.timer spielt die Updates ein. Beide haben standardmäßig einen RandomizedDelaySec-Wert, der die Ausführung um Stunden verschieben kann – apt-daily bis zu 12 Stunden, apt-daily-upgrade bis zu 60 Minuten. Ohne Override auf 0 greifen Wartungsfenster-Konfigurationen nicht zuverlässig.
Erstelle zuerst den Override für den Paketlisten-Download (5 Minuten vor der Installation):
sudo systemctl edit apt-daily.timer
Füge folgenden Inhalt ein und speichere:
[Timer]
OnCalendar=
OnCalendar=02:55
RandomizedDelaySec=0
Dann den Override für die eigentliche Installation:
sudo systemctl edit apt-daily-upgrade.timer
[Timer]
OnCalendar=
OnCalendar=03:00
RandomizedDelaySec=0
Die leere OnCalendar=-Zeile setzt den bestehenden Wert zurück, bevor der neue Wert gesetzt wird. Danach Timer neu laden und prüfen:
sudo systemctl daemon-reload && sudo systemctl restart apt-daily.timer apt-daily-upgrade.timer
sudo systemctl status apt-daily-upgrade.timer
Schritt 6: needrestart für automatischen Dienstneustart konfigurieren
Nach einem Sicherheitsupdate müssen Dienste, die aktualisierte Bibliotheken laden, neu gestartet werden – sonst laufen sie weiter mit der alten, verwundbaren Version im Arbeitsspeicher. needrestart erkennt diese Situation automatisch und startet betroffene Dienste neu, ohne einen vollständigen Reboot auszulösen.
sudo apt install needrestart
Setze den Restart-Modus auf automatisch in /etc/needrestart/needrestart.conf:
sudo nano /etc/needrestart/needrestart.conf
# a = automatisch, i = interaktiv (blockiert unattended-upgrades!), l = nur auflisten
$nrconf{restart} = 'a';
Achtung bei Ubuntu 24.04: Ein Ubuntu-spezifischer Modus kann 'a' unter bestimmten Umständen ignorieren (Launchpad Bug #2068543). Verifiziere das Verhalten nach jedem Ubuntu-LTS-Upgrade.
Wer systemd-Services kennt, versteht, warum needrestart hier besser ist als ein vollständiger Reboot: Es startet nur die betroffenen Units neu, der Rest des Systems läuft ungestört weiter.
Schritt 7: E-Mail-Benachrichtigungen einrichten
Damit Fehler-E-Mails ankommen, muss ein MTA installiert und konfiguriert sein. Für Server, die E-Mail über einen Relay-Host versenden, ist postfix die klassische Wahl:
sudo apt install postfix mailutils
# Typ bei Installation: "Satellite system" oder "Internet with smarthost"
Alternativ ist msmtp als leichtgewichtiger SMTP-Client geeignet:
sudo apt install msmtp msmtp-mta
# Symlink fuer sendmail-Kompatibilitaet
sudo ln -fs /usr/bin/msmtp /usr/sbin/sendmail
Nach der MTA-Konfiguration sendest du eine Testmail:
echo 'Test unattended-upgrades Mail' | mail -s 'Test' admin@example.com
Kommt die Testmail nicht an, schlagen auch alle späteren Fehlerbenachrichtigungen lautlos fehl – dieser Test ist Pflicht.
Schritt 8: Konfiguration testen und Logs auswerten
Bevor das System das erste Mal automatisch läuft, testest du mit einem Trockentest:
# Trockentest: zeigt was getan wuerde, ohne Pakete zu veraendern
sudo unattended-upgrade --dry-run --debug
# Sofortiger Testlauf mit Verbose-Ausgabe (spielt Updates wirklich ein)
sudo unattended-upgrade -v
Die wichtigsten Logdateien für die laufende Überwachung:
# Hauptlog: Uebersicht aller Laeufe und installierten Pakete
tail -f /var/log/unattended-upgrades/unattended-upgrades.log
# Fehler und Warnungen filtern
grep -i 'error\|warn\|upgrade' /var/log/unattended-upgrades/unattended-upgrades.log
# dpkg-Aktionen des letzten Update-Laufs
tail -100 /var/log/unattended-upgrades/unattended-upgrades-dpkg.log
# Pruefen ob ein Reboot faellig ist
cat /var/run/reboot-required
cat /var/run/reboot-required.pkgs
Die Datei /var/run/reboot-required existiert, wenn ein installiertes Paket einen Neustart erfordert. reboot-required.pkgs listet die verantwortlichen Pakete auf. Mehr zum Thema Loganalyse erklärt die Anleitung Logs lesen und auswerten mit journalctl und /var/log.
Troubleshooting / Typische Fehler
-
Updates laufen nicht zur konfigurierten Zeit:
RandomizedDelaySecwar nicht auf0gesetzt. Prüfe den Override mitsudo systemctl cat apt-daily-upgrade.timer. Der[Timer]-Abschnitt im Override muss die leereOnCalendar=-Zeile, den neuen Wert undRandomizedDelaySec=0enthalten. -
Eigene Einstellungen verschwinden nach apt upgrade: Du hast
/etc/apt/apt.conf.d/50unattended-upgradesdirekt bearbeitet. Diese Datei gehört dem Paket und wird ersetzt. Lege alle Anpassungen in52unattended-upgrades-localab. -
Package-Blacklist greift nicht oder zu weit: Regex-Anker fehlen.
nginxohne Anker trifft auchphp-nginxodernginx-common. Nutzenginx$für exaktes Matching. Teste mit--dry-run --debug. -
Keine E-Mail bei Fehlern: Kein MTA installiert oder falsch konfiguriert. Teste mit
echo 'Test' | mail -s 'Test' admin@example.com. Ohne funktionierenden MTA schlägt der Versand lautlos fehl. -
unattended-upgrades hängt und läuft nicht durch:
needrestartist im interaktiven Modus ('i') konfiguriert und wartet auf Benutzereingabe. Setze$nrconf{restart} = 'a';in/etc/needrestart/needrestart.conf. -
Listeneinträge werden doppelt ausgewertet: Beide Dateien definieren
Package-BlacklistoderOrigins-Pattern– APT kumuliert Listen. Stelle ein#clear Unattended-Upgrade::Package-Blacklist;vor dem Block in der lokalen Datei. -
Reboot startet trotz angemeldeter SSH-Session:
Automatic-Reboot-WithUsers "true"ist gesetzt. Setze es auf"false"oder entferne die Zeile (Standard istfalse).
Häufige Fragen
Wie unterscheiden sich Debian und Ubuntu bei den Origins-Pattern?
Debian nutzt das Format origin=Debian,codename=${distro_codename},label=Debian-Security und benötigt zwei Einträge, da Debian-Security-Updates aus zwei Quellen kommen. Ubuntu verwendet historisch Allowed-Origins mit dem Format ${distro_id}:${distro_codename}-security. Beide Schlüssel funktionieren auf beiden Systemen, aber beim Kopieren von Konfigurationen zwischen Systemen musst du prüfen, ob die Origins auf tatsächlich vorhandene Quellen zeigen.
Was ist der Unterschied zwischen 20auto-upgrades und 50unattended-upgrades?
20auto-upgrades ist die Schaltzentrale: Sie aktiviert (1) oder deaktiviert (0) die Funktion und legt die Frequenz fest. 50unattended-upgrades – bzw. deine lokale 52unattended-upgrades-local – definiert das Was und Wie: welche Paketquellen, welche Pakete ausschließen, wann Reboot, wohin E-Mail. Beide Dateien zusammen bilden die vollständige Konfiguration.
Kann ich unattended-upgrades auf einem Produktivserver mit Datenbank betreiben?
Ja, aber Datenbankpakete (mysql-server, postgresql, mariadb-server) und Reverse-Proxy-Pakete (nginx$, haproxy) sollten in die Package-Blacklist aufgenommen werden. Diese Updates erfordern oft Konfigurationsänderungen, Schemamigration oder geplante Downtime und dürfen nicht unbeaufsichtigt eingespielt werden. Sicherheitsupdates für diese Pakete spielst du dann manuell in einem definierten Wartungsfenster ein.
Wie stelle ich sicher, dass Reboots nur im Wartungsfenster stattfinden?
Setze Automatic-Reboot-Time auf die gewünschte Uhrzeit (z. B. "03:00") und lege den systemd-Timer apt-daily-upgrade.timer per Override auf denselben Zeitraum (OnCalendar=03:00, RandomizedDelaySec=0). So werden Updates zur definierten Zeit eingespielt, und falls nötig, findet der Reboot direkt danach statt. Das RandomizedDelaySec=0 ist dabei entscheidend.
Was passiert, wenn ein Update fehlschlägt?
Das System bleibt konsistent, da unattended-upgrades auf APT basiert – ein fehlgeschlagenes Update wird nicht halb eingespielt. Alle Aktionen werden in /var/log/unattended-upgrades/unattended-upgrades.log protokolliert. Bei konfigurierter Mail-Adresse mit MailReport "only-on-error" erhältst du eine E-Mail. Mit --dry-run simulierst du jederzeit, was installiert werden würde.
Wie teste ich die Konfiguration ohne echte Updates einzuspielen?
sudo unattended-upgrade --dry-run --debug gibt ausführliche Ausgabe über erkannte Updates, angewandte Origins-Pattern und Blacklist-Treffer, ohne Pakete zu verändern. Die Ausgabe erscheint im Terminal und wird ins Logfile geschrieben. Das ist die wichtigste Debugging-Methode nach jeder Konfigurationsänderung.
Fazit
Mit unattended-upgrades richtig konfiguriert hast du eine solide, automatische Sicherheits-Patch-Strategie für Linux-Server – vergleichbar mit dem, was WSUS für Windows-Umgebungen leistet. Der entscheidende Mehrwert liegt in der Kombination: Security-Only-Origins verhindern ungewollte Funktionsupdates, die Package-Blacklist schützt heikle Dienste vor unkontrollierten Upgrades, das definierte Wartungsfenster sorgt für Vorhersagbarkeit, und E-Mail-Benachrichtigungen stellen sicher, dass Fehler nicht unbemerkt bleiben. Regelmäßige Log-Kontrolle mit grep -i error /var/log/unattended-upgrades/unattended-upgrades.log schließt die Kontrollschleife.
Für eine umfassende Serverhärtung empfiehlt sich, unattended-upgrades in Kombination mit einer Firewall-Konfiguration und Intrusion Prevention einzusetzen – die Anleitung Linux-Server absichern mit UFW und Fail2ban zeigt den nächsten Schritt. Außerdem lohnt sich die Lektüre zur Paketverwaltung mit apt und dpkg, um den APT-Unterbau besser zu verstehen.
Weiterführende Anleitungen und Quellen
- Linux-Server absichern mit UFW und Fail2ban
- Paketverwaltung mit apt und dpkg unter Debian/Ubuntu
- Logs lesen und auswerten: journalctl und /var/log
- systemd-Services erstellen und verwalten
Offizielle Quellen: Ubuntu Server Dokumentation: Automatic Updates | Debian Wiki: PeriodicUpdates | Debian Manpage: unattended-upgrades(8)