Morpheus
Conteneurs / Isolation système

LXC sur Arch Linux

Mise en œuvre et débogage d'un conteneur système LXC non privilégié, depuis les contrôles de l'hôte jusqu'à la validation d'un service nginx.

LXC cgroups namespaces bridge AppArmor
Position publique de LXC dans le lab
Vue publique: hôte Linux, bridge de test, conteneur système non privilégié et service HTTP isolé.
01

Vérifier

Contrôler cgroups, namespaces, mappings uid/gid et outils de conteneurisation sur l'hôte.

02

Créer

Déployer un système Debian depuis un template officiel avec un mapping non privilégié.

03

Déboguer

Traiter séparément permissions, délégation réseau, namespace invité et résolution DNS.

04

Valider

Confirmer l'état RUNNING, le réseau invité, l'écoute nginx et la réponse HTTP depuis l'hôte.

Contexte

Le problème réel.

Le premier démarrage non privilégié a révélé plusieurs dépendances implicites: délégation réseau, permissions du chemin LXC, mappings uid/gid et résolution DNS du système invité. Le diagnostic devait isoler chaque blocage sans affaiblir le modèle de privilège.

Objectifs

Ce que la solution devait garantir.

  • Comprendre la place de LXC entre VM complète et conteneur applicatif.
  • Faire fonctionner un conteneur non privilégié sans publier les valeurs propres à l'hôte.
  • Relier chaque correction à un contrôle observable plutôt qu'à une modification globale.
  • Prouver le service final depuis le terminal et le navigateur.
Architecture publique

Structure documentée, détails exploitables retirés.

Exemples anonymisés

Ce qui peut être montré sans exposer le système réel.

Positionnement LXC

LXC est décrit comme conteneur système: plus proche d'une VM légère que d'un conteneur applicatif.

KVM      machine virtuelle complète  isolation la plus forte
LXC      conteneur système Linux   init complet, faible overhead
Docker   conteneur applicatif      modèle processus packagé
natif    service hôte              le plus simple, le moins isolé

Profil conteneur public

La fiche montre les paramètres importants sans publier la configuration réelle.

conteneur      <CONTAINER_NAME>
réseau          <LXC_BRIDGE>
rootfs          <LXC_ROOTFS>
idmap           plage non privilégiée
limites         cpu / mémoire / io
sécurité        AppArmor + capabilities retirées

Cycle de vie exploitable

La gestion est publiée comme chaîne d'opérations contrôlables.

créer depuis un template
démarrer et valider le réseau
attacher pour configurer le service
snapshot avant changement risqué
backup avant migration
restaurer ou cloner si nécessaire
Runbook public

Commandes et états attendus issus de la documentation privée.

Les commandes ci-dessous sont volontairement anonymisées: chemins, noms de machines, interfaces, dépôts, périphériques et actions destructrices sont remplacés par des placeholders.

Documentation privée: LXC

Préchecks hôte

Commandes anonymisées

mount | rg cgroup
ls -la /proc/self/ns/
lxc-checkconfig
systemctl status systemd-networkd --no-pager

État attendu

les cgroups sont montés
les namespaces sont disponibles
le noyau supporte les fonctions LXC
le backend réseau est connu avant création des conteneurs
Documentation privée: LXC

Cycle conteneur

Commandes anonymisées

lxc-create -n <container-name> -t download -- -d <distribution> -r <release> -a <arch>
lxc-start -n <container-name> -d
lxc-ls -f
lxc-attach -n <container-name>
lxc-info -n <container-name>

État attendu

le conteneur est créé depuis un template connu
l'état et l'IP sont visibles
attach fonctionne pour l'administration
le nom du conteneur et la distribution sont documentés
Documentation privée: LXC

Snapshots et backup

Commandes anonymisées

lxc-snapshot -n <container-name> -c <snapshot-name>
lxc-snapshot -n <container-name> -L
lxc-snapshot -n <container-name> -r <snapshot-name>
lxc-copy -n <container-name> -N <clone-name>
tar czf <backup-archive> -C <lxc-root> <container-name>

État attendu

le snapshot est nommé avant les changements risqués
la restauration est testée avant d'en dépendre
le clone est indépendant si nécessaire
l'archive de backup est stockée hors du chemin du conteneur
Travail réalisé

Décisions techniques publiables.

Démarrage non privilégié

La configuration conserve les mappings subuid/subgid et traite les permissions nécessaires sans basculer vers un conteneur privilégié.

Diagnostic réseau

La délégation de l'interface virtuelle, le bridge, le namespace et la résolution DNS sont contrôlés dans cet ordre.

Service démontré

nginx est installé dans le système invité, placé en écoute et validé par une réponse HTTP 200.

Validation

Preuves et contrôles retenus.

Preuves visuelles

Contrôles observables et portée de la preuve.

Résultats publics

Ce que le chantier démontre.

Anonymisation

Ce qui reste privé.

  • Pas de noms réels de conteneurs, sous-réseaux, chemins de montages ou IP privées.
  • Pas de scripts de backup complets avec chemins personnels.
  • Pas de règles firewall finales copiables telles quelles.
  • Les exemples utilisent des placeholders et des rôles génériques.
Sources privées

Documentation d'origine.

  • Guide LXC sur Arch Linux.
  • Documentation virtualisation du homelab.
  • Guides sécurité AppArmor et hardening.
  • Notes backup et migration de conteneurs.

LXC sur Arch Linux

Référence publique pour comprendre et prolonger le lab LXC sur Arch Linux. La campagne démontrée couvre le conteneur non privilégié, le réseau, le DNS et nginx. Les sections consacrées aux snapshots, sauvegardes, migrations et démarrage automatique décrivent les prochaines validations; elles ne sont pas présentées comme déjà réalisées.

Qu'est-ce que LXC ?

LXC est une virtualisation au niveau du système d'exploitation permettant d'exécuter plusieurs systèmes Linux isolés sur un même hôte.

TechnologieTypeIsolationCas d'usage
KVM/QEMUVM complèteHyperviseurOS différents, isolation maximale
LXCConteneur systèmeNamespaces + cgroupsServeurs Linux légers
DockerConteneur applicatifProcessus isolésApplications packagées

Les cas d'usage typiques sont les serveurs de développement, environnements de test, services système isolés et services sensibles à isoler sans lancer une VM complète.

Prérequis

  • Arch Linux à jour.
  • Noyau Linux avec cgroups v2.
  • Architecture compatible.
  • Accès root ou sudo pour les opérations système.
mount | grep cgroup
ls -la /proc/self/ns/

Installation

Installer LXC et dépendances

sudo pacman -S lxc lxd arch-install-scripts debootstrap

Configurer le réseau

sudo pacman -S bridge-utils dnsmasq

Créer un bridge dédié avec systemd-networkd ou dnsmasq. Les valeurs réseau exactes restent privées.

[NetDev]
Name=<LXC_BRIDGE>
Kind=bridge
[Match]
Name=<LXC_BRIDGE>

[Network]
Address=<LXC_BRIDGE_CIDR>
DHCPServer=yes
IPMasquerade=yes
sudo systemctl enable systemd-networkd
sudo systemctl start systemd-networkd

Configuration LXC par défaut

lxc.net.0.type = veth
lxc.net.0.link = <LXC_BRIDGE>
lxc.net.0.flags = up
lxc.net.0.hwaddr = <LXC_MAC_TEMPLATE>
lxc.apparmor.profile = generated
lxc.apparmor.allow_nesting = 1

Utilisateurs non-privilégiés

echo "$USER:<SUBUID_START>:<SUBUID_RANGE>" | sudo tee -a /etc/subuid
echo "$USER:<SUBGID_START>:<SUBGID_RANGE>" | sudo tee -a /etc/subgid
sudo usermod -aG lxc "$USER" 
lxc.idmap = u 0 <SUBUID_START> <SUBUID_RANGE>
lxc.idmap = g 0 <SUBGID_START> <SUBGID_RANGE>

Créer votre premier conteneur

Arch Linux

sudo lxc-create -n <CONTAINER_ARCH> -t download -- -d archlinux -r current -a amd64

Ubuntu

sudo lxc-create -n <CONTAINER_UBUNTU> -t download -- -d ubuntu -r <UBUNTU_RELEASE> -a amd64

Debian

sudo lxc-create -n <CONTAINER_DEBIAN> -t download -- -d debian -r <DEBIAN_RELEASE> -a amd64

Templates disponibles

sudo lxc-create -n <TEST_NAME> -t download -- --list

Gestion des conteneurs

sudo lxc-start -n <CONTAINER>
sudo lxc-start -n <CONTAINER> -d
sudo lxc-stop -n <CONTAINER>
sudo lxc-stop -n <CONTAINER> -t <TIMEOUT>
sudo lxc-ls -f
sudo lxc-ls --active

Accéder et inspecter

sudo lxc-attach -n <CONTAINER>
sudo lxc-attach -n <CONTAINER> -- /bin/bash
sudo lxc-info -n <CONTAINER>
sudo lxc-top

Supprimer

sudo lxc-stop -n <CONTAINER>
sudo lxc-destroy -n <CONTAINER>

Configuration avancée

Chaque conteneur possède un fichier de configuration. Les chemins réels restent privés.

<LXC_ROOT>/<CONTAINER>/config

Limiter les ressources

lxc.cgroup2.cpuset.cpus = <CPUSET>
lxc.cgroup2.cpu.max = <CPU_QUOTA>
lxc.cgroup2.memory.max = <MEMORY_LIMIT>
lxc.cgroup2.memory.swap.max = 0
lxc.cgroup2.io.max = <IO_LIMITS>

Partager des dossiers avec l'hôte

lxc.mount.entry = <HOST_PATH> <CONTAINER_ROOTFS>/<TARGET_PATH> none bind,create=dir 0 0

Réseau avancé

lxc.net.0.ipv4.address = <CONTAINER_IP>/<PREFIX>
lxc.net.0.ipv4.gateway = <LXC_GATEWAY>

Le port forwarding doit rester cohérent avec la politique firewall de l'hôte.

Snapshots et clonage

sudo lxc-snapshot -n <CONTAINER>
sudo lxc-snapshot -n <CONTAINER> -c <SNAPSHOT_NAME> "Description"
sudo lxc-snapshot -n <CONTAINER> -L
sudo lxc-snapshot -n <CONTAINER> -r <SNAPSHOT_NAME>
sudo lxc-snapshot -n <CONTAINER> -d <SNAPSHOT_NAME>

Cloner

sudo lxc-copy -n <CONTAINER> -N <CONTAINER_CLONE>
sudo lxc-copy -n <CONTAINER> -N <CONTAINER_CLONE> -s
sudo lxc-copy -n <CONTAINER> -N <NEW_CONTAINER> -s <SNAPSHOT_NAME>

Snapshot: état restaurable. Clone: conteneur indépendant.

Démarrage automatique

lxc.start.auto = 1
lxc.start.delay = <DELAY_SECONDS>
lxc.start.order = <START_ORDER>
lxc.group = <GROUP_NAME>
sudo lxc-autostart -g <GROUP_NAME>

Cas d'usage pratiques

  • Serveur web léger avec reverse proxy ou stack applicative.
  • Base de données isolée avec limites CPU/RAM.
  • Environnement de développement avec bind mount contrôlé.
sudo lxc-create -n <SERVICE_CONTAINER> -t download -- -d <DISTRO> -r <RELEASE> -a amd64
sudo lxc-start -n <SERVICE_CONTAINER>
sudo lxc-attach -n <SERVICE_CONTAINER> -- <INSTALL_COMMANDS>

Monitoring et statistiques

sudo lxc-top
sudo lxc-cgroup -n <CONTAINER> memory.current
sudo lxc-cgroup -n <CONTAINER> cpu.stat
sudo journalctl -M <CONTAINER>
sudo cat <LXC_LOG_PATH>/<CONTAINER>.log

Sauvegardes

sudo lxc-stop -n <CONTAINER>
sudo tar czf <BACKUP_ARCHIVE> -C <LXC_ROOT> <CONTAINER>
sudo lxc-start -n <CONTAINER>

Restauration

sudo tar xzf <BACKUP_ARCHIVE> -C <LXC_ROOT>
sudo lxc-start -n <CONTAINER>

Les scripts automatiques doivent gérer arrêt, archive, redémarrage, rétention et journalisation sans exposer les chemins privés.

Migration de conteneurs

sudo lxc-stop -n <CONTAINER>
sudo tar czf <EXPORT_ARCHIVE> -C <LXC_ROOT> <CONTAINER>
sudo tar xzf <EXPORT_ARCHIVE> -C <TARGET_LXC_ROOT>
sudo lxc-start -n <CONTAINER>

Après import, vérifier réseau, mappings uid/gid, chemins montés et limites de ressources.

Sécurité

  • Préférer les conteneurs non-privilégiés.
  • Activer AppArmor quand disponible.
  • Retirer les capacités dangereuses.
  • Limiter le trafic entre conteneurs via firewall.
lxc.apparmor.profile = generated
lxc.cap.drop = sys_module sys_rawio
lxc.cap.drop = sys_boot

Dépannage

sudo cat <LXC_LOG_PATH>/<CONTAINER>.log
sudo journalctl -u lxc
sudo lxc-checkconfig
sudo lxc-start -n <CONTAINER> -F
ip addr show <LXC_BRIDGE>
ip route
cat /etc/subuid
cat /etc/subgid
sudo lxc-cgroup -n <CONTAINER> memory.current

Comparaison LXC vs Docker

AspectLXCDocker
TypeConteneur systèmeConteneur applicatif
Initsystemd/OpenRC completProcessus applicatif
UsageVM Linux légèreMicroservices et packaging
RéseauConfiguration plus manuelleAbstrait et simplifié
ContrôleFin et proche systèmeÉcosystème riche

Checklist LXC

  • Installer LXC et configurer le réseau.
  • Créer un premier conteneur.
  • Configurer les limites de ressources.
  • Tester snapshots et clonage.
  • Configurer autostart, backups et migration.
  • Valider sécurité, AppArmor et firewall.

Débogage appliqué dans le lab

Cette séquence remonte du symptôme à la preuve finale sans exposer le chemin utilisateur, les adresses privées ou le nom du compte hôte.

Vérification de l'hôte

lxc-checkconfig
command -v newuidmap
command -v newgidmap
ip addr show <LXC_BRIDGE>

Préparation non privilégiée

mkdir -p "$HOME/.config/lxc"
printf '%s\n' \
  'lxc.include = /etc/lxc/default.conf' \
  'lxc.idmap = u 0 <SUBUID_START> <SUBUID_RANGE>' \
  'lxc.idmap = g 0 <SUBGID_START> <SUBGID_RANGE>' \
  > "$HOME/.config/lxc/default.conf"
echo '<OPERATOR> veth <LXC_BRIDGE> 1' | sudo tee /etc/lxc/lxc-usernet

Création et contrôle d'état

lxc-create -P <LXC_PATH> -n <CONTAINER> -f <LXC_CONFIG> -t download -- -d debian -r bookworm -a amd64
XDG_RUNTIME_DIR=<RUNTIME_DIR> lxc-start -P <LXC_PATH> -n <CONTAINER> -d
XDG_RUNTIME_DIR=<RUNTIME_DIR> lxc-ls -P <LXC_PATH> -f
XDG_RUNTIME_DIR=<RUNTIME_DIR> lxc-info -P <LXC_PATH> -n <CONTAINER> -p

Namespace du système invité

sudo nsenter -t <CONTAINER_PID> -m -u -i -n -p -- /bin/sh
sudo nsenter -t <CONTAINER_PID> -m -u -i -n -p -- uname -a
sudo nsenter -t <CONTAINER_PID> -m -u -i -n -p -- ip a
sudo nsenter -t <CONTAINER_PID> -m -u -i -n -p -- ip route

DNS et service

printf 'nameserver <DNS_SERVER_IP>\n' > /etc/resolv.conf
printf '<DEBIAN_MIRROR_IP> deb.debian.org\n<DEBIAN_MIRROR_IP> deb.debian.org.\n' >> /etc/hosts
apt update
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
apt install -y nginx
nginx -g 'pid /tmp/nginx.pid;'
ss -lntp | grep ':80'
curl -I http://<CONTAINER_IP>

Ordre de débogage retenu

  1. Vérifier le support LXC côté hôte.
  2. Valider newuidmap et newgidmap.
  3. Autoriser lxc-usernet sur le bridge retenu.
  4. Créer le conteneur non privilégié.
  5. Confirmer le PID et le namespace réseau.
  6. Corriger le DNS et la résolution locale.
  7. Installer le service.
  8. Placer le fichier PID hors de /run si nécessaire.
  9. Valider la réponse HTTP depuis l'hôte.