Docker : Sécuriser l’accès avec un Docker Socket Proxy

Docker : Comment améliorer la sécurité avec un Docker Socket Proxy ?

La gestion des conteneurs Docker est devenue une pratique courante dans le développement et le déploiement d’applications. Cependant, exposer le socket Docker directement à un conteneur peut poser des problèmes de sécurité. Ce tutoriel explique comment améliorer la sécurité avec un Docker Socket Proxy, une solution élégante pour filtrer et contrôler les accès à l’API Docker. En pratique, le Docker Socket Proxy agit comme un intermédiaire, autorisant uniquement les commandes nécessaires à vos conteneurs et bloquant les autres, renforçant ainsi la sécurité de votre environnement.

En bref

Vous souhaitez sécuriser l’accès à votre API Docker ? Un Docker Socket Proxy filtre les requêtes, limitant ainsi les risques. Ce tutoriel explique comment améliorer la sécurité avec un Docker Socket Proxy en configurant un proxy qui autorise uniquement les commandes nécessaires à vos conteneurs, empêchant ainsi les accès non autorisés et renforçant la sécurité de votre environnement Docker.

Prérequis

Avant de commencer, assurez-vous de disposer des éléments suivants :

  • Un serveur avec Docker installé et fonctionnel.
  • Docker Compose installé (recommandé).
  • Une connaissance de base des commandes Docker et Docker Compose.

Pourquoi utiliser un Docker Socket Proxy ?

comment améliorer la sécurité avec un Docker Socket Proxy

Exposer directement le socket Docker (/var/run/docker.sock) à un conteneur donne à ce conteneur un accès illimité à l’API Docker. Cela signifie que le conteneur peut potentiellement contrôler l’ensemble de l’environnement Docker, y compris démarrer, arrêter ou supprimer d’autres conteneurs, voire accéder au système hôte. C’est un risque de sécurité majeur, surtout si le conteneur exécute du code non fiable.

comment améliorer la sécurité avec un Docker Socket Proxy

Un Docker Socket Proxy agit comme un pare-feu pour l’API Docker. Il intercepte toutes les requêtes adressées au socket Docker et les filtre en fonction de règles prédéfinies. Seules les requêtes autorisées sont transmises à l’API Docker, tandis que les autres sont bloquées. Cela permet de limiter l’impact d’une éventuelle compromission d’un conteneur.

Installation et configuration du Docker Socket Proxy

Nous allons utiliser l’image Tecnativa/docker-socket-proxy, une solution populaire et bien maintenue.

  1. Créer un fichier docker-compose.yml : Créez un fichier docker-compose.yml avec le contenu suivant :

    comment améliorer la sécurité avec un Docker Socket Proxy
    version: "3.8"
    services:
      docker-socket-proxy:
        image: tecnativa/docker-socket-proxy
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock:ro
        environment:
          - DOCKER_SOCKET_PROXY_WHITELISTED_ROUTES=GET|/containers/json,GET|/containers/.*/json,GET|/images/json
        ports:
          - "2375:2375"
        restart: always

    Ce fichier définit un service appelé docker-socket-proxy qui utilise l’image tecnativa/docker-socket-proxy. Le volume /var/run/docker.sock:/var/run/docker.sock:ro monte le socket Docker en lecture seule dans le conteneur. L’environnement DOCKER_SOCKET_PROXY_WHITELISTED_ROUTES définit les routes autorisées (nous y reviendrons). Enfin, le port 2375 est exposé pour accéder au proxy.

  2. Définir les routes autorisées : La variable d’environnement DOCKER_SOCKET_PROXY_WHITELISTED_ROUTES est cruciale. Elle définit les routes de l’API Docker que le proxy autorisera. Dans l’exemple ci-dessus, nous autorisons :

    • GET|/containers/json : Récupérer la liste des conteneurs.
    • GET|/containers/.*/json : Récupérer les informations d’un conteneur spécifique.
    • GET|/images/json : Récupérer la liste des images.

    Adaptez cette liste en fonction des besoins de vos conteneurs. Par exemple, si un conteneur doit pouvoir redémarrer d’autres conteneurs, vous devrez ajouter la route POST|/containers/.*/restart.

  3. Démarrer le proxy : Exécutez la commande docker-compose up -d dans le répertoire contenant le fichier docker-compose.yml. Cela démarrera le conteneur Docker Socket Proxy en arrière-plan.

Utilisation du Docker Socket Proxy

Pour utiliser le Docker Socket Proxy, vous devez configurer vos conteneurs pour qu’ils utilisent le proxy au lieu du socket Docker directement. Voici comment procéder :

  1. Modifier la configuration de vos conteneurs : Au lieu de monter le volume /var/run/docker.sock directement dans vos conteneurs, vous devez configurer vos conteneurs pour qu’ils communiquent avec le proxy sur le port 2375. Cela peut se faire en utilisant la variable d’environnement DOCKER_HOST.

  2. Exemple : Si votre conteneur s’exécute sur le même hôte que le proxy, vous pouvez définir la variable DOCKER_HOST à tcp://localhost:2375. Si le conteneur s’exécute sur un autre hôte, vous devez utiliser l’adresse IP ou le nom d’hôte du serveur exécutant le proxy.

    Par exemple, dans un fichier docker-compose.yml :

    version: "3.8"
    services:
      mon-conteneur:
        image: mon-image
        environment:
          - DOCKER_HOST=tcp://localhost:2375

Tester le Docker Socket Proxy

Pour vérifier que le Docker Socket Proxy fonctionne correctement, vous pouvez utiliser la commande docker avec la variable DOCKER_HOST définie :

export DOCKER_HOST=tcp://localhost:2375
docker ps

Cette commande devrait afficher la liste des conteneurs en cours d’exécution. Si vous essayez d’exécuter une commande non autorisée par le proxy, vous devriez obtenir une erreur.

Sécuriser davantage le Docker Socket Proxy

Bien que le Docker Socket Proxy améliore considérablement la sécurité, il est possible de le renforcer davantage :

  • Utiliser TLS : Configurez le proxy pour utiliser TLS (Transport Layer Security) afin de chiffrer les communications entre les conteneurs et le proxy. Cela empêche l’interception des données sensibles.

  • Authentification : Ajoutez une authentification au proxy pour contrôler qui peut accéder à l’API Docker. Cela peut se faire en utilisant des certificats clients ou un système d’authentification basé sur un jeton.

  • Limiter l’accès au réseau : Configurez votre pare-feu pour autoriser uniquement les conteneurs autorisés à accéder au port du proxy.

Dépannage

Voici quelques problèmes courants et leurs solutions :

  • Erreur de connexion : Si vous ne parvenez pas à vous connecter au proxy, vérifiez que le conteneur proxy est en cours d’exécution et que le port 2375 est accessible.

  • Commandes bloquées : Si une commande est bloquée par le proxy, vérifiez que la route correspondante est bien autorisée dans la variable DOCKER_SOCKET_PROXY_WHITELISTED_ROUTES.

  • Problèmes de permissions : Assurez-vous que le socket Docker est accessible en lecture seule par le conteneur proxy.

Conclusion

L’utilisation d’un Docker Socket Proxy est une excellente façon d’améliorer la sécurité de votre environnement Docker. En filtrant les requêtes adressées à l’API Docker, vous pouvez limiter l’impact d’une éventuelle compromission d’un conteneur et protéger votre infrastructure. N’oubliez pas d’adapter la configuration du proxy à vos besoins spécifiques et de mettre en œuvre les mesures de sécurité supplémentaires pour une protection optimale.

Questions frequentes

Comment sécuriser l’accès à l’API Docker ?

Un Docker Socket Proxy permet de filtrer les requêtes envoyées à l’API Docker. En définissant des règles strictes sur les commandes autorisées, on limite les risques liés à une compromission de conteneur.

Quelles sont les routes API Docker à autoriser dans le Docker Socket Proxy ?

Cela dépend des besoins de vos conteneurs. Généralement, GET|/containers/json, GET|/containers/.*/json et GET|/images/json sont un bon point de départ. Adaptez cette liste en fonction des commandes que vos conteneurs doivent exécuter.

Comment tester si le Docker Socket Proxy fonctionne correctement ?

Définissez la variable d’environnement DOCKER_HOST pour pointer vers le proxy (par exemple, tcp://localhost:2375) et exécutez des commandes Docker. Vérifiez que les commandes autorisées fonctionnent et que les commandes non autorisées sont bloquées.