Product SiteDocumentation Site

9.2. Benutzer und Gruppen für Software-Daemons erstellen

Wenn Ihre Software als Daemon läuft, der keine Root-Rechte benötigt, müssen Sie für ihn einen Benutzer erstellen. Es gibt zwei Arten von Benutzern in Debian, die für Pakete verwendet werden können: statische UIDs (werden von base-passwd vergeben, eine Liste der statischen Benutzern in Debian finden Sie bei Abschnitt 12.1.1.12, „Benutzer und Gruppen des Betriebssystems“) und dynamisches UIDs, die in einem zugewiesenen Bereich liegen.
Im ersten Fall müssen Sie mit base-passwd eine Benutzer- oder Gruppen-ID erstellen. Wenn der Benutzer verfügbar ist, muss das Paket, das Sie anbieten möchten, eine Abhängigkeit vom Paket base-passwd enthalten.
Im zweiten Fall müssen Sie den Systembenutzer entweder preinst oder postinst erstellen und dafür sorgen, dass das Paket von adduser (>= 3.11) abhängt.
Im folgenden Programmbeispiel soll gezeigt werden, wie der Benutzer oder Gruppe, mit deren Rechten der Daemon laufen wird, bei der Installation oder Aktualisierung des Pakets erstellt wird.
[...]
case "$1" in
  install|upgrade)

  # If the package has default file it could be sourced, so that
  # the local admin can overwrite the defaults

  [ -f "/etc/default/packagename" ] && . /etc/default/packagename

  # Sane defaults:

  [ -z "$SERVER_HOME" ] && SERVER_HOME=server_dir
  [ -z "$SERVER_USER" ] && SERVER_USER=server_user
  [ -z "$SERVER_NAME" ] && SERVER_NAME="Server description"
  [ -z "$SERVER_GROUP" ] && SERVER_GROUP=server_group

  # Groups that the user will be added to, if undefined, then none.
  ADDGROUP=""

  # create user to avoid running server as root
  # 1. create group if not existing
  if ! getent group | grep -q "^$SERVER_GROUP:" ; then
     echo -n "Adding group $SERVER_GROUP.."
     addgroup --quiet --system $SERVER_GROUP 2>/dev/null ||true
     echo "..done"
  fi
  # 2. create homedir if not existing
  test -d $SERVER_HOME || mkdir $SERVER_HOME
  # 3. create user if not existing
  if ! getent passwd | grep -q "^$SERVER_USER:"; then
    echo -n "Adding system user $SERVER_USER.."
    adduser --quiet \
            --system \
            --ingroup $SERVER_GROUP \
            --no-create-home \
            --disabled-password \
            $SERVER_USER 2>/dev/null || true
    echo "..done"
  fi
  # 4. adjust passwd entry
  usermod -c "$SERVER_NAME" \
          -d $SERVER_HOME   \
          -g $SERVER_GROUP  \
             $SERVER_USER
  # 5. adjust file and directory permissions
  if ! dpkg-statoverride --list $SERVER_HOME >/dev/null
  then
      chown -R $SERVER_USER:adm $SERVER_HOME
      chmod u=rwx,g=rxs,o= $SERVER_HOME
  fi
  # 6. Add the user to the ADDGROUP group
  if test -n $ADDGROUP
  then
      if ! groups $SERVER_USER | cut -d: -f2 | \
         grep -qw $ADDGROUP; then
           adduser $SERVER_USER $ADDGROUP
      fi
  fi
  ;;
  configure)

[...]
Außerdem müssen Sie für das init.d-Skript sicherstellen,
  • dass der Daemon beim Starten seine Rechte ablegt: Wenn die Software nicht selbst den setuid(2) oder seteuid(2) Aufruf absetzt, sollten Sie die Option --chuid für start-stop-daemon verwenden.
  • dass der Daemon nur angehalten wird, wenn die Benutzer-IDs übereinstimmen. Dafür ist die Option --user von start-stop-daemon hilfreich.
  • dass der Daemon nicht gestartet wird, wenn sein Benutzer oder Gruppe nicht existiert:
      if ! getent passwd | grep -q "^server_user:"; then
         echo "Server user does not exist. Aborting" >&2
         exit 1
      fi
      if ! getent group | grep -q "^server_group:" ; then
         echo "Server group does not exist. Aborting" >&2
         exit 1
      fi
Wenn das Paket einen Systembenutzer erstellt, kann er wieder in postrm entfernt werden, wenn das Paket vollständig gelöscht wird (purge). Dabei gibt es allerdings einen Nachteil. Zum Beispiel werden Dateien, die von dem Benutzer des Daemons erstellt wurden, benutzerlos und können später einem neuen Benutzer gehören, dem die gleiche UID zugewiesen wurde [67]. Daher ist nicht zwingend notwendig, dass Benutzer beim vollständigen Löschen eines Pakets entfernt werden. Dies hängt vielmehr vom jeweiligen Paket ab. Im Zweifelsfall sollte der Administrator gefragt werden (mit debconf), was passieren soll, wenn ein Paket gelöscht wird.
Maintainers that want to remove users in their postrm scripts are referred to the deluser/deluser --system option.
Wenn ein Programm unter einem Benutzer mit beschränkten Rechten läuft, wird sichergestellt, dass Sicherheitsprobleme nicht das gesamte System beschädigen können. Dieses Vorgehen beachtet auch das Prinzip der geringst möglichen Privilegien. Denken Sie daran, dass Sie die Rechte eines Programms auch noch durch andere Methoden als beschränkte Benutzerrechte weiter einschränken können [68]. Weitere Informationen finden Sie im Abschnitt http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/minimize-privileges.html des Buchs Secure Programming for Linux and Unix HOWTO.


[68] Sie können sogar eine SELinux-Richtlinie erstellen.