SSD Nodes Learn Hosting plans →
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-22

Exécuter un service avec un utilisateur non privilégié

Un service lancé en root peut donner un accès complet au serveur après une faille. Utilisez un compte dédié ou systemd avec DynamicUser pour limiter l’impact.

Pourquoi ne pas tout exécuter en tant que root

root peut tout faire sur la machine : lire chaque fichier, modifier n’importe quel paramètre et supprimer l’ensemble du système. Lorsque vous exécutez un service en tant que root, vous lui donnez tous ces privilèges. Si le service contient une faille qu’un attaquant peut exploiter, celui-ci ne prend pas seulement le contrôle du service : il obtient les privilèges root, c’est-à-dire le contrôle de tout le serveur. Exécuter un service avec un utilisateur non privilégié limite les dégâts. Une faille dans un service exécuté avec un compte limité ne donne à l’attaquant accès qu’à ce que ce compte peut modifier, ce qui devrait représenter presque rien.

C’est le principe du moindre privilège : accorder à chaque composant du système exactement les accès dont il a besoin pour fonctionner, et rien de plus. C’est la mesure la plus efficace pour limiter l’impact d’une compromission. Sur un serveur moderne, sa mise en œuvre coûte presque rien.

Un compte dédié par service

L’approche classique consiste à créer un utilisateur système distinct pour chaque service. Cet utilisateur possède uniquement les fichiers du service et ne peut pas ouvrir de session. Un compte système pour une application web peut se présenter ainsi :

sudo useradd --system --no-create-home --shell /usr/sbin/nologin appsvc

Chaque option a son importance. --system indique qu’il s’agit d’un compte de service, et non d’un compte destiné à une connexion humaine. --no-create-home évite de créer un répertoire personnel dont le service n’a pas besoin. --shell /usr/sbin/nologin signifie que même si un attaquant parvient à obtenir ce compte, il ne peut pas ouvrir de shell avec celui-ci. Le compte sert uniquement à posséder un processus et ses fichiers.

Donnez ensuite à cet utilisateur uniquement les fichiers dont il a besoin :

sudo chown -R appsvc:appsvc /opt/myapp

Le service lit et écrit alors dans son propre répertoire, sans accès utile au reste du disque. S’il est compromis, les fichiers que l’attaquant peut modifier se limitent à /opt/myapp. Le compte peut toujours lire les fichiers accessibles à tous, mais il ne peut pas modifier le reste du système.

Faites exécuter le service par systemd avec cet utilisateur

Une fois le compte créé, indiquez à systemd d’exécuter le service avec ce compte. Une seule ligne suffit dans le fichier d’unité :

[Service]
ExecStart=/opt/myapp/bin/server
User=appsvc
Group=appsvc

User=appsvc signifie que le processus démarre avec les privilèges limités de ce compte, et non avec ceux de root. C’est la méthode standard pour exécuter une application avec systemd. Elle vaut la peine d’être appliquée à chaque service pour lequel vous écrivez une unité. La réduction des privilèges ne sert toutefois à rien si systemd surveille le mauvais processus. Si l’unité reste indiquée comme active alors que le daemon s’est arrêté discrètement, vérifiez que vous avez choisi la bonne valeur de Type= selon le mode de démarrage de votre processus.

Ou ignorez complètement le compte avec DynamicUser

systemd peut aller plus loin et créer pour vous un utilisateur temporaire, qui n’existe que pendant l’exécution du service. Définissez DynamicUser=yes et vous n’avez plus besoin de gérer un compte :

[Service]
ExecStart=/opt/myapp/bin/server
DynamicUser=yes
StateDirectory=myapp

Au démarrage, systemd attribue un identifiant utilisateur inutilisé ; à l’arrêt, il le libère. Le service dispose également d’un /tmp privé, d’une vue en lecture seule de la plupart du système de fichiers et d’un répertoire d’état accessible en écriture sous /var/lib/myapp, que StateDirectory= configure et lui transmet. Rien de comparable n’était possible avec SysV init : l’abandon des privilèges dépendait alors de ce que faisait le script de démarrage de chaque service. Cette lacune explique en grande partie pourquoi les distributions sont passées à systemd. Pour un service autonome qui n’a besoin que de son propre répertoire d’état, DynamicUser=yes est le moyen le plus simple d’obtenir une isolation forte, car aucun compte persistant ne peut être ciblé par un attaquant.

Écrire des unités à la main est fastidieux, et l’essentiel du travail consiste à choisir correctement les directives de durcissement. Le générateur du guide des services et timers systemd peut remplir ces options à votre place afin que l’unité soit correcte dès le premier essai.

Comment cela s’intègre au reste

Le principe du moindre privilège constitue une couche de sécurité. Il fonctionne avec les autres couches et ne les remplace pas. Un pare-feu avec refus par défaut contrôle ce qui peut atteindre le service. L’exécuter avec un utilisateur non privilégié limite ce que le service peut faire s’il est compromis. Un SSH renforcé empêche les attaquants d’accéder au serveur dès le départ. Aucune de ces mesures ne suffit seule. Ensemble, elles évitent qu’une faille dans un service ne compromette tout le serveur. L’hébergement d’un service qui protège des secrets montre aussi les limites de ces couches : un compte restreint limite ce qu’un processus compromis peut atteindre, mais un gestionnaire de mots de passe auto-hébergé comme Vaultwarden dépend toujours de la protection de son jeton d’administration et de son fichier de sauvegarde. L’isolation des utilisateurs ne protège ni l’un ni l’autre.

Avant de continuer, passez en revue une checklist de durcissement pour l’ensemble du serveur et générez-en une copie personnalisée :

ToolVPS hardening checklist

FAQ

Pourquoi ne dois-je pas exécuter un service en tant que root ?

Comme root peut tout faire sur la machine, un service exécuté en tant que root qui est exploité donne à l’attaquant le contrôle de l’ensemble du serveur, et pas seulement du service. Exécuter le service avec un compte limité et non privilégié circonscrit les dégâts à ce que ce compte peut atteindre. Réservez root à l’administration et exécutez chaque service de longue durée avec un utilisateur restreint.

Comment créer un utilisateur qui ne peut pas se connecter ?

Exécutez sudo useradd --system --no-create-home --shell /usr/sbin/nologin NAME. Le shell nologin empêche le compte d’ouvrir une session interactive, même si ses identifiants sont volés, --system l’identifie comme un compte de service et --no-create-home évite de créer un répertoire personnel dont il n’a pas besoin. Donnez-lui uniquement la propriété de ses propres fichiers avec chown.

Qu’est-ce que DynamicUser de systemd ?

DynamicUser=yes demande à systemd de créer un utilisateur temporaire pour le service. Cet utilisateur n’existe que pendant l’exécution du service. Vous n’avez donc jamais à gérer un compte permanent. Le service dispose également d’un /tmp privé, d’une vue du système de fichiers en grande partie accessible en lecture seule et d’un répertoire d’état géré automatiquement. C’est la solution la plus simple pour exécuter un service autonome avec une identité temporaire et faiblement privilégiée.

L’exécution avec un utilisateur non root remplace-t-elle un pare-feu ?

Non. Ces deux mécanismes protègent des éléments différents. L’exécution avec un utilisateur non privilégié limite ce qu’un service peut faire s’il est compromis, tandis qu’un pare-feu limite ce qui peut atteindre le service. Utilisez les deux, avec un accès SSH renforcé, afin que chaque couche couvre ce que les autres ne peuvent pas couvrir.

Quels fichiers l’utilisateur du service doit-il posséder ?

Uniquement les fichiers dont le service a réellement besoin, et rien de plus. Donnez au compte la propriété de son répertoire de travail et de ses données, puis laissez root posséder tout le reste. Un schéma courant consiste à utiliser sudo chown -R svc-app:svc-app /opt/svc-app pour le répertoire de l’application, tandis que la configuration sous /etc reste la propriété de root et est seulement lisible par le service. L’objectif est que, si le processus est compromis, les fichiers qu’il peut modifier se limitent à ses propres données, et non au reste du système.

#sécurité#least-privilege#systemd#users#hardening#linux