SSD Nodes Learn
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-07-19

Exécuter un service sans privilèges

Un service lancé en root transforme un bug en accès complet au serveur. Donnez-lui un compte non privilégié, ou laissez systemd le faire avec DynamicUser.

Pourquoi ne pas tout exécuter en root

Root peut tout faire sur la machine : lire chaque fichier, modifier n'importe quel réglage, supprimer le système entier. Quand vous exécutez un service en root, vous confiez toute cette puissance à ce service. Si le service contient un bug qu'un attaquant peut exploiter, il n'obtient pas seulement le service, il obtient root, et root, c'est le serveur tout entier. Exécuter le service en tant qu'utilisateur non privilégié limite les dégâts. Un bug dans un service qui tourne sous un compte restreint ne donne à un attaquant que ce que ce compte peut atteindre, c'est-à-dire presque rien.

C'est le principe du moindre privilège : donnez à chaque partie du système exactement l'accès dont elle a besoin pour faire son travail, et rien de plus. C'est l'habitude la plus efficace pour limiter le rayon d'impact d'une compromission, et sur un serveur moderne, elle ne coûte presque rien à appliquer.

Un compte dédié par service

L'approche classique consiste à créer un utilisateur système distinct pour chaque service, un utilisateur qui possède uniquement les fichiers de ce service et qui ne peut pas se connecter. Un compte système pour une application web peut ressembler à ceci :

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

Chaque option compte. --system en fait un compte de service, pas une connexion humaine. --no-create-home évite un répertoire personnel dont il n'a pas besoin. --shell /usr/sbin/nologin signifie que même si un attaquant met la main sur le compte, il ne peut pas ouvrir de shell avec. Le compte existe seulement pour posséder un processus et ses fichiers.

Ensuite, donnez à cet utilisateur uniquement les fichiers dont il a besoin, et rien de plus :

sudo chown -R appsvc:appsvc /opt/myapp

Maintenant, le service lit et écrit dans son propre répertoire et n'a rien à faire ailleurs sur le disque. S'il est un jour exploité, les fichiers que l'attaquant peut modifier se limitent à /opt/myapp ; le compte peut toujours lire tout ce qui est lisible par tous, mais il ne peut pas modifier le reste du système.

Laissez systemd l'exécuter sous cet utilisateur

Une fois le compte créé, indiquez à systemd d'exécuter le service sous ce compte. Dans le fichier unit, une seule ligne suffit :

[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 au lieu de ceux de root. C'est la manière normale et éprouvée d'exécuter une application sous systemd, et cela vaut la peine de le faire pour chaque service pour lequel vous écrivez un unit.

Ou supprimez le compte entièrement avec DynamicUser

systemd peut aller encore plus loin et créer pour vous un utilisateur jetable, qui n'existe que pendant l'exécution du service. Définissez DynamicUser=yes et vous ne gérez plus aucun compte :

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

Au démarrage, systemd attribue un ID utilisateur inutilisé ; à l'arrêt, il le libère. Le service reçoit aussi un /tmp privé, une vue en lecture seule de la plupart du système de fichiers, et un répertoire d'état accessible en écriture sous /var/lib/myapp que StateDirectory= met en place et lui confie. 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 forte isolation, car il n'y a aucun compte durable qu'un attaquant puisse viser.

Écrire des units à la main est fastidieux, et régler correctement les directives de sécurisation représente l'essentiel de la valeur. Le générateur du guide des services et timers systemd peut remplir ces options à votre place pour que l'unit soit correct du premier coup.

Comment cela s'articule avec le reste

Le moindre privilège est une couche, et il fonctionne avec les autres au lieu de les remplacer. Un pare-feu en refus par défaut contrôle ce qui peut atteindre le service ; l'exécuter en tant qu'utilisateur non privilégié contrôle ce que le service peut faire s'il est compromis ; et SSH renforcé empêche d'abord les attaquants d'accéder à la machine. Aucune de ces mesures ne suffit à elle seule, et ensemble elles font qu'un bug dans un service ne devient pas une compromission du serveur tout entier.

Avant de continuer, parcourez une liste de vérification de sécurisation pour toute la machine et générez une copie personnalisée pour travailler :

ToolVPS hardening checklist

FAQ

Pourquoi ne devrais-je pas exécuter un service en root ?

Parce que root peut tout faire sur la machine, un service exécuté en root qui se fait exploiter donne à l'attaquant le serveur entier, pas seulement le service. Exécuter le service sous un compte limité et non privilégié contient les dégâts à ce que ce compte peut atteindre. Réservez root à l'administration, et exécutez chaque service de longue durée sous 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 signifie que le compte ne peut pas ouvrir de session interactive même si ses identifiants sont volés, --system le marque comme compte de service, et --no-create-home évite un répertoire personnel dont il n'a pas besoin. Donnez-lui la propriété de ses seuls fichiers avec chown.

Qu'est-ce que systemd DynamicUser ?

DynamicUser=yes indique à systemd de créer pour le service un utilisateur temporaire qui n'existe que pendant son exécution, de sorte que vous ne gérez jamais de compte durable. Il donne aussi au service un /tmp privé, une vue du système de fichiers en grande partie en lecture seule, et un répertoire d'état géré. C'est le moyen le plus simple d'exécuter un service autonome sous une identité jetable et à faibles privilèges.

Exécuter un service en utilisateur non-root remplace-t-il un pare-feu ?

Non. Ils protègent des choses différentes. Exécuter le service en tant qu'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 SSH renforcé, pour que chaque couche couvre ce que les autres ne couvrent pas.

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 propre répertoire de travail et de ses données, et laissez tout le reste appartenir à root. Un bon modèle est 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 n'est lisible que par le service. Le but est que si le processus est un jour compromis, les fichiers qu'il peut modifier se limitent à ses propres données, pas au reste du système.

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