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
. 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
. 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.