Dawan Proxmox VE — TSSR

Chapitre 1 — Introduction, Installation et LXC

10. Conteneurs privilégiés et non privilégiés

Tous les conteneurs partagent le noyau de l'hôte : la question qui se pose aussitôt est donc celle de la sécurité. Que se passe-t-il si un service compromis obtient les droits root dans le conteneur ? La réponse dépend d'un seul réglage, choisi à la création — le mode privilégié ou non privilégié.

10.1 Conteneurs privilégiés et non-privilégiés

Proxmox vous propose, à la création de chaque conteneur, de choisir entre un mode privilégié et un mode non-privilégié. Ce choix conditionne directement la posture de sécurité du conteneur et certaines de ses capacités.

Tout se joue sur les UID (User ID, numéros d'utilisateur) que le noyau attribue aux processus du conteneur. Avant de cocher ou décocher cette case, il faut comprendre ce qui se passe réellement sous le capot.

10.1.1 Ce que signifie "non-privilégié" — le remapping d'UIDs

La distinction repose sur une fonctionnalité du noyau Linux appelée user namespace. Pour comprendre pourquoi elle change tout, il faut saisir ce que fait root dans un conteneur sans elle.

Sans user namespace (conteneur privilégié), l'UID 0 à l'intérieur du conteneur correspond exactement à l'UID 0 sur l'hôte. Du point de vue du noyau Linux, c'est le même utilisateur.

Si un attaquant exploite une faille dans le conteneur et parvient à en sortir, il est immédiatement root sur la machine physique. Il a alors accès à tous les autres conteneurs, aux disques, à la configuration réseau. L'isolation LXC protège contre les accès normaux, mais une faille noyau suffit à tout compromettre.

Avec user namespace (conteneur non-privilégié), Proxmox configure un remapping d'UIDs : l'UID 0 à l'intérieur du conteneur est traduit en UID 100000 sur l'hôte. L'UID 1 devient 100001, l'UID 1000 devient 101000, et ainsi de suite sur une plage de 65 536 UIDs. Ce remapping est défini dans deux fichiers sur l'hôte :

Conteneur privilégié (UID 0 du conteneur = UID 0 hôte, risque réel) versus non-privilégié (remapping UID 0 conteneur → UID 100000 hôte)

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# Plages UID/GID allouées à Proxmox pour les conteneurs non-privilégiés
cat /etc/subuid
# → root:100000:65536

cat /etc/subgid
# → root:100000:65536

Résultat attendu :

root:100000:65536

Cela signifie que l'utilisateur root sur l'hôte peut utiliser la plage d'UIDs 100000–165535 pour les conteneurs non-privilégiés. Proxmox gère automatiquement cette allocation — vous n'avez jamais à modifier ces fichiers manuellement.

Concrètement : un attaquant peut obtenir les droits root à l'intérieur du conteneur (UID 0 dans le conteneur = UID 100000 sur l'hôte). Il n'est pourtant qu'un utilisateur ordinaire, sans privilèges, sur la machine physique. La faille noyau ne suffit plus.

10.1.2 Tableau de décision — quand choisir quel mode

La règle de départ est simple : toujours commencer en non-privilégié. La majorité des services courants fonctionnent parfaitement dans ce mode. Le mode privilégié n'est justifié que dans des cas précis, et encore — souvent évitables grâce aux features (voir section suivante).

Cas d'usage Mode recommandé Raison
Serveur web (nginx, Apache) Non-privilégié Aucune interaction noyau spéciale
Base de données (MariaDB, PostgreSQL) Non-privilégié Fonctionne parfaitement
Serveur DNS, DHCP, mail Non-privilégié Aucun besoin de privilege
Docker à l'intérieur du LXC Non-privilégié + nesting=1 Feature suffisante depuis PVE 7
Serveur NFS (exports) Privilégié NFS kernel server exige l'UID réel
Accès à un périphérique /dev/ Privilégié Remapping incompatible avec /dev
Modules noyau personnalisés Privilégié Nécessite des capabilities kernel
Tout le reste Non-privilégié Par défaut

10.1.3 Les features — la voie du milieu

Entre « non privilégié strict » et « privilégié total », Proxmox permet d'activer des fonctions précises sur un conteneur non privilégié, par l'option --features. On évite ainsi de sacrifier toute la sécurité du remappage pour un besoin ponctuel.

Feature Usage Exemple typique
nesting=1 systemd récent, Docker ou LXC dans le conteneur Debian 13, environnement de développement
fuse=1 Montages FUSE (sshfs, rclone…) Stockage distant monté dans le conteneur

Le message WARN: Systemd 257 detected. You may need to enable nesting.

À la création d'un conteneur Debian 13, Proxmox affiche cet avertissement. Le conteneur est créé et démarre, mais il faut le traiter : Debian 13 embarque systemd 257, qui a besoin de la fonction nesting dans un conteneur non privilégié. Sans elle, des services peuvent ne pas démarrer, ou les journaux rester vides.

Le nom est trompeur : nesting évoque l'imbrication (Docker dans le conteneur), mais c'est surtout ce qui permet à systemd lui-même de fonctionner normalement.

L'activer sur un conteneur déjà créé — interface : CT 200 → Options → Features → Edit → cocher Nesting → OK. En ligne de commande :

Dans le Shell du nœud (interface web → votre nœud → Shell) :

pct set 200 --features nesting=1   # ajouter la fonction nesting
pct config 200 | grep features      # vérifier la configuration
pct reboot 200                      # redémarrer pour l'appliquer

Résultat attendu : features: nesting=1.

LXC applique les features au démarrage du conteneur : le redémarrage est obligatoire, deux à trois secondes pour un conteneur. Pour ne pas voir l'avertissement du tout, ajoutez --features nesting=1 dès la création, avec pct create.

10.1.4 Créer un conteneur dans chaque mode

La commande pct create reste identique dans les deux cas, seule la valeur de --unprivileged change :

Dans le Shell du nœud (interface web → votre nœud → Shell) :

# Mode non-privilégié — à utiliser par défaut
# --unprivileged 1 : root du CT = UID 100000 sur l'hôte
pct create 200 local:vztmpl/debian-13-standard_13.6-1_amd64.tar.zst \
  --hostname ct-secure \
  --unprivileged 1 \
  --memory 512 \
  --rootfs local-lvm:8 \
  --net0 name=eth0,bridge=vmbr0,ip=10.44.1.50/24,gw=10.44.1.1 \
  --password dawan

# Mode privilégié — uniquement si NFS server ou accès /dev indispensable
# --unprivileged 0 : root du CT = root sur l'hôte — risque réel
pct create 300 local:vztmpl/debian-13-standard_13.6-1_amd64.tar.zst \
  --hostname ct-nfs-server \
  --unprivileged 0 \
  --memory 512 \
  --rootfs local-lvm:8 \
  --net0 name=eth0,bridge=vmbr0,ip=10.44.1.50/24,gw=10.44.1.1 \
  --password dawan

# Vérifier le mode d'un conteneur existant
pct config 200 | grep unprivileged

Résultat attendu :

unprivileged: 1

La valeur 1 confirme le mode non-privilégié. Sur un conteneur privilégié, la commande n'affiche rien : 0 est la valeur par défaut, et Proxmox n'écrit pas dans la configuration une option laissée à sa valeur par défaut. Un grep muet n'est donc pas une erreur, c'est la réponse « privilégié ».

Limitation importante du mode non-privilégié : les montages NFS côté serveur (export via /etc/exports) ne fonctionnent pas — le kernel NFS server a besoin d'UIDs réels. En revanche, monter un partage NFS en tant que client (mount -t nfs) fonctionne parfaitement en non-privilégié.

Règle de sécurité : en production, tous les conteneurs doivent être non-privilégiés sauf justification documentée. Si un service semble nécessiter le mode privilégié, vérifiez d'abord si une feature spécifique ne suffit pas — c'est presque toujours le cas.

Un service compromis donne à un attaquant le compte `root` **à l'intérieur** d'un conteneur non privilégié. Sur le nœud, qui est-il ?
Réponse **Un utilisateur sans aucun droit.** Dans un conteneur non privilégié, les UID sont décalés : le root du conteneur (UID 0) correspond sur l'hôte à l'UID `100000`, déclaré dans `/etc/subuid`. S'il sort du conteneur, il n'a pas plus de pouvoir qu'un compte ordinaire. Dans un conteneur **privilégié**, il serait le vrai root du nœud : c'est pourquoi le non privilégié est la règle.

À retenir : un conteneur non privilégié décale ses UID : le root du conteneur est un utilisateur sans droit sur l'hôte (/etc/subuid). C'est le choix par défaut et la règle en production. nesting et fuse ajoutent des capacités sans passer en privilégié.