Aller au contenu

Les capabilities Linux

Mise à jour :

Les Linux Capabilities, c’est un peu comme des super-pouvoirs pour les processus système. Elles permettent de diviser les privilèges du super-utilisateur root en morceaux plus petits et plus ciblés. Cela rend Linux plus sûr, mais aussi plus complexe à configurer. Et si ces capacités sont mal gérées ? Vous ouvrez une porte royale à l’escalade de privilèges. Dans ce guide, je vais vous montrer comment fonctionnent les capabilities, pourquoi elles sont essentielles et, surtout, comment les utiliser intelligemment pour sécuriser vos systèmes.

Un peu d’histoire

Au commencement, Linux avait un modèle très simple : le super-utilisateur root pouvait tout faire, et les autres utilisateurs avaient des permissions limitées. Ce modèle monolithique était efficace, mais il présentait un gros problème : si un processus obtenait les privilèges de root, il pouvait faire absolument tout, souvent bien plus que ce qui était nécessaire.

C’est ici que les Linux Capabilities entrent en jeu. Introduites avec le noyau Linux 2.2, elles ont été conçues pour résoudre ce problème en découpant les privilèges de root en plusieurs morceaux appelés capabilities. Chaque capability représente un privilège spécifique, comme ouvrir des ports réseau ( < 1024 ) ou changer l’horloge système.

Au fil des ans, ce système a évolué pour offrir davantage de granularité et de flexibilité. Aujourd’hui, les capabilities sont utilisées non seulement pour sécuriser les applications, mais aussi pour permettre à certaines d’entre elles d’accéder à des fonctionnalités avancées sans avoir besoin de permissions globales. Par exemple, un serveur web peut écouter sur le port 80 grâce à CAP_NET_BIND_SERVICE, sans nécessiter les privilèges complets de root.

En bref, les Linux Capabilities sont le fruit d’une évolution pour répondre aux exigences modernes de sécurité tout en conservant la souplesse nécessaire pour gérer des systèmes complexes. Mais comme souvent avec la puissance, elles viennent aussi avec leur lot de responsabilités. Si elles ne sont pas correctement maîtrisées, elles peuvent devenir une faille de sécurité majeure.

Les concepts essentiels

Les Linux Capabilities reposent sur un modèle bien structuré, mais qui peut paraître un peu complexe au premier abord. Pour bien les utiliser, il est essentiel de comprendre leur fonctionnement et leur gestion. Voici les concepts clés à connaître :

*** Le modèle POSIX Capabilities**

Les capabilities sont définies selon le standard POSIX, qui les divise en trois ensembles principaux pour chaque processus :

  1. Effective : Ce sont les capabilities actuellement actives pour un processus. Elles déterminent ce qu’un processus peut faire à un instant donné. Par exemple, si un processus possède CAP_NET_ADMIN dans son ensemble Effective, il peut modifier les configurations réseau.

  2. Permitted : Cet ensemble regroupe les capabilities qu’un processus est autorisé à activer. Il agit comme une liste de contrôle : seules les capabilities figurant dans cet ensemble peuvent être activées dans l’ensemble Effective.

  3. Inheritable : Ces capabilities peuvent être transmises aux processus enfants. Si un processus exécute un autre programme, cet ensemble détermine quelles capabilities seront disponibles pour ce dernier.

  • Héritage des capabilities : Quand un processus exécute un nouveau programme, l’héritage des capabilities dépend de plusieurs facteurs, notamment des paramètres du fichier exécuté et de l’ensemble Inheritable du processus parent. Cela permet de limiter les capabilities qui pourraient être involontairement propagées.

  • Les fichiers avec capabilities : Certains fichiers exécutables peuvent avoir des capabilities spécifiques attachées. Cela permet à ces fichiers d’être exécutés avec des permissions précises, sans nécessiter une élévation de privilèges via sudo.

Liste des capabilities et leurs usages pratiques

Les Linux Capabilities sont nombreuses et chacune a un rôle précis. Voici une liste des capabilities les plus courantes, leur description et des exemples pratiques pour mieux comprendre leur utilité.

CapabilityDescriptionExemple d’utilisation
CAP_NET_BIND_SERVICEPermet de lier des processus à des ports inférieurs à 1024.Serveurs web ou applications écoutant sur le port 80.
CAP_SYS_ADMINDonne accès à diverses fonctions administratives critiques.Montage de systèmes de fichiers, gestion de namespaces (utilisé souvent dans Docker).
CAP_NET_RAWAutorise l’utilisation de sockets RAW pour manipuler directement les paquets.Analyse réseau avec des outils comme tcpdump ou nmap.
CAP_DAC_OVERRIDEIgnore les restrictions de permissions classiques sur les fichiers.Permet à un processus d’accéder à des fichiers qu’il ne devrait pas lire ou écrire.
CAP_SYS_TIMEAutorise la modification de l’horloge système.Utilisé pour synchroniser les horloges ou ajuster le temps système.
CAP_SYS_PTRACEPermet d’attacher un débogueur à d’autres processus.Utilisé dans des outils comme strace ou gdb pour le débogage.
CAP_CHOWNPermet de changer le propriétaire ou le groupe d’un fichier.Utilisé pour administrer des systèmes de fichiers sans avoir un accès complet à root.

Commandes pour gérer les Linux Capabilities

La gestion des Linux Capabilities repose sur quelques commandes clés, principalement getcap, setcap et des outils intégrés au système comme /proc. Voici un guide pratique pour utiliser ces commandes efficacement.

Vérifier les capabilities d’un fichier

Pour savoir quelles capabilities sont associées à un fichier exécutable, utilisez la commande getcap :

Terminal window
getcap /chemin/vers/le/fichier

Exemple :

Terminal window
getcap /usr/bin/ping

Résultat possible :

/usr/bin/ping cap_net_raw=ep

Pour scanner l’ensemble du système et identifier tous les fichiers avec des capabilities :

Terminal window
getcap -r / 2>/dev/null

Cela retourne une liste de tous les fichiers et leurs capabilities.

Attribuer des capabilities à un fichier

Pour ajouter une capability, utilisez la commande setcap :

Terminal window
sudo setcap <capability>=+ep /chemin/vers/le/fichier
  • <capability> : Nom de la capability (par exemple cap_net_bind_service).
  • +ep : Indique que la capability doit être activée pour l’exécution du fichier.

Exemple :

Terminal window
sudo setcap cap_net_bind_service=+ep /usr/bin/python3

Cela permet à Python d’écouter sur des ports inférieurs à 1024.

Retirer des capabilities d’un fichier

Pour supprimer toutes les capabilities associées à un fichier :

Terminal window
sudo setcap -r /chemin/vers/le/fichier

Exemple :

Terminal window
sudo setcap -r /usr/sbin/nginx

Cela réinitialise le fichier, lui retirant toutes les capabilities.

Vérifier les capabilities d’un processus

Pour vérifier les capabilities actives d’un processus, utilisez /proc :

Terminal window
cat /proc/1885/status | grep Cap
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000

Interpréter les valeurs hexadécimales des capabilities

Les valeurs retournées par /proc sont en hexadécimal. Pour les convertir en noms lisibles, utilisez l’outil capsh :

Terminal window
capsh --decode=0x<valeur>

Exemple :

Terminal window
capsh --decode=0x000001ffffffffff
0x000001ffffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read,cap_perfmon,cap_bpf,cap_checkpoint_restore```

Un cas Concret

Pour exécuter Nginx avec un utilisateur non privilégié sans nécessiter les droits root, nous allons utiliser les Linux Capabilities et configurer correctement le service. Cela permet de renforcer la sécurité en limitant les permissions du processus.

Étape 1 : Ajouter la capability nécessaire à l’exécutable Nginx

Nginx nécessite CAP_NET_BIND_SERVICE pour écouter sur des ports inférieurs à 1024 (par exemple, le port 80).

  1. Assurez-vous que Nginx est installé :

    Terminal window
    sudo apt update && sudo apt install nginx
  2. Attribuez la capability à l’exécutable Nginx :

    Terminal window
    sudo setcap cap_net_bind_service=+ep /usr/sbin/nginx

    Vous pouvez vérifier que la capability a été appliquée :

    Terminal window
    getcap /usr/sbin/nginx

Étape 2 : Modifier la configuration du service Nginx

Nous allons éditer le fichier du service Nginx pour qu’il s’exécute avec un utilisateur non privilégié.

  1. Ouvrez le fichier de configuration du service :

    Terminal window
    sudo systemctl edit nginx.service

    Si le fichier n’existe pas encore, créez une surcharge pour le service avec les directives suivantes :

    [Service]
    User=nom_utilisateur
    Group=nom_groupe
    ExecStartPre=/bin/bash -c 'mkdir -p /run/nginx && chown nom_utilisateur:nom_groupe /run/nginx'
    ExecStart=/usr/sbin/nginx -g 'daemon off;'

    Remplacez nom_utilisateur et nom_groupe par l’utilisateur et le groupe souhaités, par exemple nginx.

  2. Rechargez la configuration du service pour appliquer les modifications :

    Terminal window
    sudo systemctl daemon-reload

Étape 3 : Configurer les permissions sur les fichiers

  1. Assurez-vous que l’utilisateur dispose des permissions sur les répertoires de configuration et de logs :

    Terminal window
    sudo chown -R nom_utilisateur:nom_groupe /etc/nginx /var/log/nginx
  2. Si nécessaire, attribuez les permissions aux répertoires où Nginx écrit des fichiers PID ou temporaires :

    Terminal window
    sudo chown -R nom_utilisateur:nom_groupe /run/nginx

Étape 4 : Tester et démarrer Nginx

  1. Vérifiez que la configuration Nginx est correcte :

    Terminal window
    sudo -u nom_utilisateur nginx -t
  2. Démarrez le service :

    Terminal window
    sudo systemctl start nginx
  3. Assurez-vous que le service est actif et fonctionne correctement :

    Terminal window
    systemctl status nginx

Étape 5 : Sécuriser la configuration

  • Limitez les permissions de l’exécutable Nginx pour éviter tout abus :

    Terminal window
    chmod 750 /usr/sbin/nginx
  • Assurez-vous que seul l’utilisateur spécifié peut accéder aux fichiers critiques de Nginx :

    Terminal window
    chmod -R 750 /etc/nginx /var/log/nginx

Résultat

Avec cette configuration, Nginx peut écouter sur des ports comme 80 ou 443 tout en s’exécutant avec un utilisateur non privilégié. Cette approche renforce la sécurité en limitant l’accès de Nginx au strict nécessaire, réduisant ainsi les risques d’exploitation. 🚀

L’importance de la maîtrise des capabilities

À mon avis, les Linux Capabilities sont l’un des outils les plus sous-estimés en matière de sécurité système. Trop souvent, les administrateurs préfèrent utiliser sudo ou exécuter des processus avec des droits root complets, alors qu’une configuration intelligente des capabilities pourrait suffire dans la majorité des cas.

Cependant, leur flexibilité peut être un couteau à double tranchant. Une capability mal configurée, comme CAP_SYS_ADMIN, peut être exploitée pour compromettre tout le système. C’est pourquoi il est indispensable d’avoir une approche méthodique et rigoureuse.