Aller au contenu
Administration Linux medium

Limiter les ressources d'un processus avec ulimit et systemd

8 min de lecture

Chaque processus Linux a des plafonds de ressources : nombre de fichiers ouverts, nombre de processus, taille mémoire. Sans garde-fou, une application qui fuit des descripteurs ou une boucle qui crée des processus sans fin peut saturer la machine entière. Ce guide montre comment lire ces limites, en fixer de durables par utilisateur avec limits.conf et par service avec systemd, et surtout diagnostiquer le piège classique : une limite posée quelque part n'est pas celle qui s'applique. Pour administrateurs intermédiaires, toutes distributions. C'est un objectif LFCS. Sorties issues d'un test AlmaLinux 10.

  • La différence entre limite souple (soft) et limite stricte (hard).
  • Lire les limites en vigueur avec ulimit, prlimit et /proc.
  • Fixer une limite durable par utilisateur via limits.conf.
  • Fixer une limite par service via les directives Limit* de systemd.
  • Comprendre pourquoi une limite ne s'applique pas là où on l'attend.

Le cas d'école est la fuite de descripteurs de fichiers : un serveur qui ouvre des connexions sans les fermer finit par atteindre son plafond nofile et refuse tout nouveau client avec un Too many open files, sans planter pour autant. L'autre est la fork bomb : un script qui se duplique en boucle remplit la table des processus jusqu'à rendre la machine inutilisable. Plafonner nofile (fichiers ouverts) et nproc (processus par utilisateur) transforme ces incidents en simple refus local au lieu d'un effondrement global.

Chaque limite existe en deux valeurs. La limite souple est celle réellement appliquée, que l'utilisateur peut relever jusqu'à la limite stricte, le plafond absolu qu'il ne peut pas dépasser sans privilège. On les manipule avec la commande intégrée ulimit (-S pour souple, -H pour stricte).

Pour la session courante, ulimit -a liste tout ; ciblez une ressource avec son option (-n pour nofile, -u pour nproc). Par défaut, un compte affiche souvent une limite souple de 1024 fichiers ouverts et une limite stricte bien plus haute :

Fenêtre de terminal
ulimit -Sn # limite souple : 1024
ulimit -Hn # limite stricte : 524288

Pour n'importe quel processus déjà lancé, la source de vérité est le noyau lui-même, exposé dans /proc/<pid>/limits, ou lue proprement avec prlimit :

Fenêtre de terminal
prlimit --pid 1234 --nofile
cat /proc/1234/limits

prlimit sait aussi lancer une commande sous une limite imposée, pratique pour tester le comportement d'un programme sous contrainte :

Fenêtre de terminal
prlimit --nofile=256 -- monprogramme

Une valeur posée avec ulimit disparaît à la fermeture du terminal. Pour qu'une limite survive aux reconnexions, on la déclare dans /etc/security/limits.conf ou, mieux, dans un fichier dédié sous /etc/security/limits.d/. C'est le module pam_limits qui les applique, à chaque ouverture de session.

  1. Écrire la règle dans un fichier de limits.d. Chaque ligne a quatre champs : le domaine (un utilisateur, un groupe avec @, ou * pour tous), le type (soft ou hard), l'item (nofile, nproc...) et la valeur.

    /etc/security/limits.d/90-appuser.conf
    appuser soft nofile 2048
    appuser hard nofile 4096
    appuser soft nproc 50
  2. Ouvrir une nouvelle session pour l'utilisateur : la règle n'est lue qu'au login, jamais sur une session déjà active.

    Fenêtre de terminal
    runuser -l appuser -c 'ulimit -Sn; ulimit -Hn; ulimit -Su'

    La sortie confirme les valeurs voulues, et rien d'autre :

    2048
    4096
    50
  3. Vérifier qu'un autre compte n'est pas touché. La règle vise appuser, donc root garde son défaut.

    Fenêtre de terminal
    ulimit -Sn # toujours 1024 pour root

Comme un service ne lit pas limits.conf, sa limite se déclare dans son unité, avec les directives Limit* (LimitNOFILE, LimitNPROC, LimitMEMLOCK...). C'est le bon endroit pour un serveur web ou une base de données qui a besoin de beaucoup de descripteurs.

  1. Déclarer la limite dans l'unité (ou un fichier d'override via systemctl edit).

    /etc/systemd/system/demo-limit.service
    [Service]
    Type=simple
    ExecStart=/bin/sleep 600
    LimitNOFILE=1234
  2. Recharger et démarrer le service.

    Fenêtre de terminal
    sudo systemctl daemon-reload
    sudo systemctl start demo-limit.service
  3. Vérifier la limite réellement appliquée au processus, dans /proc, et la valeur configurée, via systemd.

    Fenêtre de terminal
    pid=$(systemctl show -p MainPID --value demo-limit.service)
    grep 'Max open files' /proc/$pid/limits
    systemctl show -p LimitNOFILE demo-limit.service
    Max open files 1234 1234
    LimitNOFILE=1234

La valeur 1234 est bien celle du processus, indépendamment de tout limits.conf. Pour un service, c'est la seule voie fiable.

Quand une limite « ne marche pas », le réflexe est de comparer ce qui est configuré et ce qui est appliqué. La configuration se lit dans limits.d ou l'unité systemd ; l'application se lit toujours dans /proc/<pid>/limits, l'unique source de vérité. Voici les cas les plus fréquents.

SymptômeCause probableSolution
Un service reste à 1024 malgré limits.confLes services ignorent limits.confPoser LimitNOFILE= dans l'unité, daemon-reload, redémarrer
La nouvelle limite n'est pas prise en compteSession ouverte avant le changementSe reconnecter (login) ; pam_limits n'agit qu'au login
Un utilisateur ne peut pas relever sa limiteIl vise au-dessus de la limite stricteAugmenter la valeur hard dans limits.conf (nécessite root)
  • Chaque limite a une valeur souple (appliquée, ajustable) et stricte (plafond absolu).
  • ulimit agit sur la session courante ; prlimit lit ou impose une limite à un processus ; /proc/<pid>/limits dit la vérité.
  • limits.conf (et limits.d) fixe des limites durables par utilisateur, appliquées par pam_limits au login uniquement.
  • Un service systemd ignore limits.conf : sa limite se pose avec LimitNOFILE et consorts dans l'unité.
  • Pour diagnostiquer, comparez toujours le configuré au réellement appliqué dans /proc.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn