Docker et vous :)

Salut tout le monde :partying_face:

Je sais que beaucoup d’entre vous utilise docker en perso et/ou pro.
J’ai bientôt une infra de test à faire sur docker et donc pas mal de question sur votre utilisation. :slight_smile:

En lisant les recommandations de l’ANSSI j’avais pu voir des petits trucs coté sécu :

  • remap uid
  • unprivileged

Remap

Pour le remap uid, si on prends lxc, à partir du moment ou on le met unprivilege :

  • user lxc = 1000, user host = 101000

Donc en cas d’échapemment pas de soucis. Est-ce que c’est quelque chose que vous utilisez beaucoup ? systématiquement ?

Unprivileged

Est-ce que vous l’utilisez beaucoup ? Dans ma vision, il ne devrait jamais tourner avec les privilege fuul. Si par exemple y’a besoin des 4 ports usb, je préfere les mettres spécifiquement

Stockage

De souvenir, un docker est volatile, les data applicative doivent être binder à l’intérieur. Donc forcément elles doivent être stocker ailleurs. Comment gérez-vous cette partie ? Exportez-vous vos logs par exemple ?

Cloud

Est-ce que vous utilisez du cloud public ? cloud privé ?

Je vais partir sur un auto-hébergement infra / image etc en limitant les dépendances externes au strict minimum. Du coup je suis tombé sur OKD il y a peu, ça parait pas trop mal

https://www.okd.io/

Si quelqu’un a des recommandations je suis prenneur :slight_smile:

L’idée final c’est de proposer une plateforme a quelques developpeur et qu’ils puissent être autonome avec le déploiement d’image.

En gros… si vous pouvez partager votre expériences docker, vos utilisattions, vos besoins / contraintes ça me permettra de faire un tour d’horizon.

Les personnes pour qui je vais faire ça veulent utiliser docker, mais je ne penses pas qu’elles aient en tête les fonctionnalitées type HA en tête etc :slight_smile:

Merci à vous !

En contexte privé ou pro ?

Les deux sont interessant.

Ma solution va etre mise dans le cadre pro, d’ou l’aspect sécu avant tout :slight_smile:

Salut

J’avais jamais vu ton post désolé !

De mon côté en perso j’utilise Docker avec plusieurs options pour retirer les droits root par défaut.

Pour cela :

  1. Option user namespace (le remap de UID et GID)
    C’est top car un processus en root dans le conteneur n’est enfin plus root sur ton OS. C’est d’ailleurs ce qu’utilise les plateformes de CI/CD publiques je crois.
    Seul inconvénient : certaines applications doivent être adaptées pour ne pas utiliser les ports a privilèges comme le port 80 ou 443 ou certaines actions système ne fonctionneront pas (comme créer une carte réseau)

  2. Supprimer toutes les CAPABILITIES par défaut avec drop_cap=all puis ajouter uniquement celles qui sont nécessaires.

  3. Limiter les performances max du conteneur en CPU, RAM et nombre de processus lancés.
    Cela évite qu’un conteneur qui bug ou est compromis utilise toutes les ressources de l’hôte.

  4. Installer docker dans sa version userland, sans le daemon qui s’exécute en root. C’est radical mais meilleur en sécurité.

Voilà ce a quoi je pensais pour le moment :sweat_smile:

Un exemple de Docker-compose avec ces éléments sans la partie limitation des pids :

Pas de soucis :slight_smile:

C’est ce que j’utilise aussi avec LXC

Merci ça va sans doute m’être utile

Je risque de falre un lab peut être avant la fin de l’année sur OKD d’ici la fin d’année voir comment ça se présente.

Vu que l’on va fournir les images docker personnalisés aux dev, avec des custom apache, php, php-fpm etc etc, je vois une problématique qui peu se poser.

Par exemple, si il y a une image apache2/php7.4 avec certains modules php. Si pour tel projet un dev a besoin d’une extension qui n’est pas dedans, un autre dev c’est une autre extension… ça risque de devenir ingérable. Cela reviendrait a faire une image par projet. J’ai un peu de mal a visualiser cette partie.

Justement, en général c’est ce paradigme qui est utilisé.

Un projet = une image docker.

C’est le dev du projet qui conçoit son image Docker et qui fait évoluer son Dockerfile au fur et à mesure de l’évolution du projet.

Le Dockerfile est traité comme n’importe quel fichier de code, tout comme tu ajoutes des dépendances au package.json (ou équivalent pour les projets PHP), tu ajoutes des dépendances systèmes au Dockerfile au fil de l’évolution du projet.

1 Like

Dans notre cas non, on est plutôt dans le rôle de l’hébergeur et donc la configuration serveur web, mail ou autres, s’il y a une faille dedans c’est pour nous. C’est plus une histoire de périmètre et responsabilité.

Aujourd’hui, on livre des VM pour accueillir le code suivant leurs besoin. Je commence a travailler avec Ansible pour automatiser le process de construction de la VM. Demain, ils veulent commencer à utiliser docker sur une plateforme de lab pour voir ce qu’ils peuvent faire. Donc forcément ce principe ou l’image est mise à dispo par l’hébergeur restera. Ce qui risque d’être compliqué :slight_smile:

Ah je vois ok ! :slight_smile: Je pensais que tu parlais de développement en interne, dans ce cas oui c’est à toi de faire une image assez exhaustive pour que ça convienne à tout le monde, ou alors proposer plusieurs versions avec différents niveaux d’exhaustivités suivant les projets

Ce serait plutôt le second cas. Il va y avoir beaucouuuupp de discussion pour trouver une organisation.

Même avec plusieurs images c’est compliqué. Dans le sens ou tu peux avoir un projet qui a besoin de exec, ce qui n’est pas recommandé de base.
Donc tu mets une image avec exec et une sans et forcément le dev peut faire son choix.

Pour exec on fonctionne bloqué par défaut, si vraiment y’a besoin on avertis sur le risque et on active. Si le dev peut faire son choix, j’ai peur que ça devienne de la consommation d’image sans forcément avoir conscience du risque de celles-ci etc etc.

Sans tomber dans la caricature, j’ai déjà vu un dev faire un chmod 777 parce qu’il était bloqué … Euhhhhhhhh :nauseated_face: :crazy_face:

Hardening

Là dessus, tu as bien fait de lire les recommandations de l’ANSSI. Je peux te recommander celles du CIS BENCHMARK aussi (docker mais aussi toute sorte de systèmes).

Remap

Ca se passe niveau configuration de Docker directement. Exemple de ma config :

/etc/docker/daemon.json

{
     "dns": ["9.9.9.9", "1.0.0.1"],
     "live-restore": true,
     "log-level": "debug",
     "max-concurrent-downloads": 30,
     "selinux-enabled": true,
     "no-new-privileges": true,
     "userland-proxy": false,
     "userns-remap" : "default"
}

Unprivileged

Je voudrais ajouter qu’il existe aussi une suite de micro exécutables super pratique pour adresser cette problématique : GitHub - just-containers/s6-overlay: s6 overlay for containers (includes execline, s6-linux-utils & a custom init)

En résumé, ce projet permet de créer des conteneurs qui vont exécuter une suite d’actions en root si besoin (changer des permissions, créer certains fichier spécifiques, créer un utilisateur simple dans le conteneur, etc.) puis exécuter le programme qui doit être lancé dans le conteneur avec les privilèges les plus bas.
C’est très bien pensé et bien pratique. C’est ce que j’utilise dans mon image ici : Dockerfiles/seedbox/flood at master · LM1LC3N7/Dockerfiles · GitHub

Stockage

Je te confirme, par défaut le stockage dans un conteneur n’est pas persistant. C’est l’idée des volumes docker, garder du stockage même après la suppression d’un conteneur.
L’avantage c’est que tu peux faire rm -rf /, ça ne fera rien sur le serveur hôte (mais ton conteneur sera HS).
La plupart de mes applications doivent utiliser du stockage persistant, pour les bases de données par exemple.
Je le gère un peu dans l’esprit de Docker : un conteneur = un processus.

Donc pour un blog qui a une partie serveur web et une partie base de données, j’ai deux conteneurs :

  1. Serveur web, avec les fichiers html, JS, images, etc.
    Rien n’est persistant (car embarqué dans l’image), sauf le dossier logs, uploads et images, qui sont amené à changer.
  2. La base de données.
    Même idée, rien n’est persistant sauf le dossier qui stocke les fichiers de base de données (par exemple /var/lib/mysql.

Mon serveur utilise une distribution gratuite basée sur RedHat (Oracle Linux), qui intègre par défaut SELinux. Cela permet de protéger les volumes, pour qu’un conteneur ne puisse pas s’échapper ou lire des fichiers restreints sur le système. Ca marche très bien d’ailleurs !

Plateforme

Vu que c’est du perso, j’utilise un serveur dédié chez Online.net (maintenant Scaleway.fr). Mais il est possible d’utiliser des instances cloud Kubernetes par exemple, ou directement de la création de conteneurs avec AWS, Azure, Google Cloud, etc.