Codics GmbH

Nextcloud und Podman: Updates automatisiert

Eine eigene Nextcloud als lokale Collaboration-Plattform zu betreiben, hat den entscheidenden Vorteil, dass alle Daten wirklich im eigenen Rechenzentrum auf einem selbstverwalteten Server verbleiben und nicht unkontrolliert in der Cloud herumschwirren – möglicherweise sogar in Drittländern. Für eine effizientere Wartung setzen auch in KMU immer mehr Admins auf die Container-Technologie, stehen dann aber vor der Herausforderung, dass Software (hier Nextcloud und MariaDB) regelmäßige Updates braucht. Nur so ist es möglich, Sicherheitslücken zu schließen und die Datensicherheit auch auf lange Sicht zu gewährleisten. Wir zeigen in diesem Blog-Beitrag, was Podman im Vergleich zu Docker kann und wie sich Updates damit effizient automatisieren lassen.

Quick Links
Vorteile
Podman vs. Docker
Auto-Updates von Containern
Plan Satz und Sieg
So geht’s
Updates einfach, automatisch oder manuell.

Was sind Container und welche Vorteile bieten sie auch für KMU?

Ein Container funktioniert wie ein in sich geschlossenes virtuelles Betriebssystem, in dem alles Notwendige vorhanden ist, damit eine Anwendung ausgeführt werden kann - darunter Programm- und Konfigurationsdateien, Bibliotheken etc.

In unserem Beispiel nutzen wir die auf docker.io/library bereitgestellten OCI1 nextcloud und mariadb.

Das geht schnell, und die Applikation kann auf diese Weise überall implementiert und ausgeführt werden – in einem Rechenzentrum genauso wie auf einem lokalen PC und unabhängig vom dort vorhandenen Betriebssystem. Dadurch dass Container keinen Betriebssystem-Kernel enthalten, beanspruchen sie im Vergleich zur Servervirtualisierung weniger Systemressourcen.

Dieser Zweiklang aus Portabilität und Ressourceneffizienz macht die Container-Technologie auch für KMU interessant, um Anwendungen schneller zu erstellen, zu testen und in unterschiedlichen Umgebungen bereitzustellen. Gleichzeitig ermöglichen Container eine klare Trennung der darin betriebenen Apps, Datenbanken oder Webservices – ein Plus für die Informationssicherheit und Business Continuity. Da Anwendungen in Containern immer auf dieselbe Art und Weise ausgeführt werden, egal wo sie implementiert sind, macht die Technologie ihre Wartung prinzipiell leichter. Den Kernel gibt bei Containern der Host vor. Bei uns stellt Fedora CoreOS sicher, dass der Host aktuell ist.

Auf der anderen Seite braucht jeder Container, der zur Verfügung gestellt wird, regelmäßige Updates und der möglicherweise damit verbundene Aufwand schreckt manch einen ab. Hier kommt der Container-Manager Podman im Zusammenhang mit systemd ins Spiel. Er bringt nützliche Mechanismen mit, um diesen Vorgang zu automatisieren – vorausgesetzt man berücksichtigt schon beim Setup einige Dinge.

Was kann Podman im Vergleich zu Docker?

Docker und Podman sind die Programme, die Container ausführen und damit erst nutzbar machen. Als Docker 2013 auf den Markt kam, war es das erste Containermanagement-System, mit dem sich im Handumdrehen Container erstellen und auf unterschiedliche Standorte verteilen ließen – vorher fristete die Container-Technologie eher ein Nischendasein. Daher galt Docker lange Zeit als die Laufzeitumgebung schlechthin. Die Open-Source-Firma RedHat hat Podman etwas später als Alternative zu Docker entwickelt, die – und das ist für uns der entscheidende Unterschied – daemonless arbeitet. Podman führt Container mit der Fork-Exec-Funktion als Unterprozess aus. Damit lässt sich jederzeit nachvollziehen, welcher Container von welchem User gestartet worden ist. Gleichzeitig kann man so sicherstellen, dass der Container ohne Root-Rechte läuft, was bei einer erfolgreichen Attacke den Vorteil hat, dass nur er betroffen ist. Hat ein Container Root-Rechte, können mögliche Angreifer auch auf den gesamten Rechner mit allen anderen Containern zugreifen.

Vor diesem Hintergrund ist Podman inzwischen für immer mehr Admins die erste Wahl, um Container zu erstellen und zu verwalten, zumal es auf Fedora Linux bereits vorinstalliert ist. Aber auch auf anderen Linux-Distributionen wie Debian, Ubuntu und CentOS lässt sich Podman mit wenigen Kommandos installieren (siehe unter podman.io 2).

Warum sind Auto-Updates von Containern so nützlich?

Jede Software, jedes Betriebssystem hat Sicherheitslücken, und sobald diese im Rahmen eines Patches bekannt werden, nutzen mehr Cyberkriminelle sie gezielt für ihre Zwecke. Regelmäßige proaktive Updates sind daher eine gute Möglichkeit, alle behobenen Schwachstellen zu eliminieren, bevor eine breite Öffentlichkeit Kenntnis davon gewinnt. Das gilt natürlich auch für jeden einzelnen Container und seinen Inhalt – in unserem Fall die Nextcloud und MariaDB.

Jedes Container-Update besteht aus drei Schritten: 1. das neue Container-Image ziehen, 2. die laufende Instanz stoppen und löschen und 3. den neuen Container starten. Das sind pro Container drei bis vier Kommandozeilen, und wer viele Container laufen hat, ist bei komplett manuellen Updates erstmal beschäftigt.

Auto-Updates mit Podman3 schlagen somit zwei Fliegen mit einer Klappe: Sie sparen Zeit und stellen sicher, dass alles auf dem neuesten Stand ist.

Wer gut plant, erspart sich Überraschungen im Nachhinein

Bei der im Folgenden beschriebenen Verwendung von systemd gibt es drei Wege, ein Update durchzuführen, sobald sich eine neuere Version auf docker.io/library befindet:

Es ist empfehlenswert zu planen, in welchen Releases automatische Updates möglich sein sollen – zum Beispiel 2.1 nach 2.2 oder 2.x nach 3.x. Wenn man mit dem „latest“-Tag arbeitet, werden auch größere Updates automatisiert ausgeführt.

Das Überspringen (1.x -> 3.x) von Major Updates ist in der Nextcloud nicht möglich. 4 Wird der Service regelmäßig neu gestartet, bzw. ein Update über einen Timer durchgeführt, sollte dies bei der beschriebenen Methode nicht vorkommen und es kann “latest” eingetragen werden.

Wir hatten uns zuerst für automatische Updates der Nextcloud innerhalb von Major-Releases 2.1 -> 2.2 entschieden, da dies das Risiko von Ausfällen des Service verringert. Für ein Major-Update wurde manuell die Version im Service File angepasst und der Service neugestartet. Da wir das Risiko mittlerweile gering einschätzen, überwiegt der Nutzen, immer auf der neuen Nextcloud zu sein. Nach jedem Update bietet es sich an, die Apps innerhalb der Nextcloud zu überprüfen.

So geht’s: Auto-Updates mit Podman

Um Auto-Updates mit Podman zu ermöglichen, müssen wir das Thema Aktualisierung schon beim Aufsetzen des Containers mitdenken und die notwendige Umgebung schaffen. Wir nutzen die Podman-Befehle zum Erzeugen der Systemd Service Dateien. Die Container werden beim Start der Services erzeugt und existieren nur so lange dieser läuft. Stoppt man einen Container mit “podman stop”, ist ein neuerlicher Start mit “podman start” folglich nicht mehr möglich.

Systemd Service Dateien:

Initiales Erzeugen der Systemd Service Dateien

Da die Inhalte des Containers flüchtig sind, gilt es festzulegen, welche Volumes gespeichert und auch nach Updates erhalten bleiben müssen – andernfalls würden die Daten in unserer Nextcloud verloren gehen (hierzu wird ein eigener Post folgen).

#!/bin/bash
set -e
set -x
set -u

CONTAINER=container_1
POD=pod_1
VOL=html

podman volume exists $VOL || podman volume create $VOL

podman pod exists $POD || podman pod create -n $POD \
  --network=slirp4netns:enable_ipv6=true,port_handler=slirp4netns \
  -p 8080:80 \
  --label "io.containers.autoupdate=registry"

podman container exists $CONTAINER || podman create --pod $POD \
  --name $CONTAINER \
  -v content_html:/usr/share/nginx/html:ro \
  --label "io.containers.autoupdate=registry" \
 docker.io/library/nginx:1-alpine

# generate service files
pushd $(mktemp -d)
podman generate systemd --new --name --files $POD
mkdir -p ~/.config/systemd/user/
rsync -av *.service ~/.config/systemd/user/
systemctl --user daemon-reload
popd

# remove pod and container
podman pod rm $POD

# enable and start pod-$POD, don't forget "loginctl enable-linger $USER"
systemctl --user enable --now pod-$POD.service
# manual auto update with
# podman auto-update
# timed auto update
systemctl --user enable --now podman-auto-update.timer

Updates einfach, automatisch oder manuell:

Unser Container und somit auch die Nextcloud wird aktualisiert, sobald eine neue Version auf docker.io/library verfügbar ist. Dabei wird je nach Setup einer der folgenden drei Wege automatisch oder manuell genutzt.

1a. Auto-Updates wenn Service oder System neugestartet wird (automatisch)
systemctl --user enable --now pod-nc.service

Wir verwenden als Hostsystem für unsere Container Fedora CoreOS.5 Das ist ein sich automatisch aktualisierendes, minimales, Container-fokussiertes Betriebssystem.

Alle paar Wochen wird automatisch ein neues Fedora CoreOS installiert und das System neu gestartet. Dabei werden auch die Service der Container neu gestartet und somit aktualisiert.

1b. Vorab geplante Auto-Updates (automatisch)

Zur manuellen Variante gibt es bei Podman auch die Möglichkeit, Auto-Updates über einen Timer zu planen, so dass zum Beispiel einmal pro Woche die gewünschten neuen Updates aufgespielt werden.

1c. Manuell gestartete Auto-Updates (manuell)

Indem man das Auto-Update manuell startet, behält man die Kontrolle, wie oft und wann genau aktualisiert werden muss. Das macht etwa Sinn, wenn Container nur in einem bestimmten Wartungsfenster oder am Wochenende upgedatet werden sollen und erfolgt über den Befehl

podman auto-update

Dies spart im Vergleich zur nicht automatisierten Variante immerhin drei Linux-Kommandos beim Update-Start ein.

systemctl --user enable podman-auto-update.timer

Wir verwenden neben dem Update bei den regelmäßigen Reboots zusätzlich die podman-auto-update timer. Somit lassen sich Probleme mit neuen Versionen der Container zeitnah erkennen und beheben. Wartet man bis zum Reboot des Systems, ist das Hostbetriebssystem aktualisiert und der Container.

2. Nacharbeiten (manuell)

Das Aktualisieren der Nextcloud beim Starten des neuen Containers wird weitgehend automatisch durchgeführt. Allerdings werden keine Operationen mit langer Laufzeit ausgeführt. Die Übersicht in der Verwaltung6 bietet einen guten Überblick, wenn ein Kommando manuell ausgeführt werden muss. Das betrifft z.B. das Aktualisieren der Datenbank.7

podman exec --user www-data -it nc_1 ./occ db:add-missing-columns
podman exec --user www-data -it nc_1 ./occ db:add-missing-indices
podman exec --user www-data -it nc_1 ./occ db:add-missing-primary-keys

Sie können die Option –dry-run verwenden, um die Datenbankabfragen auszugeben, anstatt sie auszuführen.