TokkNet

Veraltetes Arch-Linux Updaten

wenn Paketsignaturen nicht validiert werden können
Tokk 131 Wörter ~1 Min.

Privat nutze ich auf meinem Laptop Arch Linux. Derzeit ist der Laptop allerdings nicht viel in Verwendung, da ich mich meist an den PC setze um zu arbeiten. Dies führt dazu, das Systemupdates, derer es bei einer Rolling-Release-Distribution ja nicht gereade wenige gibt, ein wenig mehr hinterherhängen als sie eigentlich sollten.
Dies kann dann dazu führen, dass beim Update folgende Fehlermeldungen erscheinen:

Fehler: <Paketname>: signature from "Mr. Maintainer maintainer@archlinux.org" is unknown trust
:: Datei /var/cache/pacman/pkg/paket-version-x86_64.pkg.tar.zst ist beschädigt (Ungültiges oder beschädigtes Paket (PGP-Signatur)).
Soll die Datei entfernt werden? [J/n]

Dies liegt dann zumeist am veralteten archlinux-keyring, der zum verifizieren der Pakete verwendet wird und nicht alle aktuellen Schlüssel enthält.
Die Lösung ist einfach, zunächst muss das Paket mittels

pacman -S archlinux-keyring

upgedatet werden, dann kann das Systemupdate wieder wie gewohnt durchgeführt werden.

Mailcow Backup Mit Systemd Timern

Tokk 551 Wörter ~3 Min.

Ein elementarer Teil der Betriebssicherheit eines IT-Systems ist die Datensicherung. Spätestens wenn man Dienste auch Freunden und Familie zur Verfügung stellt ist die Sicherung ein Muss. Wem seine eigenen Daten lieb sind, sollte sich natürlich auch schon vorher damit beschäftigen. Ein Mailserver ist hier ein Paradebeispiel, der Grundgedanke sollte aber auf alle anderen Dienste übertragen werden.

Die Mailcow-Dokumentation zur Datensicherung ist ein guter Einstiegspunkt, beschäftigt sich allerdings nur mit der periodischen Ausführung mittels cron. Auf meinem Server habe ich kein Cron installiert, da ich im laufe der Zeit die Vorteile von Systemd-Timern schätzen gelernt habe.

Einrichtung

Zunächst erstellen wir einen Systemd-Service, der beim Starten ein Backup von Mailcow erstellt und sich dann wieder beendet. Hierzu legen wir die Datei /etc/systemd/system/mailcowBackup.service mit folgendem Inhalt an:

[Unit]
Description=Mailcow Backup

[Service]
Type=oneshot
Environment="MAILCOW_BACKUP_LOCATION=/opt/backup"
ExecStart=/opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all --delete-days 5

[Install]
WantedBy=multi-user.target

Type=oneshot bedeutet hierbei, dass es sich um einen Prozess handlet der gestartet wird und sich nach getaner Arbeit beendet - das ist wichtig, das Backup soll ja nicht direkt wieder gestartet werden. Die Environment-Variable MAILCOW_BACKUP_LOCATION steuert den Ausgabepfad des fertigen Backups, daher muss diese Variable natürlich gesetzt und entsprechend angepasst werden

Sobald diese Service-Unit existiert kann der Backup-Prozess mittels systemctl start mailcowBackup.service jederzeit manuell gestartet werden.

Die Ausgabe des Backup-Skriptes wird im Systemlog erfasst und kann daher über systemctl status mailcowBackup.service und journalctl -f -u mailcowBackup.service eingesehen werden.

[user@server]$ sudo systemctl status mailcowBackup.service
○ mailcowBackup.service - Mailcow Backup
     Loaded: loaded (/etc/systemd/system/mailcowBackup.service; disabled; preset: disabled)
     Active: inactive (dead)

Aug 07 07:32:16 mailcow.url backup_and_restore.sh[14066]: /backup_mariadb/ib_buffer_pool
Aug 07 07:32:16 mailcow.url backup_and_restore.sh[14066]: /backup_mariadb/aria_log.00000001
Aug 07 07:32:16 mailcow.url backup_and_restore.sh[14066]: /backup_mariadb/aria_log_control
Aug 07 07:32:16 mailcow.url backup_and_restore.sh[14066]: /backup_mariadb/xtrabackup_checkpoints
Aug 07 07:32:16 mailcow.url backup_and_restore.sh[14066]: /backup_mariadb/backup-my.cnf
Aug 07 07:32:16 mailcow.url backup_and_restore.sh[14066]: /backup_mariadb/xtrabackup_info
Aug 07 07:32:16 mailcow.url backup_and_restore.sh[14066]: /backup_mariadb/xtrabackup_binlog_pos_innodb
Aug 07 07:32:16 mailcow.url systemd[1]: mailcowBackup.service: Deactivated successfully.
Aug 07 07:32:16 mailcow.url systemd[1]: Finished Mailcow Backup.
Aug 07 07:32:16 mailcow.url systemd[1]: mailcowBackup.service: Consumed 1.056s CPU time, 14.1M memory peak.sudo 

Periodische Ausführung mittels Timer

Der nächste Schritt ist die Anlage eines Timers, der die neu angelegte Unit zu definierten Zeitpunkten startet.
Hierzu legen wir die Datei /etc/systemd/system/mailcowBackup.timer wie folgt an:

[Unit]
Description=Starts the Mailcow Backup every night
Requires=mailcowBackup.service

[Timer]
Unit=mailcowBackup.service
OnCalendar=*-*-* 00:30:00
[Install]
WantedBy=timers.target 

Wichtig ist hier neben der Angabe der entsprechenden Service-Unit die Zeile OnCalendar=*-*-* 00:30:00, die besagt, dass der Timer An jedem Tag jeden Monats jeden Jahres um 00:30 aktiv werden soll. Der Timer muss abschließend noch aktiviert und gestartet werden. Dies erfolgt analog zu Service Units: systemctl enable --now mailcowBackup.timer.
Mittels systemctl list-timers können aktive Timer eingesehen werden. Der Befehl zeigt eine Auflistung aller Timer inklusive dem absoluten und relativen Zeitpunkt der nächsten sowie vorherigen Ausführung.

[tokk@mx-web backup]$ systemctl list-timers
NEXT                            LEFT LAST                              PASSED UNIT                             ACTIVATES
[...]
Thu 2024-08-08 00:30:00 UTC      16h -                                      - mailcowBackup.timer              mailcowBackup.service
Wed 2024-08-14 07:05:57 UTC   6 days Wed 2024-08-07 07:05:57 UTC    33min ago certbot-renewal.timer            certbot-renewal.service
[...]

Auch hier landet die Ausgabe des Backups im System-Log und kann via journalctl eingesehen werden. Die komplette Ausgabe der tagesaktuellen Sicherung lasen sich zum Beispiel mittels journalctl -S today -u mailcowBackup.service anzeigen.

Weiterführende Gedanken

Nach der Einrichtung des Timers wird jede Nacht ein Backup unter dem spezifizierten Pfad angelegt. Sollte die Festplatte des Servers oder der ganze Server jedoch ausfallen ist dadurch jedoch nicht nur Mailcow betroffen, sondern auch das Backup.
Daher ist es dringend notwendig, die Backups automatisiert noch anderweitig abzulegen.

YaST2 Angeblich Ohne Root Rechte

trotz ausführung als User root
Tokk EN 316 Wörter ~2 Min.

Von Zeit zu Zeit habe ich das zweifelhafte Vergnügen, mit SLES-Systemen arbeiten zu dürfen. Dabei muss natürlich auch mit yast bzw. yast2 interagiert werden, um das System und einige Dienste zu konfigurieren. Von der Philosophie, die eigentlichen Konfigurationsdateien hinter einer GUI zu verstecken kann man halten was man will, ich halte davon nichts - aber das nur am Rande.

Bei meinem letzten Ausflug in die Welt dieser Enterprise Distribution ist mir dann ein kurioser Fehler aufgefallen. Ich habe mich in das System eingeloggt, meinen Benutzerkontext auf root geändert und YaST2 gestartet. Dabei wurde ich von folgender Meldung begrüßt:

YaST2 Control Center is not running as root.
You will only see modules which do not require root privileges.

Mit meiner Anmeldung war aber alles in Ordnung, wie ein kurzer Check ergab:

$# whoami
root

Nach einigem Googeln fand ich dann mehrere Threads, die mit dem gleichen Problem zu kämpfen hatten. Anscheinend tritt die Fehlermeldung relativ häufig und bei einer Vielzahl von Problemen auf. Es könnte daran liegen, dass zu wenig RAM zur Verfügung steht - aber das war bei mir nicht das Problem.
In einem anderen Thread hatte ein Benutzer ebenfalls das obige Problem, hier lag es an einem fehlenden Logverzeichnis /var/log/YaST2.
Bei mir war das Verzeichnis zwar vorhanden, aber der Thread brachte mich auf die richtige Spur - offensichtlich tritt der Fehler auf, wenn YaST2 keine Logdateien schreiben kann. Ein Check mit df -h ergab eine Festplattenauslastung von 100% - damit konnten natürlich auch keine Dateien geschrieben werden. Nach einer Bereinigung der Festplatte konnte YaST2 wieder normal ausgeführt werden.
Ob es in diesem speziellen Fall daran liegt, dass keine Logfiles geschrieben werden konnten oder ob eine volle Festplatte auch andere Probleme mit sich bringt, kann ich natürlich nicht mit Sicherheit sagen, da keine Logfiles geschrieben wurden.

Zusammenfassend kann man sagen, dass die obige Meldung relativ generisch zu sein scheint und nicht unbedingt auf fehlende Rechte hinweist.

Passwortlogin über SSH unter Ubuntu deaktivieren

Oder: Warum Sicherheitseinstellungen immer getestet werden müssen
Tokk EN 207 Wörter ~1 Min.

Eine der ersten Dinge, die ich bei einem neuen Server immer anpasse ist die sshd_config, der Login über SSH mittels Passwort wird deaktiviert:

PubkeyAuthentication yes
ChallengeResponseAuthentication no
PasswordAuthentication no
PermitEmptyPasswords no
KbdInteractiveAuthentication no
UsePAM no

Normalerweise geht man davon aus, das die Einträge funktionieren. Meist testet man den Login dann vom eigenen PC aus und stellt zufrieden die Verwendung des Zertifikates fest.

Cloud Init

Natürlich wird Ubuntu aber heutzutage mit Cloud-Init ausgeliefert und seit Ubuntu 20.04 bringt dies direkt eine neue Config-Datei namens /etc/ssh/sshd_config.d/50-cloud-init.conf mit, die eine einzige Zeile enthält:

PasswordAuthentication yes

Da das Einbinden des Verzeichnisses sshd_config.d sehr weit oben in der sshd_config stattfindet, ist dies fast immer das erste Vorkommen der PasswordAuthentication Direktive. Das bedeutet, dass der hier angegebene Wert erhalten bleibt und die Passwortauthentifizierung trotz aller anderen Einstellungen aktiviert bleibt.
Um die Möglichkeit, sich mit einem Passwort anzumelden, vollständig zu deaktivieren, muss diese Datei daher gelöscht oder bearbeitet werden. Da diese Datei jedoch nur einem Zweck dient, kann sie mit gutem Gewissen gelöscht werden.

Abschließende Bemerkungen

  1. Dieser Sachverhalt zeigt deutlich, dass Sicherheitseinstellungen immer getestet werden müssen, egal wie sorgfältig man die Konfiguration durchführt, und zwar auch aus der Sicht eines externen Kontextes, in diesem Fall die Anmeldung ohne eigenes Zertifikat zu erzwingen.
  2. WTF Canonical?

Unpriviligertes Binding an priviligierte Ports

Ports unter 1024 an User-Prozesse binden
Tokk EN 167 Wörter ~1 Min.

Normalerweise erlaubt es der Linux-Kernel nicht, dass sich unprivilegierte Prozesse an Ports unter 1024 binden. Daher laufen die meisten (Web-) Server-Prozesse als root. Sicherheitstechnisch ist es natürlich nicht ideal, das gerade die Prozesse, welche sich um die Bearbeitung von Anfragen aus dem Internet kümmern umfassende Rechte haben, da dies im Falle einer feindlichen Übernahme des Prozesses natürlich auch direkt zu Root-Rechten auf dem ganzen Systems führt.
An dieser Stelle bietet Systemd jedoch die Möglichkeit, unserem Service die Bindung an die Ports zu erlauben, in dem man dem entsprechenden Prozess per AmbientCapabilities =CAP_NET_BIND_SERVICE die Berechtigung erteilt, sich an die Ports unter 1024 zu binden. Eine Übersicht über alle anderen erteilbaren Berechtigungen gibt es zum Beispiel in der Linux Man Page zu den Capabilities.

Bei der Gelegenheit kann man direkt noch per CapabilityBoundingSet=CAP_NET_BIND_SERVICE einschränken, das der Service nur diese Berechtigung bekommen darf und keine anderweitigen bekommen kann Die Unit-Datei sollte dann so aussehen:

[Service]
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE

Am besten kann man solche Änderungen als Drop-In in einer eigenen Override-Datei anlegen.