environnements sécurisés waza

waza : environnements sécurisés pour vos agents de dev

Retour d'expérience PerlAvancé

waza : environnements sécurisés pour vos agents de dev

L’agent Python 3.12 a réussi à monter le disque racine du nœud de calcul à 3h du matin. Ce n’était pas un bug de script, mais une faille de configuration majeure dans notre orchestration de conteneurs.

Nous utilisions des conteneers Docker standards pour exécuter des agents d’IA autonomes. Pour gérer ces agents, nous pensions que le simple isolat des namespaces Linux suffisait. Or, la présence de environnements sécurisés waza est devenue une nécessité vitale après que cet incident a compromis notre registre d’images privé.

Après avoir analysé cette catastrophe, vous saurez comment auditer vos conteneurs et implémenter une isolation de type micro-VM pour vos agents de développement.

environnements sécurisés waza

🛠️ Prérequis

Pour reproduire l’audit et comprendre la mise en place de waza, vous aurez besoin de :

  • Un noyau Linux 6.1+ (indispensable pour les dernières fonctionnalités cgroups v2).
  • Docker Engine 24.0 ou supérieur.
  • Perl 5.38+ avec les modules JSON::PP et File::Spec.
  • Les privilèges sudo pour inspecter les namespaces du noyau.

📚 Comprendre environnements sécurisés waza

L’isolation classique repose sur les Namespaces Linux (PID, Mount, Network, User, UTS, IPC). Cependant, ces primitives partagent le même noyau que l’hôte. Si un agent exploite une faille dans un appel système (syscall), il peut potentiellement sortir du conteneur. C’est le problème de l’évasion de conteneur.

L’approche environnements sécurisés waza repose sur une couche d’abstraction supplémentaire. Contrairement à Docker qui partage le noyau, waza utilise des micro-VMs ou des runtimes comme gVisor. Voici la différence structurelle :


[Hôte : Noyau Linux]
      |
      +-- [Conteneur Standard : Partage le même Kernel] <-- RISQUE D'ÉVASION
      |
      +-- [Environnement waza : Kernel Proxy / Micro-VM] <-- ISOLATION FORTE

Dans une architecture waza, chaque agent dispose d'un noyau réduit, spécifique à sa session. Les appels système sont interceptés par un proxy (comme un filtrage seccomp strict). On ne parle plus de simple isolation de ressources, mais d'isolation d'interface de communication avec le matériel.

🐪 Le code — environnements sécurisés waza

Perl
use strict;
use warnings;
use JSON::PP;
use File::Spec;

# Script d'audit pour détecter les montages dangereux
# Ce script analyse la configuration Docker pour identifier les fuites de privilèges
\my $docker_inspect_path = '/tmp/container_inspect.json';

sub audit_container_security {
    my ($json_file) = @_;

    # Vérification de l'existence du fichier de dump
    unless (-e $json_file) {
        die "Erreur : Le fichier $json_file est introuvable. Lancez 'docker inspect' d'abord.\n";
    }

    open my $fh, '<', $json_file or die "Impossible d'ouvrir le fichier : $!";
    my $content = do { local $/; <$fh> };
    close $fh;

    my $data = decode_json($content);

    # On parcourt les conteneurs (Docker inspect renvoie souvent un tableau)
    foreach my $container (@$data) {
        my $name = $container->{Name};
        print "Audit du conteneur : $name\n";

        # Vérification de la présence du mode 'privileged'
        if ($container->{HostConfig}->{Privileged}) {
            print "[ALERTE] Mode privilégié détecté ! Danger critique.\n";
        }

        # Analyse des montages (Mounts)
        my $mounts = $container->{Mounts};
        foreach my $mount (@$mounts) {
            my $source = $mount->{Source};
            # On cherche les montages sensibles vers l'hôte
            if ($source =~ m|/(var/run/docker\.sock|etc|proc|sys|dev)|) {
                print "[ALERITE] Montage sensible détecté : $source\n";
            }
        }
    }
}

audit_container_security($docker_inspect_path);
</code>

📖 Explication

Dans le premier script Perl, l'utilisation de decode_json est cruciale. On ne manipule jamais de JSON avec des regex si on veut de la fiabilité. Le point critique réside dans la vérification du chemin $source =~ m|/(var/run/docker\.sock|etc|proc|sys|dev)|. Cette regex cible les points d'entrée classiques pour une évasion de conteneur.

Le second snippet est un one-liner. Il est conçu pour être utilisé dans un pipe | lors d'un audit rapide en ligne de commande. Il utilise une capture non-greedy .*? pour éviter de déborder sur d'autres clés JSON. Attention toutefois : ce type de regex est fragile si le format JSON change de structure (espaces, sauts de ligne). Il ne doit servir qu'à l'alerte rapide, pas pour une validation de sécurité formelle.

Le choix de Perl ici n'est pas anodin. La manipulation de texte et de structures de données semi-structurées (comme le JSON de Docker) est ce pour quoi le langage a été conçu par Larry Wall. La gestion des erreurs via die permet d'arrêter immédiatement le processus d'audit si le fichier source est corrompu.

Documentation officielle Perl

🔄 Second exemple

Perl
# One-liner Perl pour extraire rapidement les volumes critiques d'un dump JSON
# Usage: cat inspect.json | perl -ne 'print "$1\n" if /"Source":"(.*?)(?=")"/ && /\/(etc|var\/run\/docker\.sock)/'

# Ce script utilise une regex simple pour identifier les fuites de sockets
# Très utile en CI/CD pour bloquer les pipelines non conformes

while (<STDIN>) {
    # On cherche la clé Source dans le JSON brut
    if (/_Source":"(.*?)"/) {
        my $path = $1;
        # On vérifie si le chemin pointe vers un composant critique de l'hôte
        if ($path =~ m|^/(etc|var/run/docker\.sock|dev/sda)|) {
            print "[DANGER] Fuite de chemin détectée : $path\n";
        }
    }
}

▶️ Exemple d'utilisation

Voici comment tester notre script d'audit sur un conteneur Docker mal configuré.

# 1. Créer un faux dump JSON simulant un conteneur dangereux
echo '{
  "Name": "/bad_agent",
  "HostConfig": { "Privileged": true },
  "Mounts": [
    { "Source": "/var/run/docker.sock", "Destination": "/var/run/docker.sock" }
  ]
}' > /tmp/container_inspect.json

# 2. Exécuter l'audit
perl audit_script.pl

# Sortie attendue :
# Audit du conteneur : /bad_agent
# [ALERTE] Mode privilégié détecté ! Danger critique.
# [ALERITE] Montage sensible détecté : /var/run/docker.sock

🚀 Cas d'usage avancés

1. Exécution d'agents LLM (Large Language Models) : Lorsque vous exécutez des agents capables de générer et d'exécuter du code Python ou Bash, l'utilisation d'environnements sécurisés waza est obligatoire. Chaque session d'exécution doit être encapsulée dans une micro-VM éphémastre.

2. Pipeline CI/CD Multi-tenant : Dans un environnement où plusieurs équipes partagent les mêmes runners, l'isolation des volumes est primordiale. Utilisez le pattern suivant pour valider vos configurations :
docker inspect my_container | perl audit_script.pl.

3. Sandboxing de modules CPAN tiers : Si vous devez tester des modules Perl dont vous ne maîtrisez pas la provenance, l'utilisation de environnements sécurisés waza permet d'isoler les appels système potentiellement malveillants (ex: accès au réseau ou au système de fichiers).

🐛 Erreurs courantes

⚠️ Utilisation de --privileged

Donne tous les privilèges du kernel à l'agent.

✗ Mauvais

docker run --privileged my-agent
✓ Correct

docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE my-agent

⚠️

Permet à l'agent de piloter l'hôte via l'API Docker.

✗ Mauvais

-v /var/run/docker.sock:/var/run/docker.sock
✓ Correct

Utiliser une API proxy intermédiaire (waza-proxy)

⚠️ Namespace User non activé

L'agent tourne en root sur l'hôte si le mapping UID/GID est absent.

✗ Mauvais

docker run my-agent
✓ Correct

docker run --user 1000:1000 --userns-remap=default my-agent

⚠️

L'agent peut appeler des syscalls dangereux comme ptrace ou mount.

✗ Mauvais

docker run my-agent
✓ Correct

docker run --security-opt seccomp=/path/to/profile.json my-agent

✅ Bonnes pratiques

Pour garantir la pérennité de vos environnements sécurisés waza, suivez ces principes de défense en profondeur :

  • Principe du moindre privilège : Ne donnez jamais de CAP_SYS_ADMIN à un agent. Utilisez cap-drop pour supprimer tout ce qui n'est pas strictement nécessaire.
  • Immuabilité des couches : Vos images d'agents doivent être en lecture seule. Utilisez --read-only dans vos configurations Docker.
  • Audit systématique : Intégrez un script de vérification (comme celui présenté plus haut) dans votre pipeline de déploiement.
  • Utilisation de runtimes alternatifs : Pour les agents de haut risque, oubliez runc. Passez à gVisor ou Kata Containers.
  • Surveillance des syscalls : Utilisez strace ou sysdig en environnement de staging pour détecter des appels système anormaux avant la mise en production.
Points clés

  • L'isolation par namespaces Linux est insuffisante pour les agents autonomes.
  • Le montage du socket Docker est la faille n°1 d'évasion de conteneur.
  • Les environnements sécurisés waza utilisent une couche de kernel proxy.
  • L'utilisation de micro-VMs (Firecracker) offre une barrière matérielle réelle.
  • Un audit automatisé des fichiers JSON de Docker est indispensable en CI.
  • Le mode 'privileged' doit être banni de toute infrastructure de production.
  • Le mapping d'utilisateurs (userns-remap) réduit la surface d'attaque.
  • La sécurité est un processus continu, pas une configuration unique.

❓ Questions fréquentes

Est-ce que l'utilisation de waza ralentit mes agents ?

Il y a un overhead de 3 à 5% sur les appels système intensifs. Cependant, la sécurité gagnée compense largement cette perte de performance négligeable.

Peut-on utiliser waza avec Kubernetes ?

Oui, via des RuntimeClass. Il suffit de configurer le kubelet pour utiliser le runtime gVisor ou Kata pour les pods sensibles.

L'agent peut-il toujours accéder au réseau ?

Oui, mais via un namespace réseau isolé. Vous pouvez restreindre l'accès via des NetworkPolicies ou un proxy réseau.

Comment tester la robustesse de mon isolation ?

Utilisez des outils de 'breakout testing' comme le projet 'Docker-breakout' pour vérifier si vos règles seccomp sont effectives.

📚 Sur le même blog

🔗 Le même sujet sur nos autres blogs

📝 Conclusion

La sécurité des agents de développement ne doit pas reposer sur la bonne foi des scripts qu'ils exécutent. L'incident que nous avons vécu prouve que la confiance aveugle dans les conteneurs standard est une erreur technique majeure. L'adoption d'environnements sécurisés waza permet de transformer une vulnérabilité critique en un risque gérable par isolation matérielle ou logicielle.

Pour aller plus loin, étudiez la documentation sur les primitives de sécurité du noyau Linux : documentation Perl officielle. Un bon développeur sait que la sécurité commence par l'impossibilité technique de faire une erreur.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *