systemd Archives - credativ®

Mit Version 256 hat systemd run0 eingeführt. Lennart Poettering beschreibt run0 als Alternative zu sudo und erklärt auf Mastodon zugleich, was in seinen Augen das Problem mit sudo ist.

In diesem Blogeintrag wollen wir aber nicht auf die Stärken oder Schwächen von sudo eingehen, sondern uns run0 einmal etwas genauer anschauen und es als sudo-Alternative verwenden.

Anders als sudo verwendet run0 weder die Konfigurationsdatei /etc/sudoers, noch ein SUID-Bit zur Erweiterung der User-Berechtigungen. Im Hintergrund nutzt es systemd-run zum Start neuer Prozesse, welches bereits seit einigen Jahren in systemd zu finden ist.

PolKit kommt zum Einsatz, wenn es darum geht zu prüfen, ob ein User auch entsprechende Berechtigungen besitzt, run0 zu verwenden. Hierbei können alle Regeln verwendet werden, die die Konfiguration von PolKit hergeben. In unserem Beispiel werden wir uns auf eine einfache Variante konzentrieren.

Versuchsaufbau

Für unser Beispiel verwenden wir eine t2.micro EC2-Instanz mit Debian Bookworm. Da run0 erst in systemd Version 256 Einzug gehalten hat und Debian Bookworm zum aktuellen Zeitpunkt noch mit Version 252 ausgeliefert wird, müssen wir zunächst das Debian Testing Repository hinzufügen.

❯ ssh admin@2a05:d014:ac8:7e00:c4f4:af36:3938:206e
…

admin@ip-172-31-15-135:~$ sudo su -

root@ip-172-31-15-135:~# cat < /etc/apt/sources.list.d/testing.list
> deb https://deb.debian.org/debian testing main
> EOF

root@ip-172-31-15-135:~# apt update
Get:1 file:/etc/apt/mirrors/debian.list Mirrorlist [38 B]
Get:5 file:/etc/apt/mirrors/debian-security.list Mirrorlist [47 B]
Get:7 https://deb.debian.org/debian testing InRelease [169 kB]
Get:2 https://cdn-aws.deb.debian.org/debian bookworm InRelease [151 kB]
…
Fetched 41.3 MB in 6s (6791 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
299 packages can be upgraded. Run 'apt list --upgradable' to see them.

root@ip-172-31-15-135:~# apt-cache policy systemd
systemd:
Installed: 252.17-1~deb12u1
Candidate: 256.1-2
Version table:
256.1-2 500
500 https://deb.debian.org/debian testing/main amd64 Packages
254.5-1~bpo12+3 100
100 mirror+file:/etc/apt/mirrors/debian.list bookworm-backports/main amd64 Packages
252.22-1~deb12u1 500
500 mirror+file:/etc/apt/mirrors/debian.list bookworm/main amd64 Packages
*** 252.17-1~deb12u1 100
100 /var/lib/dpkg/status
root@ip-172-31-15-135:~# apt-get install systemd
…

root@ip-172-31-15-135:~# dpkg -l | grep systemd
ii libnss-resolve:amd64 256.1-2 amd64 nss module to resolve names via systemd-resolved
ii libpam-systemd:amd64 256.1-2 amd64 system and service manager - PAM module
ii libsystemd-shared:amd64 256.1-2 amd64 systemd shared private library
ii libsystemd0:amd64 256.1-2 amd64 systemd utility library
ii systemd 256.1-2 amd64 system and service manager
ii systemd-cryptsetup 256.1-2 amd64 Provides cryptsetup, integritysetup and veritysetup utilities
ii systemd-resolved 256.1-2 amd64 systemd DNS resolver
ii systemd-sysv 256.1-2 amd64 system and service manager - SysV compatibility symlinks
ii systemd-timesyncd 256.1-2 amd64 minimalistic service to synchronize local time with NTP servers

root@ip-172-31-15-135:~# reboot
…

Zum initialen Login wird der User admin verwendet. Dieser User wurde durch cloud-init bereits in der Datei /etc/sudoers.d/90-cloud-init-users hinterlegt und darf demnach ohne Passwortabfrage beliebige sudo-Kommandos ausführen.

sudo cat /etc/sudoers.d/90-cloud-init-users
# Created by cloud-init v. 22.4.2 on Thu, 27 Jun 2024 09:22:48 +0000

# User rules for admin
admin ALL=(ALL) NOPASSWD:ALL

Analog zu sudo wollen wir nun run0 für den User admin freischalten.

Ohne weitere Konfiguration erhält der User admin einen Login-Prompt, bei dem er nach dem root-Passwort gefragt wird. Dabei handelt es sich um das Standardverhalten von PolKit.

admin@ip-172-31-15-135:~$ run0 ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ==== Authentication is required to manage system services or other units. Authenticating as: Debian (admin) Password:

Da dies nicht dem von uns gewünschten Verhalten entspricht, müssen wir in Form einer PolKit-Regel ein wenig nachhelfen. Zusätzliche PolKit Regeln werden unter /etc/polkit-1/rules.d/ abgelegt.

root@ip-172-31-15-135:~# cat < /etc/polkit-1/rules.d/99-run0.rules
polkit.addRule(function(action, subject) {
  if (action.id = "org.freedesktop.systemd1.manage-units") {
    if (subject.user === "admin") {
      return polkit.Result.YES;
    }
  }
});
> EOF

Die verwendete Regel ist dabei wie folgt aufgebaut: Zunächst wird überprüft, ob es sich bei der aufgeführten action um org.freedesktop.systemd1.manage-units handelt. Ist das der Fall, wird geprüft, ob es sich bei dem ausführenden User um den User admin handelt. Sind beide Voraussetzungen erfüllt, gibt unsere Regel „YES“ zurück, was bedeutet, dass keine weitere Prüfung (z.B. Passwortabfrage) nötig ist.

Alternativ hierzu könnte auch geprüft werden, ob der ausführende User einer bestimmten Gruppe angehört, wie z.B. admin oder sudo (if (subject.isInGroup("admin")). Auch wäre es denkbar, den Benutzer nach seinem eigenen Passwort zu fragen anstelle des root-Passworts.

Die neue Regel wird von PolKit automatisch eingelesen und kann sofort verwendet werden. Via journalctl -u polkit kann geprüft werden, ob es etwaige Fehler beim Einlesen der neuen Regeln gab. Nach der Konfiguration von PolKit darf der User admin nun analog zu unserer initialen sudo-Konfiguration run0 ausführen.

Prozessaufbau

Im nachfolgenden Listing wird ersichtlich, worin der Unterschied des Call-Stacks zwischen sudo und run0 liegt. Während im Falle von sudo jeweils eigene Child-Prozesse gestartet werden, startet run0 einen neuen Prozess via systemd-run.

root@ip-172-31-15-135:~# sudo su -
root@ip-172-31-15-135:~# ps fo tty,ruser,ppid,pid,sess,cmd
TT       RUSER       PPID     PID    SESS CMD
pts/2    admin       1484    1514    1484 sudo su -
pts/0    admin       1514    1515    1515  \_ sudo su -
pts/0    root        1515    1516    1515      \_ su -
pts/0    root        1516    1517    1515          \_ -bash
pts/0    root        1517    1522    1515              \_ ps fo tty,ruser,ppid,pid,sess,cmd
admin@ip-172-31-15-135:~$ run0
root@ip-172-31-15-135:/home/admin# ps fo tty,ruser,ppid,pid,sess,cmd
TT       RUSER       PPID     PID    SESS CMD
pts/0    root           1    1562    1562 -/bin/bash
pts/0    root        1562    1567    1562  \_ ps fo tty,ruser,ppid,pid,sess,cmd

Fazit und Anmerkung

Wie das oben stehende Beispiel gezeigt hat, kann run0 generell als einfache sudo-Alternative verwendet werden und bietet dabei einige sicherheitsrelevante Vorteile. Falls run0 sich gegenüber sudo durchsetzt, wird dies allerdings nicht innerhalb des nächsten Jahres geschehen. Einigen Distributionen fehlt stand jetzt schlicht eine ausreichend aktuelle systemd-Version. Hinzukommt, dass die Konfiguration von PolKit für einige Admins nicht zu den täglichen Aufgaben gehört und hier erst Know-How aufgebaut werden muss, um etwaige vorhandene sudo-„Konstrukte“ zu überführen.

Zudem sollte ein entscheidender Vorteil von run0 nicht außen vor bleiben: Standardmäßig färbt es den Hintergrund rot! 😉