Contexte et besoins
Dans le cadre de mon alternance, l’hyperviseur Proxmox VE du lab interne héberge déjà des VM pleines (contrôleur de domaine, hôte Docker, OPNsense). Pour les services Linux légers à venir (DNS interne, gestionnaire de mots de passe, reverse proxy), monter une VM complète à chaque fois consomme inutilement la RAM et le disque de l’hyperviseur. C’est le cas d’usage typique des conteneurs LXC.
L’objectif de cette intervention est de créer un conteneur LXC Debian 12 non privilégié, avec une IP statique sur le segment du lab, pour qu’il soit utilisable comme cible de service. Pas de service métier déployé encore : uniquement la mécanique LXC bien comprise et un conteneur de référence prêt à recevoir une charge.
Rappel théorique sur LXC dans Proxmox
Conteneur Linux : entre VM et processus
Un conteneur LXC est un environnement isolé qui partage le noyau de l’hôte mais a son propre arbre de fichiers, ses propres interfaces réseau, ses propres limites de ressources. C’est la même mécanique que Docker, mais orientée « système complet » plutôt que « processus applicatif » :
| Aspect | LXC (Proxmox) | Docker | VM (KVM/QEMU) |
|---|---|---|---|
| Isolation | namespaces + cgroups | namespaces + cgroups | matérielle (hyperviseur) |
| Noyau | Partagé avec l’hôte | Partagé avec l’hôte | Indépendant |
| Démarrage | Quelques secondes | < 1 seconde | 30 secondes à plusieurs minutes |
| OS supportés | Linux uniquement | Linux uniquement | Tous (Windows, BSD, etc.) |
| Cas d’usage | Service système complet | Application packagée | Compatibilité maximale, sécurité |
Privilégié vs non privilégié
C’est l’option de sécurité la plus importante à choisir. Sur Proxmox :
- Conteneur privilégié : le
rootdu conteneur est lerootde l’hôte (UID 0 partagé). Une vulnérabilité d’évasion peut donner les pleins pouvoirs sur l’hyperviseur. - Conteneur non privilégié (recommandé) : le
rootdu conteneur est mappé sur un UID élevé côté hôte (par exemple100000). Une évasion donne des droits limités côté hôte.
Je crée systématiquement des conteneurs non privilégiés, sauf besoin précis.
Templates et stockages
Proxmox stocke deux types d’éléments :
- les templates LXC (fichiers
.tar.zst) dans le storagelocal, dossiertemplate/cache/; - les rootfs (système de fichiers du conteneur) dans
local-lvmou un autre stockage de type rootdir.
Avant de créer un conteneur, on télécharge un template depuis Proxmox via Datacenter → pve → local → CT Templates.
Topologie
| Équipement | Rôle | Adresse |
|---|---|---|
| Passerelle du lab | Routeur / DHCP / DNS | 192.168.10.254/24 |
Hôte Proxmox pve | Hyperviseur LXC + KVM | 192.168.10.250/24 |
Conteneur LXC web-ct | Cible de l’intervention | 192.168.10.140/24 (statique) |
| Mon poste d’admin | Navigateur Web Proxmox | DHCP sur LAN |
Prérequis
- Un hôte Proxmox VE 8 fonctionnel avec un storage
local-lvmopérationnel. - Un accès admin (
root@pam) ou un compte délégué avec les droitsVM.AllocateetDatastore.AllocateSpace. - Un réseau bridge
vmbr0configuré (par défaut sur l’hôte). - Connectivité Internet pour télécharger le template Debian.
Téléchargement du template
Sur l’interface Web Proxmox, Datacenter → pve → local → CT Templates → Templates, je cherche debian-12-standard et clique sur Download. Proxmox récupère l’image depuis le miroir LinuxContainers. La taille du template est d’environ 250 Mo, le téléchargement prend une minute.
debian-12-standard_12.7-1_amd64.tar.zstAstuce
En CLI directement sur l’hôte, on aurait fait pveam update && pveam download local debian-12-standard. Pratique quand on automatise.
Création du conteneur
Bouton Create CT en haut à droite de l’interface Web. L’assistant en plusieurs onglets s’ouvre.
Onglet General
Node : pve
CT ID : 110
Hostname : web-ct
Unprivileged container : coché
Resource Pool : (vide)
Password : (passphrase 16+ caractères)
SSH public key(s) : ssh-ed25519 AAAA... admin@poste-adminExplications ligne par ligne :
CT ID 110: les conteneurs et VM partagent le même espace d’identifiants. La dernière VM créée portait le 109, j’enchaîne.Hostname web-ct: nom court qui sera aussi le hostname interne du conteneur.Unprivileged container: coché: choix de sécurité par défaut. À ne décocher que si on a un besoin technique précis (par exemple un conteneur qui doit charger un module noyau, cas rare).Password: définit le mot de passerootdu conteneur. Stocké dans le gestionnaire de mots de passe de l’équipe.SSH public key: ma clé publique est ajoutée à/root/.ssh/authorized_keysdu conteneur. Bonne pratique : se connecter en SSH par clé plutôt que par mot de passe une fois le conteneur démarré.
Onglet Template
Storage : local
Template : debian-12-standard_12.7-1_amd64.tar.zstJe sélectionne le template téléchargé à l’étape précédente.
Onglet Disks
Storage : local-lvm
Disk size : 8 GiB8 Go suffisent largement pour Debian + un service léger. La taille peut être étendue plus tard avec pct resize.
Onglet CPU
Cores : 2
CPU limit : (vide, pas de plafond)
CPU units : 1024 (poids relatif standard)Cores: 2 me donne deux threads CPU, suffisant pour la plupart des services internes.
Onglet Memory
Memory : 1024 MB
Swap : 512 MB1 Go de RAM + 512 Mo de swap, ça reste raisonnable pour Debian + un petit service. Le swap est posé sur le même storage que le rootfs.
Onglet Network
Name : eth0
Bridge : vmbr0
IPv4 : Static
IPv4/CIDR : 192.168.10.140/24
Gateway (IPv4) : 192.168.10.254
IPv6 : SLAAC
Firewall : cochéExplications ligne par ligne :
Bridge: vmbr0: bridge par défaut de Proxmox, relié à l’interface physique de l’hôte. Le conteneur se retrouve sur le LAN du lab.IPv4: Static / 192.168.10.140/24: je sors de la plage DHCP de la passerelle et j’utilise une IP réservée à la zone des conteneurs de service (.140et suivantes).Gateway 192.168.10.254: passerelle du lab.Firewall: coché: active le firewall Proxmox au niveau du conteneur. Indispensable : sans ça, le conteneur est totalement exposé sur le LAN.
Onglet DNS
DNS domain : lab.local
DNS servers : 192.168.10.250192.168.10.250 est le DC LAB.LOCAL qui sert aussi de DNS interne. Pour un conteneur sans besoin de résoudre des noms internes, on cocherait Use host settings.
Onglet Confirm
L’assistant récapitule tout. Je relis ID, hostname, storage, RAM, IP, puis Finish. Proxmox crée le conteneur en quelques secondes.
Démarrage et vérifications
Démarrage
Je sélectionne 110 (web-ct) dans l’arborescence, je clique sur Start. La LED verte apparaît. Le démarrage prend moins de 5 secondes.
# Équivalent en CLI sur l'hôte
pct start 110
# Vérification de l'état
pct status 110
# Sortie attendue : status: runningConnexion à l’intérieur
Je clique sur Console dans l’interface Web. Un terminal NoVNC s’ouvre directement sur le prompt de login du conteneur.
Debian GNU/Linux 12 web-ct tty1
web-ct login: root
Password: ********
root@web-ct:~#Alternative en CLI sur l’hôte :
# Entrer dans le conteneur sans mot de passe (équivaut à console)
pct enter 110
# Ou exécuter une commande unique
pct exec 110 -- hostnamectlConfiguration initiale du conteneur
# À l'intérieur du conteneur
apt update && apt upgrade -y
# Outils de base
apt install -y curl wget vim htop ca-certificates
# Fuseau horaire
timedatectl set-timezone Europe/Paris
# Vérification du hostname et de la résolution DNS
hostnamectl
ping -c 2 google.fr
ping -c 2 dc.lab.localExplications ligne par ligne :
apt update && apt upgrade: met à jour le conteneur. Le template peut avoir quelques semaines de retard.timedatectl set-timezone: aligne l’heure locale. Important pour les logs corrélés avec le reste du parc.ping -c 2 google.fr: valide la résolution DNS publique et la sortie Internet via la passerelle.ping -c 2 dc.lab.local: valide que le DNS interne (192.168.10.250) résout bien les noms du domaine du lab.
Vérifications côté hôte Proxmox
# Lister tous les conteneurs
pct list
# Configuration du conteneur (en clair, sans mot de passe)
pct config 110
# Consommation temps réel
pct status 110 --verbosepct config 110 montre l’agrégat de la configuration appliquée, par exemple :
arch: amd64
cores: 2
features: nesting=1
hostname: web-ct
memory: 1024
net0: name=eth0,bridge=vmbr0,firewall=1,gw=192.168.10.254,hwaddr=...,ip=192.168.10.140/24,type=veth
ostype: debian
rootfs: local-lvm:vm-110-disk-0,size=8G
swap: 512
unprivileged: 1Astuce
Le fichier de config réel est dans /etc/pve/lxc/110.conf. On peut l’éditer en direct (l’hôte applique au prochain restart), mais il vaut mieux passer par pct set pour rester cohérent avec la base Proxmox.
Problèmes rencontrés et solutions
| Symptôme | Cause | Correction |
|---|---|---|
| Le conteneur ne démarre pas, failed to mount /sys/fs/cgroup | Hôte Proxmox sans cgroups v2 (rare en VE 8) | Mettre à jour l’hôte : VE 8 active cgroups v2 par défaut |
| Pas d’accès Internet depuis le conteneur | Mauvaise passerelle ou DNS | Vérifier ip route dans le conteneur, corriger via pct set 110 -nameserver 192.168.10.254 |
apt update échoue avec certificate verify failed | Heure du conteneur fausse au premier boot | apt install -y ca-certificates ntpdate && ntpdate fr.pool.ntp.org |
| Le hostname n’apparaît pas dans le DNS interne | Pas d’enregistrement A côté DNS | Ajouter manuellement l’A web-ct → 192.168.10.140 dans le DNS interne |
| Le conteneur consomme tout le CPU de l’hôte | Pas de plafond CPU configuré | pct set 110 -cpulimit 1.0 (max 1 cœur) |
| Modification de mémoire à chaud refusée | Memory hotplug non actif | Modifier la valeur, redémarrer le conteneur (le hotplug n’est pas géré pour LXC sur tous les noyaux) |
Compétences du bloc 1 mobilisées
| Compétence officielle | Mobilisation concrète |
|---|---|
| Installer et configurer des éléments d’infrastructure | Création d’un conteneur LXC non privilégié sur l’hyperviseur Proxmox du lab. |
| Mettre à disposition aux utilisateurs un service informatique | Préparation d’une cible Debian 12 prête à recevoir un service applicatif léger. |
| Gérer le patrimoine informatique de l’organisation | Documentation du conteneur (web-ct, ID 110, IP, ressources, hôte Proxmox) dans le plan d’adressage du lab. |
| Réaliser les tests d’intégration et d’acceptation d’un service | Vérifications croisées (pct status, ping passerelle, ping DNS interne, ping Internet). |
Bilan
web-ct est en service : conteneur Debian 12 non privilégié, 2 cœurs, 1 Go de RAM, 8 Go de disque, IP statique 192.168.10.140. Il répond au ping, il a accès à Internet, il résout les noms internes. C’est une base prête à recevoir n’importe quel petit service Linux du lab.
Trois enseignements :
- la création LXC est plus rapide qu’une VM (5 secondes vs 1 minute) parce qu’il n’y a pas de boot d’OS — le conteneur démarre directement dans le runlevel 3 avec systemd, comme un système Linux qu’on aurait juste démarré ;
- l’option non privilégié est essentielle pour la sécurité, sans coût pratique pour 95 % des usages ;
- le firewall Proxmox au niveau du conteneur est une couche de défense qu’on prend trop souvent à la légère — activé par défaut + une règle d’autorisation explicite, c’est l’approche par moindre privilège.
Pour la suite, ce conteneur servira de socle pour les prochaines interventions (déploiement de services applicatifs en Docker, services système simples installés directement, etc.).
Sources
- Proxmox VE Documentation — Linux Container (LXC) , Proxmox Server Solutions.
- Proxmox VE Documentation — pct (Container Toolkit) manual , Proxmox Server Solutions.
- LinuxContainers.org — LXC introduction , LinuxContainers project.
- Debian Wiki — LXC , Debian Project.
- ANSSI — Recommandations relatives à l’administration sécurisée des systèmes d’information , ANSSI.