Product SiteDocumentation Site

9.2. Création d'utilisateurs et de groupes pour les démons logiciels

Si le logiciel exécute un démon qui n'a pas besoin des droits du superutilisateur, vous devez lui créer un utilisateur. Deux types d'utilisateurs Debian peuvent être utilisés par les paquets : avec identifiant (UID) statique (attribué par base-passwd ; consultez Section 12.1.1.12, « Les utilisateurs et les groupes du système d'exploitation » pour une liste des utilisateurs statiques dans Debian) et avec identifiant dynamique dans l'intervalle dévolu aux utilisateurs système.
Dans le premier cas, il faut demander un identifiant de groupe ou d'utilisateur à base-passwd. Une fois l'utilisateur disponible, le paquet doit être distribué avec une dépendance sur la version adéquate du paquet base-passwd.
Dans le second cas, il faut créer un utilisateur système en preinst ou en postinst et rendre le paquet dépendant de adduser (>= 3.11).
L'exemple de code suivant crée les utilisateur et groupe utilisés par le démon pour s'exécuter quand le paquet est installé ou mis à niveau :
[...]
case "$1" in
  install|upgrade)

  # Si le paquet a un fichier « default » permettant à
  # l'administrateur local d'écraser les valeurs par défaut

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

  # Valeurs par défaut correctes :

  [ -z "$SERVER_HOME" ] && SERVER_HOME=rép_serveur
  [ -z "$SERVER_USER" ] && SERVER_USER=utilisateur_serveur
  [ -z "$SERVER_NAME" ] && SERVER_NAME="Description du serveur"
  [ -z "$SERVER_GROUP" ] && SERVER_GROUP=groupe_serveur

  # Groupes auxquels l'utilisateur sera ajouté ; aucun si non défini.
  ADDGROUP=""

  # créer un utilisateur pour éviter d'exécuter le serveur en tant
  # que superutilisateur
  # 1. Créer le groupe s'il n'existe pas
  if ! getent group | grep -q "^$SERVER_GROUP:" ; then
     echo -n "Ajout du groupe $SERVER_GROUP.."
     addgroup --quiet --system $SERVER_GROUP 2>/dev/null ||true
     echo "fait"
  fi
  # 2. Créer un répertoire personnel s'il n'existe pas
  test -d $SERVER_HOME || mkdir $SERVER_HOME
  # 3. Créer un utilisateur s'il n'existe pas
  if ! getent passwd | grep -q "^$SERVER_USER:"; then
    echo -n "Ajout de l'utilisateur système $SERVER_USER.."
    adduser --quiet \
            --system \
            --ingroup $SERVER_GROUP \
            --no-create-home \
            --disabled-password \
            $SERVER_USER 2>/dev/null || true
    echo "fait"
  fi
  # 4. Ajuster l'entrée de mot de passe
  usermod -c "$SERVER_NAME" \
          -d $SERVER_HOME   \
          -g $SERVER_GROUP  \
             $SERVER_USER
  # 5. Ajuster les droits des fichiers et répertoires
  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. Ajouter l'utilisateur au groupe ADDGROUP
  if test -n $ADDGROUP
  then
      if ! groups $SERVER_USER | cut -d: -f2 | \
         grep -qw $ADDGROUP; then
           adduser $SERVER_USER $ADDGROUP
      fi
  fi
  ;;
  configure)

[...]
Assurez-vous que le fichier de script init.d :
  • démarre le démon en abandonnant les droits du superutilisateur : si le logiciel ne fait pas l'appel setuid(2) ou seteuid(2) lui-même, l'option --chuid de start-stop-daemon est utilisable.
  • n'arrête le démon que si l'identifiant utilisateur correspond, l'option --user de start-stop-daemon permet de faire cela.
  • ne s'exécute pas si l'utilisateur ou le groupe n'existent pas :
      if ! getent passwd | grep -q "^utilisateur_serveur:"; then
         echo "L'utilisateur du serveur n'existe pas. Abandon" >&2
         exit 1
      fi
      if ! getent group | grep -q "^groupe_serveur:" ; then
         echo "Le groupe du serveur n'existe pas. Abandon" >&2
         exit 1
      fi
Si le paquet crée l'utilisateur système, il peut le retirer lors de la purge en postrm. Cela a cependant quelques inconvénients. Par exemple les fichiers créés par cet utilisateur seront orphelins et pourraient être repris par un nouvel utilisateur système plus tard si le même identifiant utilisateur lui est attribué[68]. Par conséquent, retirer les utilisateurs système lors de la purge n'est pas encore obligatoire et dépend des besoins du paquet. En cas de doute, cette action pourrait être faite en demandant à l'administrateur sa préfèrence lors du retrait du paquet (c'est-à-dire avec debconf).
Les responsables qui souhaitent supprimer des utilisateurs dans leurs scripts postrm sont renvoyés à l'option deluser/deluser --system.
L'exécution de programmes avec un utilisateur ayant des droits restreints assure qu'aucun problème de sécurité ne pourra endommager tout le système. Cela suit aussi le principe du minimum de droits. Songez aussi à limiter les droits dans les programmes avec d'autres mécanismes que l'exécution en tant que non superutilisateur[69]. Pour de plus amples renseignements, consultez le chapitre http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/minimize-privileges.html du livre HOWTO de programmation sécurisée pour Linux et UNIX.


[68] Plusieurs discussions à propos de ces inconvénients ont déjà eu lieu comme http://lists.debian.org/debian-mentors/2004/10/msg00338.html et http://lists.debian.org/debian-devel/2004/05/msg01156.html.
[69] Vous pouvez même fournir une politique SELinux pour cela.