Journal Comment sécurisez-vous les images docker externes ?

Posté par  . Licence CC By‑SA.
11
4
nov.
2022

je ne sais pas si cette question mérite vraiment un journal, j'ai le sentiment (ou du moins j'ose espérer) qu'il existe une réponse triviale que je ne connais pas

images d'application

Parlons d'abord des images d'application présentes sur dockerhub (ou autre registre d'images).

Typiquement le dockerfile d'une appli lambda commence par FROM debian:stable (ignorons les autres distributions pour la simplicité du raisonnement, qui s'appliquera aussi aux autres) puis contient une série d'instructions comme RUN. Au moment de la sortie d'une nouvelle version de l'application, les mainteneurs reconstruisent l'image docker, et les versions de toutes les dépendances (paquets debian notamment) sont donc figées à ce moment là. Si le lendemain, debian met à jour une des dépendance (par exemple mise à jour de sécurité), l'image figée n'en profite pas ! Cela n'implique pas forcément que la vulnérabilité est exploitable mais il convient de s'en prémunir.

Comment faire pour s'en prémunir ? Ne parlons pas de « les mainteneurs doivent reconstruire le paquet régulièrement », car quand bien même ça serait la bonne pratique à suivre en théorie, en pratique ce n'est pas le cas. J'ai d'abord pensé à mettre à jour les conteneurs en cours d'exécution comme un système ordinaire, lancer périodiquement docker exec -u root CONTENEUR sh -c "apt-get update && apt-get upgrade -y" mais ça coince au niveau du redémarrage : le processus principal du conteneur ne profiterait pas forcément de la mise à jour (par exemple les .so ne sont pas rechargés si le processus est en cours d'exécution).

j'ai pensé à un gros bricolage qui comblerait cette lacune mais je vais éviter de l'évoquer pour ne pas paraitre bête au cas où quelque chose de propre existerait déjà

Les images de base

De toute manière, les images de base (comme debian:stable) ne sont pas elles-mêmes reconstruites à chaque mise à jour de sécurité. Il faudrait donc placer un RUN apt-get update && apt-get upgrade -y au début de chaque Dockerfile (se servant de debian), et reconstruire l'image régulièrement ? En plus, cela forcerait à re-télécharger toutes les mises à jour à chaque reconstruction de l'image, sans profiter du système de cache en couches des images docker, ce qui est un peu du gaspillage. Un système traditionnel non-conteneurisé n'aurait pas tous ces défauts.

  • # trivy ou un autre scanner de vulnérabilités

    Posté par  (site web personnel) . Évalué à 7.

    j'aime bien Trivy, que je lance systématiquement après

    docker build

    https://github.com/aquasecurity/trivy

    mais il y a aussi Clair, Snyk et d'autres

    https://github.com/quay/clair

    https://snyk.io/docker/

    tu as une page sur ce sujet sur docker.com, et tu peux scanner des images du dockerhub

    https://docs.docker.com/develop/scan-images/

    ウィズコロナ

  • # Titre

    Posté par  . Évalué à 6.

    Cela n'implique pas forcément que la vulnérabilité est exploitable mais il convient de s'en prémunir.

    Il existe pleins d'outils pour faire des scan d'image docker (qui vont lire le dpkg status) et détecter celles avec des failles de sécurités. Ça te donne la liste d'image à reconstruire.

    Il faudrait donc placer un RUN apt-get update && apt-get upgrade -y au début de chaque Dockerfile (se servant de debian)

    Ou plus simplement, avoir une image de base qui le fait sur laquelle les autres images se basent.

    Mais sinon, tu dois quasiment avoir toujours un apt-get update au début de ton dockerfile sinon, tu ne pourras pas installé de paquet vu que tu n'aura pas le cache des images.

    Un système traditionnel non-conteneurisé n'aurait pas tous ces défauts.

    Je ne comprends pas trop ce que tu veux dire, dans les deux cas il faut faire des mises à jour.

    « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

    • [^] # Re: Titre

      Posté par  . Évalué à 3. Dernière modification le 04 novembre 2022 à 11:59.

      Il existe pleins d'outils pour faire des scan d'image docker (qui vont lire le dpkg status) et détecter celles avec des failles de sécurités.

      Je ne cherche pas à scanner mais à corriger les problèmes.

      Ça te donne la liste d'image à reconstruire.

      Je ne veux pas reconstruire les images à partir du dockerfile, ce sont des images externes que j'utilise, que je n'ai pas créées moi-même. Je veux un moyen de mettre à jour les distributions des images présentes sur dockerhub.

      Ou plus simplement, avoir une image de base qui le fait sur laquelle les autres images se basent.

      C'est ce que je dis dans le journal :

      De toute manière, les images de base (comme debian:stable) ne sont pas elles-mêmes reconstruites à chaque mise à jour de sécurité.

      Et

      Mais sinon, tu dois quasiment avoir toujours un apt-get update au début de ton dockerfile sinon, tu ne pourras pas installé de paquet vu que tu n'aura pas le cache des images.

      Je ne manipule aucun dockerfile, et je ne souhaite aucunement le faire, j'utilise uniquement des images existantes dans un docker-compose.yml.

      Un système traditionnel non-conteneurisé n'aurait pas tous ces défauts.

      Je ne comprends pas trop ce que tu veux dire, dans les deux cas il faut faire des mises à jour.

      Oui, sur un système non-conteneurisé, je fais les mises à jour de la distribution. Sur un système conteneurisé, je n'ai plus la main sur la distribution, et en pratique les images présentes sur dockerhub, même si elles faisaient les mises à jour à la construction de l'image, et bien ça serait à la date de la construction de l'image uniquement, pas chaque jour.

      • [^] # Re: Titre

        Posté par  . Évalué à 5.

        Je ne manipule aucun dockerfile, et je ne souhaite aucunement le faire,

        Le Dockerfile, c'est la manière de modifier une image de conteneur qui est censé être immutable dans les bonnes pratiques. Donc tu veux te reposer sur le travail des autres (ce n'est pas une critique, juste un constat). Dans ce cas, tu ne peux que faire confiance aux gens pour fournir un système à jour. De la même manière que si tu ajoute des repos hors distribution. Il n'y a pas de grand

        Oui, sur un système non-conteneurisé, je fais les mises à jour de la distribution. Sur un système conteneurisé, je n'ai plus la main sur la distribution, et en pratique les images présentes sur dockerhub, même si elles faisaient les mises à jour à la construction de l'image, et bien ça serait à la date de la construction de l'image uniquement, pas chaque jour.

        Ben, soit tu reprends le Dockerfile et tu rebuild toi-même les images, soit tu considère ça comme une appliance et tu n'as pas plus la main dessus d'une appliance sur un système classique.

        Ou plus simplement, avoir une image de base qui le fait sur laquelle les autres images se basent.

        C'est ce que je dis dans le journal :

        Je n'avais pas compris que tu parlais des images externes, je parlais de faire ta propre image de base pour les conteneurs que tu construis, mais ce n'est pertinent pour les images externes.

        « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

      • [^] # Re: Titre

        Posté par  (site web personnel) . Évalué à 10.

        Je ne veux pas reconstruire les images à partir du dockerfile,
        ce sont des images externes que j'utilise, que je n'ai pas
        créées moi-même. Je veux un moyen de mettre à jour les
        distributions des images présentes sur dockerhub

        C'est sans doute mort. Les devs de logiciel se sont lancés sur docker en se disant "ça va éviter de faire le taf des distributions", mais c'est une connerie, ça évite pas les distributions du tout, ça obscurcit le tout.

        Les conteneurs sont un outil et un format d'image pour distribuer des logiciels. Mais il n'y a pas de solution technique pour la question de la curation de contenu, et c'est ce qui coince ici.

        Fedora a tenté de pousser ça, des conteneurs basés sur Fedora utilisant les paquets et avec des standards et une gestion des versions. Ça n'a pas trop décollé que je sache.

        Et Dockerhub vise plus à avoir tout le monde pour des questions de croissances que de devoir faire un choix, donc tu as effectivement plein de trucs douteux.

        • [^] # Re: Titre

          Posté par  . Évalué à 10.

          Après, il y a aussi trois utilisations des conteneurs en parallèle qui n'ont pas les mêmes objectifs: fournir une image pour faciliter de développement, fournir une image pour faciliter la découverte du logiciel, fournir une image pour la prod. Ce ne sont pas les même politique de sécurité, paquets installé, bonne pratiques. Et ce n'est pas forcément facile de savoir ce qu'une image vise comme objectif (ça peut même se mixer en fonction des images).

          « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

          • [^] # Re: Titre

            Posté par  . Évalué à 6.

            fournir une image pour la prod. Ce ne sont pas les même politique de sécurité, paquets installé, bonne pratiques. Et ce n'est pas forcément facile de savoir ce qu'une image vise comme objectif

            et (du commentaire au dessus)

            Et Dockerhub vise plus à avoir tout le monde pour des questions de croissances que de devoir faire un choix, donc tu as effectivement plein de trucs douteux.

            Oui, les mises à jour ne sont qu'un problème parmi d'autres (par exemple, l'utilisation de root dans la majorité des images de dockerhub). Il y a un problème de qualité générale et en effet c'est difficile de trier le bon grain de l'ivraie. J'essayais d'en corriger une partie avec peu d'efforts (pour ne pas avoir à passer du temps à faire moi-même un dockerfile complet correct pour chaque logiciel que je veux déployer).

            • [^] # Re: Titre

              Posté par  (site web personnel) . Évalué à 4.

              Il y a un problème de qualité générale et en effet c'est difficile de trier le bon grain de l'ivraie.

              Vu que c'est l'un des sujets sur lesquels je bosse, ca m'intéresse.
              Qu'est ce qui ferait qu'une image est de meilleure qualité qu'une autre ? Quels seraient les critères sur lesquels se baser ?

              • [^] # Re: Titre

                Posté par  (site web personnel) . Évalué à 6.

                Juste pour préciser un peu plus le commentaire précédent, je bosse chez Docker dans l'équipe de dev en charge de ce qu'on regroupe sous le terme de Trusted Content regroupant les images officielles (Docker Official Images, DOI), les éditeurs vérifiés (Docker Verified Publishers) et le programme de sponsor des projets Open Source (Docker Sponsored Open Source).
                Et entre autre on travaille sur la qualité des images.

                Dans ce sens je suis assez curieux de vues des utilisateurs sur ce qui fait ou non une image de qualité.

                Pour prendre un exemple, les images utilisant root ou spécifiant un utilisateur. C'est pas un sujet si simple, car certaines images (par exemples des images de bases) doivent plutôt rester sur root. Par contre un service qui tourne, probablement pas. Mais au final il n'y a pas un consensus absolu sur la question.

                • [^] # Re: Titre

                  Posté par  . Évalué à 3. Dernière modification le 07 novembre 2022 à 15:18.

                  C'est pas un sujet si simple, car certaines images (par exemples des images de bases) doivent plutôt rester sur root. Par contre un service qui tourne, probablement pas.

                  En effet, mais il y a peu d'images de base comparé au nombre d'images d'applications, et les images d'applications passant par un utilisateur non-privilégié sont une minorité (je ne pense même pas arriver à en citer une). Par défaut également, tous les capabilities sont conservées, et bien peu d'images les désactivent.

                  Il y a bien sûr le problème des mises à jour qui fait l'objet de ce journal, et très peu d'images que j'ai rencontrées sur dockerhub sont reconstruites fréquemment pour avoir les paquets du système à jour. Aucun moyen facilitateur n'est fourni pour le faire. Quelques exemples ont été donnés ici pour employer une CI/CD dans ce but, mais ce ne sont que des solutions « maison » et ce n'est même pas ne serait-ce qu'évoqué dans la documentation de docker concernant les bonnes pratiques.

                  Sur un autre sujet de qualité, qui ne concerne pas la sécurité, mais qui a été mentionné dans les commentaires : le poids des images. Il existe des moyens pour faire des images finales minimales comme le multi-stage build mais c'est relativement peu utilisé dans les faits. Voir par exemple monicahq/docker#109 et docker-library/php#1324 où la balle est renvoyée entre une appli et l'image de base utilisée.

                • [^] # Re: Titre

                  Posté par  . Évalué à 4.

                  Pour prendre un exemple, les images utilisant root ou spécifiant un utilisateur. C'est pas un sujet si simple, car certaines images (par exemples des images de bases) doivent plutôt rester sur root. Par contre un service qui tourne, probablement pas. Mais au final il n'y a pas un consensus absolu sur la question.

                  Il n'y a pas d'absolu, mais les images de service qui ne tournent pas en root, c'est plutôt l'exception. Si on prend l'image d'exemple que je vois passé le plus souvent, c'est nginx, qui tourne en root et donc ne peut pas tourner dans un contexte de prod qui interdit ça. Et on a du coup vite l'association, les images officielle docker, ce n'est pas pour la prod.

                  Pour nginx, il y a plusieurs config qui ne serait pas possible sans être root, mais c'est plutôt un cas particulier qui devrait être traité comme tel et pas dans la configuration par défaut.

                  « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                  • [^] # Re: Titre

                    Posté par  (site web personnel, Mastodon) . Évalué à 3.

                    Pour le cas de nginx, le projet fourni lui même une imange avec accès restreints: https://hub.docker.com/r/nginxinc/nginx-unprivileged#!

                    Malheureusement, elle ne peut pas être mise en officielle sur docker hub: https://github.com/nginxinc/docker-nginx-unprivileged/issues/19#issuecomment-479536708

                    • [^] # Re: Titre

                      Posté par  . Évalué à 5.

                      Pour le cas de nginx, le projet fourni lui même une imange avec accès restreints: https://hub.docker.com/r/nginxinc/nginx-unprivileged#!

                      Sinon, il y a bitnami qui en fournit aussi (et pas que pour Docker), mais ce n'était pas vraiment la question.

                      Malheureusement, elle ne peut pas être mise en officielle sur docker hub: https://github.com/nginxinc/docker-nginx-unprivileged/issues/19#issuecomment-479536708

                      Je ne comprends pas trop pourquoi, ça dit juste que ce n'est pas fait.

                      « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                      • [^] # Re: Titre

                        Posté par  (site web personnel, Mastodon) . Évalué à 3.

                        Je ne comprends pas trop pourquoi, ça dit juste que ce n'est pas fait.

                        Ah oui, tu as raison, j'ai lu que les discussions sont encore en cours dans un commentaire plus bas. J'ai interprété "avec Docker Hub", mais il n'y a rien de précisé, c'est peut être juste en interne chez ngnix.

                  • [^] # Re: Titre

                    Posté par  (site web personnel) . Évalué à 5.

                    Perso, j'ai fini par remplacer nginx par caddy pour mettre des fichiers statiques à dispo. C'est largement plus simple pour moi.

                    • [^] # Re: Titre

                      Posté par  . Évalué à 3.

                      Oui, il y a plein d'alternative, j'ai pris celui-là parce que c'est l'image qu'on retrouve le plus dans les exemple un peu partout.

                      « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                  • [^] # Re: Titre

                    Posté par  (site web personnel) . Évalué à 4.

                    Oui c'est pas simple les images "de base". C'est pas simple car les usages sont très variés. Entre autre forcer un utilisateur non root si l'image n'est utilisée que comme base pour construire une autre, ben c'est pas top côté facilité d'usage. Par contre non root serait mieux d'un point de vue sécurité.
                    Le tout étant affaire de compromis. Mais la première étape serait en effet de présenter ces informations.

                    • [^] # Re: Titre

                      Posté par  . Évalué à 5.

                      Alors, ça ne permet pas tous les usages, mais le fait d'être root par défaut, ça complique aussi le travail de ceux qui ne veulent pas l'être parce que rien n'est fait pour eux. Je trouve que c'est plus simple de changer l'utilisateur à root pour mon besoin, plutôt que de changer l'utilisateur root vers un autre utilisateur et devoir gérer toutes les permissions qui en découle. Donc la facilité d'usage pour les utilisateurs qui veulent respecter les bonnes pratiques de base n'est pas du tout là.

                      Après, on pourrait aussi avoir les deux images qui se référence dans la documentation. Genre, nginx et nginx-root.

                      « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

              • [^] # Re: Titre

                Posté par  (site web personnel, Mastodon) . Évalué à 4.

                Pour pouvoir juger de la qualité des images, il faut pouvoir lire leur Dockerfile et les sources qui l'accompagnent.

                Malheureusement, je trouve difficile de lire le Dockerfile directement sur Docker Hub, car il manque le contexte des fichiers sources avec.

                Par exemple, celui de nginx est encore lisible, mais on ne sait pas le contenu des fichiers des entry points.

                Un point qui pourrait grandement aider à juger les images serait de donner la possibilité d'afficher directement sur la page des projets Docker Hub l'URL du site du projet, celle du dépôt de sources et éventuellement celle pour rapporter des bugs.

                Je trouve par exemple facilement ces 3 liens sur les modules JavaScript hébergés sur npmjs.com. Ce n'est pas obligatoire sur ce site, mais les projets renseignent ça souvent.

                Je sais qu'il y a un fichier Readme où les projets peuvent mettre du lien et du texte, mais j'apprécie que le Readme présente le projet plutôt que des liens. En plus, ça permet aussi de repérer rapidement les liens puisqu'ils sont toujours au même endroit si c'est en dehors (comme sur npmjs où je sais que je trouve ces liens sur la droite).


                Je n'ai pas de parts dans npmjs, mais j'aime bien aussi le fait de voir les quelques métriques qu'ils ajoutent au projet:

                • le nombre de téléchargement hebdomadaire donne une idée sur le nombre de personnes qui se fient à se projet et l'évolution dans le temps (projet jeune, projet abandonné dont les utilisateurs partent…)
                • le nombre de dépendances
                • le nombre de dépendants

                Les deux derniers semblent bizarre pour des images de containers, mais je pense que ça permettrait de voir quelle est la profondeur du graphe des FROM pour construire l'image.

                • [^] # Re: Titre

                  Posté par  (site web personnel) . Évalué à 5.

                  je trouve difficile de lire le Dockerfile directement sur Docker Hub

                  L'une des difficultés (pour expliquer que c'est rarement aussi simple qu'on le croit) est que à la base d'une registry sont les images. Construire une image à partir d'un Dockerfile n'est qu'une des options.

                  Maintenant, les choses évoluent dans le bon sens. Voici par exemple la vue de l'image python:latest : https://dso.docker.com/images/python/digests/sha256%3Ac43926b6865b221fb6460da1e7e19de3143072fc6be8b64cb1e679f90c7fcaa3
                  Ce n'est pas vraiment le Hub, c'est basé sur atomist qu'on a racheté il y a quelques temps.
                  Entre autres choses, le Dockerfile est associé.
                  C'est orienté vulnérabilités mais c'est une base pour beaucoup d'autres choses.

                  Un truc qui peut aider, c'est le SBOM d'une image : https://docs.docker.com/engine/sbom/

                  Les deux derniers semblent bizarre pour des images de containers

                  Non non, c'est pas si bizarre. Il y a pas mal de choses qu'on pourrait présenter. Je n'avais pas tellement pensé en terme de dépendances, mais c'est je vais le proposer. A partir d'une image permettre de connaitres les autres images utilisées lors du build est intéressant.
                  Une autre information qui m'intéresse d'afficher serait le nombre d'images basées sur celle-ci. Genre combien d'images sont basées sur alpine:3.

                  Ce sont des choses dont on discute (même si je n'ai aucune information à communiquer sur une potentielle sortie).

              • [^] # Re: Titre

                Posté par  (site web personnel) . Évalué à 5.

                Qu'est ce qui ferait qu'une image est de meilleure qualité
                qu'une autre ? Quels seraient les critères sur lesquels se
                baser ?

                Alors, pour moi:
                1) les images dont je connais la provenance vs celle dont je ne la connais pas.

                Exemple (plus ou moins au pif) :
                https://hub.docker.com/r/superseriousbusiness/gotosocial

                Je sais d'ou ça vient, c'est dans le README.

                https://hub.docker.com/r/jibbow/rust-wasm32-unknown-unknown/

                Je sais pas d’où ça vient, y a pas de lien. Je peux deviner que ça vient de https://github.com/Jibbow/docker-rust-wasm mais j'ai du chercher.

                Afficher la source (le label org.opencontainers.image.source) serait un pas en avant.

                2) les images qui sont mises à jour assez régulièrement vs celles qui ne le sont pas.

                rust-wasm32-unknown-unknown n'a pas bougé depuis 4 ans. C'est pas terrible, ni visible. Mais https://hub.docker.com/r/truecharts/ethercalc a été mis à jour y a 4 mois, mais pas plus. Et si je cherche le Dockerfile:
                https://github.com/truecharts/containers/blob/318299179acb15b2b73ef02673f7f32f9a6cafc8/mirror/ethercalc/Dockerfile

                ça code en dur une image spécifique. Donc même si il y a un rebuild régulier, ça n'est pas bon. Et ça se voit pas.

                Donc une certaine fréquence de mise à jour, et que ça ne code pas en dur l'image de base.

                3) je suis sans doute un puriste, mais les images qui lancent plusieurs process, c'est AMHA niet. Avoir supervisord ou autre dans l'image, ça me parait pas propre.

                4) la qualité des tags. Latest veut pas dire la même chose suivant les projets, tout le monde n'a pas plusieurs branches. Je pense qu'avoir une branche de dev, et une stable, ç'est un conteneur de meilleur qualité que rien

                5) avoir un README. C'est con, mais c'est important.

                6) avoir une image vérifié du projet. On parle de la vérification sur le fediverse (en utilisant rel=me, mais j'aimerais aussi avoir ça (et pas que pour Docker, car j'ai aussi le souci avec les images Centos sur AWS). Ensuite, vu que Docker fournit des images officiels (genre https://hub.docker.com/_/nginx) qui sont pas les images de projets upstream, mais celle de Docker, je peux comprendre que ça ferait tache ou que ça rendrait le tout vachement flou.

                7) avoir l'image compilé par une CI, dont je peux voir les logs (ou au moins avoir une trace). Les images fait à la main, bof.

                8) capable de se lancer sans être root avec le / en readonly

                9) plus controversé, ne pas me filer un shell tout pourri quand je me connecte sur le conteneur pour tenter de le faire marcher. J'ai du me retenir pour ne pas faire tab avec le conteneur de mastodon qui lance sh par défaut.

                J'imagine que je peux trouver d'autres points pour juger la qualité (genre, j'ai des opinions sur les Dockerfile, les choix des images de base, l'origine du code, etc), mais c'est déjà long.

                • [^] # Re: Titre

                  Posté par  (site web personnel, Mastodon) . Évalué à 2.

                  Pour le point 2, j'ai envie de dire bof… :) Parce-que régénérer juste pour le fun est un gâchis de temps et de ressources. ceci rejoint un autre point évoqué dans un autre message : avoir le lien du dépôt officiel du projet pour juger de l'activité (effectivement s'il y en a et que l'image n'est pas à jour c'est pas top et tu auras amplement raison.)

                  Pour le point 4, moi je demanderai juste une numérotation SemVer et un développement en branches… Parce-que je m'en balance par exemple des nouvelles fonctionnalités de 9.4 mais je veux les fixes de la 9.3 (le dernier de la branche pouvant juste s'appeler 9.3.latest) avec la liste des corrections…

                  7… :-D Pour couper la poire en deux, on pourrait avoir la possibilité de lancer bash ou zsh (mais d'autres voudront fish halala) ; mais je trouve bien que ash soit le shell par défaut (sifflote)

                  “It is seldom that liberty of any kind is lost all at once.” ― David Hume

                  • [^] # Re: Titre

                    Posté par  . Évalué à 3.

                    Pour le point 2, j'ai envie de dire bof… :) Parce-que régénérer juste pour le fun est un gâchis de temps et de ressources.

                    Outre le fait que les projets qui n'ont pas eu de faille de sécurité en 4 ans (dans le projet ou les dépendances) sont quand même très rare. Ça permet aussi de montrer que le pipeline de build est à jour et que je ne vais pas d'abord passer 4h à corriger les dépendance si je veux l'utiliser.

                    « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                • [^] # Re: Titre

                  Posté par  . Évalué à 2.

                  Le 8 est pas possible tel quel. Les images ne gèrent pas de partition. Ce que tu souhaite c'est une image qui ne fasse aucune écriture disque et c'est souvent qu'il y a besoin de créer des fichiers temporaires.

                  Le 9 avoir un shell c'est déjà dommage (mais c'est déjà perdu si tu as un interpréteur comme perl ou python)

                  https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

                  • [^] # Re: Titre

                    Posté par  (site web personnel) . Évalué à 3.

                    Le 8 est pas possible tel quel. Les images ne gèrent pas de
                    partition. Ce que tu souhaite c'est une image qui ne fasse
                    aucune écriture disque et c'est souvent qu'il y a besoin de
                    créer des fichiers temporaires.

                    Tu as raison sur les partitions, mais je pense qu'on peut imaginer avoir /tmp ou /var/tmp en tmpfs par défaut dans le conteneur au niveau du moteur de conteneur.

                • [^] # Re: Titre

                  Posté par  (site web personnel) . Évalué à 4.

                  1) les images dont je connais la provenance vs celle dont je ne la connais pas.

                  Très bon point. Pas toujours le plus simple :-)

                  Est-ce que le fait d'avoir les informations (les badges visibles) "Verified Publisher" ou ici "Sponsored OSS" peuvent aider à faire ce tri ?

                  Afficher la source (le label org.opencontainers.image.source) serait un pas en avant.

                  Alors clairement oui. Je ne sais plus où ca en est, je sais que ca a déjà été évoqué. Un des problèmes ici est que beaucoup d'images n'utilisent pas ces labels, mais on travaille à améliorer ceci.

                  2) les images qui sont mises à jour assez régulièrement vs celles qui ne le sont pas.

                  C'est clairement un des points qu'on va mettre en avant.

                  3) je suis sans doute un puriste, mais les images qui lancent plusieurs process, c'est AMHA niet. Avoir supervisord ou autre dans l'image, ça me parait pas propre.

                  Dans l'idée je suis totalement d'accord. Dans les faits, c'est toujours un peu plus compliqué à détecter simplement. Je me demande si avec le SBOM on ne pourrait pas le savoir.
                  Je me le garde sous le coude, je vais voir pour le rajouter à notre liste.

                  4) la qualité des tags

                  Si je suis d'accord sur l'idée, sujet très épineux. Certains voudraient du semver partout, d'autres s'en fichent et veulent juste du latest. Pour le moment j'ai pas d'idée immédiate sur comment améliorer ce point, mais j'aimerais bien trouver quelque chose.

                  5) avoir un README. C'est con, mais c'est important.

                  Oui. J'irais même plus loin, je pense qu'on peut définir un certain nombre de choses qu'on voudrait dans un readme. Genre une description du schéma de tags, ou un exemple sur comment lancer l'image, quels sont les paramètres, variables d'environnement nécessaires, etc.

                  6) avoir une image vérifié du projet. […] Ensuite, vu que Docker fournit des images officiels […] qui sont pas les images de projets upstream, mais celle de Docker, je peux comprendre que ça ferait tache ou que ça rendrait le tout vachement flou.

                  Ho non, ca ne ferait pas tache. Un des axes de travail de mon équipe est justement de remettre dans les mains des éditeurs leurs images.
                  Il faut voir qu'il y a quelques années encore, faire des images c'était pas la principale qualité de nombreux éditeurs. D'où aussi les images officielles.
                  Aujourd'hui c'est de moins en moins valable, et inciter les éditeurs à avoir leurs propres images est probablement une bonne chose pour tout le monde.
                  Le fait de passer d'une image officielle (disons nginx) à une image plus classique (qui pourrait être nginx/nginx) n'est pas un problème en soit.
                  Néanmoins (et c'est l'objet de tout ceci) cela doit s'accompagner d'une qualité suffisante.

                  7) avoir l'image compilé par une CI, dont je peux voir les logs (ou au moins avoir une trace)

                  Je vois, mais j'imagine que ce n'est pas forcément évident vu la variété des solutions pour construire une image.
                  Mais c'est une bonne idée, au moins de manière optionnelle. Je me demande si on ne pourrait pas juste le faire avec un label dans l'image contenant un lien vers le build.

                  8) capable de se lancer sans être root avec le / en readonly

                  Quel serait le but du readonly sachant que le conteneur est déjà immuable ?

                  9) plus controversé, ne pas me filer un shell tout pourri

                  Je suis plutôt adepte du pas de shell dans le conteneur sur ce point :-)

                  J'imagine que je peux trouver d'autres points pour juger la qualité […] mais c'est déjà long.

                  Nan c'est très bien.
                  Merci pour ces détails et ces idées.
                  Je vais partager au moins certaines d'entre elles en interne et voir ce qu'on peut améliorer sur ces points.

                • [^] # Re: Titre

                  Posté par  (site web personnel) . Évalué à 2.

                  Tant que j'y pense, un point de détail mais qui n'est pas si détail que ca :

                  6) avoir une image vérifié du projet. On parle de la vérification sur le fediverse (en utilisant rel=me, mais j'aimerais aussi avoir ça (et pas que pour Docker, car j'ai aussi le souci avec les images Centos sur AWS). Ensuite, vu que Docker fournit des images officiels (genre https://hub.docker.com/_/nginx) qui sont pas les images de projets upstream, mais celle de Docker, je peux comprendre que ça ferait tache ou que ça rendrait le tout vachement flou.

                  L'image officielle nginx est l'image du projet upstream. Cette image est maintenue par nginx, pas par Docker.

                  C'est visible en haut du README :

                  Maintained by:
                  the NGINX Docker Maintainers

                  Alors certes ce n'est pas très visible, et on va travailler sur cette partie. Mais image officielle docker ne veut pas dire que ce n'est pas l'image officielle du projet upstream.

        • [^] # Re: Titre

          Posté par  . Évalué à 2.

          Fedora a tenté de pousser ça, des conteneurs basés sur Fedora utilisant les paquets et avec des standards et une gestion des versions. Ça n'a pas trop décollé que je sache.

          Par curiosité, il y a un lien qui documente ça ?

          C'est sans doute mort. Les devs de logiciel se sont lancés sur docker en se disant "ça va éviter de faire le taf des distributions", mais c'est une connerie, ça évite pas les distributions du tout, ça obscurcit le tout.

          Ok, j'aurais espéré que le problème était déjà résolu quelque part et que ce n'était que de la méconnaissance de ma part…

          Je pense que je vais tenter mon idée de bricolage imparfait, voir si c'est réalisable déjà. Pour une image donnée, démarrer un nouveau conteneur de l'image dockerhub (mais sans entrypoint), faire les mises à jour dedans, puis le docker commit pour figer une nouvelle image locale. Cela devrait pouvoir être rendu suffisamment générique pour fonctionner avec toutes les images basées sur les distributions courantes. On pourrait alors mettre ça dans un crontab. Bien sûr, ne pas oublier de relancer ses conteneurs après ça.

          Pour aller plus loin, on pourrait remplacer localement l'image originale avec son tag pour ne pas avoir à modifier nos docker-compose.yml existants. Ça ne résistera pas à un docker pull, mais en bricolant encore un peu plus, on pourrait sûrement sauvegarder l'état quelque part et ne faire que des mises à jour incrémentales plutôt que repartir de l'image présente sur dockerhub à chaque fois (et alléger le crontab).

          • [^] # Re: Titre

            Posté par  (site web personnel) . Évalué à 7.

            Par curiosité, il y a un lien qui documente ça ?

            Vaguement, des choses comme
            https://fedoramagazine.org/community-container-images-available-for-applications-development/

            Le logiciel s'appelle osbs, et c'est du coté de Fedora cloud, mais je trouve pas trop de doc et/ou de discussion.

            Je pense que je vais tenter mon idée de bricolage imparfait,
            voir si c'est réalisable déjà

            L'approche que tu proposes marcherais, mais j'ai peur que tu tombes assez vite dans des cas ou ça marche pas, vu que tu supposes:

            • que les logiciels sont installés via le gestionnaire de paquet natif (quid de pip install)

            • que la distribution est encore maintenu (eg, quid d'un conteneur basé sur une version EOL)

            • que la distribution lors de sa mise à jour ne va pas casser la compatibilité quelque part

            • que l'image a un gestionnaire de paquet dispo en premier lieu (il y a sans doute des images ultra minimalistes sans ça)

            Ensuite, peut être qu'on parle de cas mineurs.

  • # SELinux et co, faire mes propres images

    Posté par  (site web personnel) . Évalué à 8.

    Alors pour ça, j'ai un certain nombre de choses, car la sécurité, c'est vaste (tm)

    Primo, j'expose pas les conteneurs directement, mais j'ai un proxy devant. Ça permet d'éviter les soucis liés à de la crypto pas à jour (bien que je pense que ça soit rarement applicable en pratique), et ça m'assure des logs. Ça permet aussi d'éviter les soucis dans le gestion du protocole HTTP en utilisant une pile éprouvé (en l’occurrence, apache httpd ou HAProxy).

    Ensuite, j'utilise SELinux. Au taf, c'est directement dans la plateforme (Openshift), chez moi, c'est directement dans l'OS, les conteneurs ne tournent pas en root autant que possible. Le but est d'éviter les sorties du conteneur trop facile en cas d'execution dans le conteneur.

    Ensuite, je prends pas n'importe quel image, et je fait mes propres images ou mes propres déploiements.

    J'essaye de partir d'images de distros en vérifiant que c'est bien officiel, avec l'orga derrière et pas juste un dev.

    L'exemple de Debian est un bon cas, car je ne connais pas la situation maintenant, mais avant, c'était un peu bizzare.

    J'essaye donc de faire mes images et d'automatiser la recompilation via une CI, en utilisant les paquets de la distro autant que possible.

    L'exemple que j'ai, c'est un dépôt github qui recompile les images toutes les semaines et qui changent automatiquement la version de base de Fedora:

    https://github.com/mscherer/various_containers/blob/main/.github/workflows/build_docker.yml

    Donc je sais que si je déploie un site sur hugo ou zola, la CI qui recompile le site en prenant mon conteneur va utiliser la dernière stable du logiciel qui tourne sur la dernière Fedora automatiquement (ou avec grosso modo 1 semaine de délai). Il faut juste que je clique un bouton tout les 6 mois, ou que je fasse un commit pour pas que github coupe la CI (et j'imagine, à terme, que je nettoie le dépôt).

    J'évite les images des projets qui utilise node ou python comme base parce que je ne sais pas ce qu'il y a dedans ou à quoi m'attendre. Parfois, je prends des images pour tester (par exemple, grist), ou pour des trucs que j'estime mineur et difficile à exploiter (par exemple, ethercalc), mais pour la production, je passe plus de temps à faire gaffe.

    Et c'est pas tant la sécurité qui me chagrine (car ça reste assez rare) que les incompatibilités qui peuvent arriver (l'exemple que j'ai est sur un blog qui est en panne, mais c'était une histoire d'userspace Ubuntu qui ne marche pas sur une Fedora, et qui casse de façon subtil).

    • [^] # Re: SELinux et co, faire mes propres images

      Posté par  . Évalué à 2.

      Ensuite, j'utilise SELinux. Au taf, c'est directement dans la plateforme (Openshift), chez moi, c'est directement dans l'OS, les conteneurs ne tournent pas en root autant que possible. Le but est d'éviter les sorties du conteneur trop facile en cas d'execution dans le conteneur.

      Peux-tu m'en dire plus ?

      Ensuite, je prends pas n'importe quel image, et je fait mes propres images ou mes propres déploiements.

      J'essaye donc de faire mes images et d'automatiser la recompilation via une CI, en utilisant les paquets de la distro autant que possible.

      Je comprends que ça serait le plus propre, mais c'est ce que j'aurais aimé éviter.

      L'exemple de Debian est un bon cas, car je ne connais pas la situation maintenant, mais avant, c'était un peu bizzare.

      C'est intéressant, j'étais loin de m'en douter, surtout que la page dockerhub arbore fièrement l'indication « Docker Official Image », mais qui, en y regardant de plus près, signifie :

      Docker Official Images are a curated set of Docker open source and drop-in solution repositories.

      Il faut donc comprendre « officielle à docker » et non « officielle au projet conteneurisé »…

      • [^] # Re: SELinux et co, faire mes propres images

        Posté par  (site web personnel) . Évalué à 4.

        Peux-tu m'en dire plus ?

        Sans doute, mais à quel niveau ?

        Sur openshift, chaque conteneur tourne dans un contexte selinux séparé (en utilisant MCS ), et sur ma Fedora, les conteneurs tournent aussi via une politique SELInux qui bloque l’accès au fs (ce qui fait que je doit changer le label des fichiers pour donner accès). Il y a quelques articles sur https://github.com/containers/container-selinux

        Donc si jamais un process arrive à contourner les limitations des namesapces suite à une faille, il reste encore les permissions SELinux pour éviter de faire trop de choses.

        Et Openshift par défaut bloque le fait de lancer un conteneur en temps que root, en mappant root vers autre chose automatiquement via les userns.

        Il faut donc comprendre « officielle à docker » et non « 
        officielle au projet conteneurisé »…

        Pour la défense de Docker, ça a pu changer depuis que l'article a été posté. Je ne connais pas assez Debian pour savoir.

        Mais oui, c'est un peu le souci. Je trouve que l'approche de Fedora consistant a publier son propre registre intéressante, vu que tu sais que c'est fait par le projet vu que le domaine corresponds.

  • # lxc ?

    Posté par  (site web personnel) . Évalué à 9.

    Ta question me fait plaisir, parce que c'est une question que je me suis aussi posé, sans trouver de solution triviale ( à part reconstruire régulièrement les containers ).
    C'est pour cela que j'utilise de préférence lxc à docker : au moins je peux faire mes mises à jour système comme sur un os traditionnel

  • # reconatruction

    Posté par  (Mastodon) . Évalué à 5.

    Je reconstruits les images avec l'option pull=always et je fais effectivement une mise à jour des paquets dans la Dockerfile.

    Et tant pis pour le cache, les électrons perdus et tout ça.

    • [^] # Re: reconatruction

      Posté par  . Évalué à 4.

      l'option pull=always

      C'est pareil que docker build --pull ... ?

      Moi aussi j'utilise ça, en fixant la version majeur pour avoir les fix et éviter les régressions.

      Et tant pis pour le cache, les électrons perdus et tout ça.

      Si rien a bougé, rien ne sera téléchargé à part les metadata.

  • # images docker externes

    Posté par  (site web personnel) . Évalué à 5. Dernière modification le 04 novembre 2022 à 15:19.

    Merci beaucoup à tous, premièrement pour la personne qui a posté le sujet, et ensuite aux personnes qui ont répondu, j'avais ce problème récurrent de sécurisation de mes images, je vais réessayer avec les réponses apportées, je vous tiendrais informés !

    Marisa

  • # build cache

    Posté par  . Évalué à 3.

    De toute manière, les images de base (comme debian:stable) ne sont pas elles-mêmes reconstruites à chaque mise à jour de sécurité. Il faudrait donc placer un RUN apt-get update && apt-get upgrade -y au début de chaque Dockerfile (se servant de debian), et reconstruire l'image régulièrement ? En plus, cela forcerait à re-télécharger toutes les mises à jour à chaque reconstruction de l'image, sans profiter du système de cache en couches des images docker, ce qui est un peu du gaspillage.

    Il y un autre système de cache sur le host justement pour ce cas la. Voir le paragraphe sur le RUN cache dans la doc:

    https://docs.docker.com/build/building/cache/

    • [^] # Re: build cache

      Posté par  . Évalué à 5.

      Le problème c'est que ça sera soit pas assez en cache, soit trop en cache, car tu dépends d'une ressource externe.

      Si à un instant T tu construis l'image, le RUN apt-get … sera bien lancé la première fois. Le lendemain, tu refais un docker build pour reconstruire l'image ? Perdu, le RUN est en cache donc aucune mise à jour ne sera faite. Une astuce pourrait être d'inclure une règle qui vérifie s'il y a eu des mises à jour, comme ADD http://security.debian.org/debian-security/dists/stable/updates/Release.gpg /tmp/peuimporte

      • [^] # Re: build cache

        Posté par  . Évalué à 4.

        Effectivement.

        Je crois qu'au boulot on contourne ça en faisant un system prune régulièrement sur le CI, donc a un moment ce sera bien rebuilde, mais je comprends le souci.

  • # FROM scratch

    Posté par  (site web personnel) . Évalué à 6.

    Si tu as la main sur les sources de l'application, tu peux essayer de construire une image sans distribution de base.

    Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

    • [^] # Re: FROM scratch

      Posté par  . Évalué à 4.

      +1

      J'ai cette obsession d'avoir des images les plus petites possibles, principalement pour économiser stockage et bande passante. Donc minimiser les dépendances, utiliser alpine comme base et le graal : partir de zéro.

      Le multistage aide beaucoup pour ça : 1/ construire le builder 2/ builder l'application 3/ ne garder que le nécessaire.

      L'effet collatérale est que cela minimise la surface d'attaque et doit probablement améliorer la sécurité.

      Bien évidemment, cela vient en complément de bonnes pratiques plus essentielles : vérifier la source de ses dépendances, faire un scan de vulns, faire des images non root, limiter les capabilities.

      stay safe

      • [^] # Re: FROM scratch

        Posté par  (site web personnel) . Évalué à 6.

        L'effet collatérale est que cela minimise la surface d'attaque
        et doit probablement améliorer la sécurité.

        J'ai des réserves. La surface d'attaque dépend de ce que tu exposes, et donc de l'application principal du conteneur (en supposant 1 conteneur == 1 process).

        Avoir gcc et ImageMagick dans le conteneur ne va rien impacter si ton process ne les utilisent pas, car les attaquants ne vont pas pouvoir y toucher. On peut sans doute trouver des cas tordus, mais ça me semble être l'exception plus que la régle.

        Ne pas activer des fonctionnalités que tu n'utilise pas va réduire la surface d'attaque mais ça n'est pas pareil. Et retirer les composants que tu n'utilise pas va réduire les alertes des scanners (qui sont un peu con quand même), mais ça ne réduit pas la surface d'attaque mais juste sa perception.

        Ensuite, les autres raisons (réduire la bande passante et le stockage) sont largement suffisantes pour moi, il n'y a pas besoin de ressortir la sécurité à tout bout de champ car ça ne fait qu'obscurcir ce qui est important et ce qui l'est moins à ce niveau.

        • [^] # Re: FROM scratch

          Posté par  . Évalué à 3.

          ressortir la sécurité à tout bout de champ car ça ne fait qu'obscurcir ce qui est important

          Je vous demande donc de m'excuser pour cet acte d'obscurantisme bien indépendant de ma volonté.

          L'un des classiques étant de monter le FS host sur le container guest.

          $ mount
          Command 'mount' not found, did you mean:
          [...]
          

          Et en vrai, il n'y a pas de shell.

          • [^] # Re: FROM scratch

            Posté par  (site web personnel) . Évalué à 4.

            Je vous demande donc de m'excuser pour cet acte d'obscurantisme
            bien indépendant de ma volonté.

            Je vous en sais gré.

            Et en vrai, il n'y a pas de shell.

            Supposons qu'un attaquant arrive à avoir la capacité d’exécuter du code dans le processus du conteneur (genre, un buffer overflow classique sans protection).

            Il est vrai que le plus simple est de lancer un shell surtout si c'est ce qui traîne dans les exploits publiques, ou une commande.

            Mais en pratique de nos jours, il y a des kits tout fait pour contourner ce genre de limitation (exemple metasploit ). Donc le bénéfice est la en théorie (genre, ça va coincer des débutants qui prennent un truc tout fait), mais en pratique, ça se contourne sans trop de moyens.

            Si c'est simple de builder et de faire le ménage (exemple en go ou en rust), ouais, ça vaut le coup.

            Par contre, je me prendrais pas forcément la tête pour nettoyer un truc en python ou en node au nom de la sécurité car l'effort risque d'être trop grand pour un bénéfice pas ouf (si on reste que sur la sécurité).

            • [^] # Re: FROM scratch

              Posté par  . Évalué à 4. Dernière modification le 05 novembre 2022 à 16:08.

              Je vous en sais gré.

              Vous êtes bien urbain.

              Je suis d'accord que cela ne protège par contre un bufferover flow avec exécution de code et l'exploit qui va bien.

              Ça protégera contre une injection de code qui tenterai un exec.

              car l'effort risque d'être trop grand pour un bénéfice pas ouf (si on reste que sur la sécurité).

              Tout à fait. C'est pour ça que je parle d'effet collatérale. Et que la motivation première est la taille de l'image.

              nettoyer un truc en python ou en node

              En node je ne sais pas mais en python ça se fait bien. On peut arriver a une taille de quelques 10aines de MB.

              • [^] # Re: FROM scratch

                Posté par  (site web personnel) . Évalué à 5.

                Intéressant. J'aurais un peu peur de choses comme les chargements dynamiques (ctypes) et les os.exec en tout genre, mais je suppose qu'il suffit de tester.

                En node, l'exemple que j'ai, c'est ethercalc, dont le conteneur pèse 1G. J'ai pas le sentiment que ça soit justifier pour un tableur web.

                • [^] # Re: FROM scratch

                  Posté par  . Évalué à 3.

                  mais je suppose qu'il suffit de tester.

                  je n'aurai pas dit mieux :)

                  En node, l'exemple que j'ai, c'est ethercalc, dont le conteneur pèse 1G.

                  Ça parait big en effet. J'ai pas trop fait l'exerce pour l'écosystème JS. J'ai testé le Google Closure Compiler sur un petit projet en Elm. Ça donne de bon résultat.

                • [^] # Re: FROM scratch

                  Posté par  . Évalué à 4.

                  D'ailleurs pour Ethercalc, j'ai l'impression que le plus officiel est ceci et ça pèse 375MB.

                  • [^] # Re: FROM scratch

                    Posté par  (site web personnel) . Évalué à 4.

                    Ah, je me suis arrêté à celui dans le docker-compose.

                    $ podman images | grep audrey
                    docker.io/audreyt/ethercalc latest 509b7c08e8b2  22 months ago  1.08 GB
                    

                    Le lien que tu donnes ne dit pas d’où ça vient (mais en même temps, dockerhub est pas terrible pour ça). L'avantage des registres de Gitlab et Github, c'est que tu as une idée rapide d'où vient le code.

            • [^] # Re: FROM scratch

              Posté par  . Évalué à 4.

              Supposons qu'un attaquant arrive à avoir la capacité d’exécuter du code dans le processus du conteneur (genre, un buffer overflow classique sans protection).

              Ce n'est qu'un type d'attaque, tu peux aussi avoir (l'équivalent d') un exec ou system dans ton programme (ou dans une des bibliothèques que tu utilise) et si tu n'as pas d'autres binaires à lancer (ou des binaires qui ne permettront pas de faire quelque chose d'utile). Et ce n'est pas un cas si rare que ça.

              Après, je suis bien d'accord qu'il ne faut pas vouloir à tout prix supprimer tout ce qui traîne sur le système, surtout en fonction de l'exposition du container. Mais si on peut en virer pour un coût faible, autant de ne pas se priver.

              « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

              • [^] # Re: FROM scratch

                Posté par  (site web personnel) . Évalué à 3. Dernière modification le 06 novembre 2022 à 12:31.

                Et ce n'est pas un cas si rare que ça.

                Donc tu parles d'un cas ou il n'y a pas un buffer overflow (ou autre détournement bas niveau), donc je ne peux pas avoir de l’exécution de code complète dans l'espace mémoire du programme, mais je peux avoir un exec/system arbitraire sur un programme qui existe déjà sur le disque ?

                Par exemple, le programme passe des variables mal échappées venant de dehors.

                Si c'est le cas, ça veut dire qu'il y a déjà un appel à exec/system. Et si tu as un exec/system dans le programme principal, tu as une dépendance vers un autre binaire, donc il faut la gérer.

                Suivant le type de binaire, le raisonnement n'est pas le même. Si c'est 2 binaires statiques qui s'appellent, oui, tu peux en effet réussir à éviter d'avoir un gestionnaire de paquet dans le conteneur final. Mais je pense que c'est assez rare, et la question se pose de pourquoi ne pas mettre tout dans 1 seul binaire, ou dans 2 conteneurs séparés.

                Si un des 2 programmes est fourni ailleurs ou n'est pas statique, par exemple via ta distro (exemple, tu lances imageMagick), alors tu va sans doute hériter d'un gestionnaire de paquet dans le conteneur pour installer le binaire et ses éventuels dépendances, et tu peux pas utiliser "FROM scratch" + "COPY from" facilement.

                Mais du coup, si tu as dnf/apt/pip dans le conteneur et une faille qui permet d’exécuter un programme arbitraire mais qui doit exister, il suffit d'installer un paquet vérolé pour exécuter du code (en l'absence d'autre mesures de protection).

                Par exemple, "pip install --user monpaquetpasverolé".

                Et si tu utilises system (en tout cas en python), il y a des chances que ça tire aussi un shell pour son fonctionnement que tu ne peux pas retirer, ce qui donne plein de primitives funs (cat/echo, etc).

                Il y a des outils qui permettent d'assembler des conteneurs sans avoir de gestionnaire de paquets à l'intérieur (e.g. apko, si je comprends bien), mais ça reviens à changer un peu tout le fonctionnement (et sans doute de distro).

                Et n'oublions pas aussi que si tu as python/ruby/perl/node dans le conteneur pour lancer le programme ruby/perl/python/node, tu as aussi defacto de quoi lancer des onliners, donc je pense qu'un ménage visant à retirer les dépendances ne va pas aider pour la sécurité si tu as un interpréteur que tu peux pas retirer.

                • [^] # Re: FROM scratch

                  Posté par  . Évalué à 3.

                  Si c'est le cas, ça veut dire qu'il y a déjà un appel à exec/system. Et si tu as un exec/system dans le programme principal, tu as une dépendance vers un autre binaire, donc il faut la gérer.

                  Tu peux aussi utiliser un framework d'une manière qui fait qu'il peut faire des appels à exec sans que tu le sache. La question ne se pose pas de savoir si ton code peut charger des binaires ou pas.

                  Mais du coup, si tu as dnf/apt/pip dans le conteneur et une faille qui permet d’exécuter un programme arbitraire mais qui doit exister, il suffit d'installer un paquet vérolé pour exécuter du code (en l'absence d'autre mesures de protection).

                  Souvent, mes conteneurs n'ont pas accès au net, donc l'ajout de payload depuis l'extérieur n'est pas un problème.

                  « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

  • # Sécu

    Posté par  . Évalué à 3.

    Tu viens de résumer le principal problème de la containérisation (qui est d'ailleurs ignoré par beaucoup de professionnel).

    Je pense que la meilleure solution est d'éviter au maximum les containers.

    Et si tu n'as pas le choix, il faut tout simplement rebuild souvent (donc dans une CI/CD) à chaque fix debian par exemple, ou par semaine. (cf: le rebuild des images distroless)

    Prioriser podman qui run en tant qu'user et non en root avec le remappage des UID/GID.

    Et suivre des bonnes pratique comme par exemple : https://github.com/GoogleContainerTools/distroless

    Personnellement pour des petits projets qui n'ont pas besoin de CI/CD mais auquel je suis obligé d'avoir recours au container je me contente de systemd-nspawn unprivileged ou de vm avec qemu.

    • [^] # Re: Sécu

      Posté par  (site web personnel) . Évalué à 3.

      Un autre projet intéressant est https://github.com/chainguard-dev/apko

    • [^] # Re: Sécu

      Posté par  . Évalué à 4.

      Je pense que la meilleure solution est d'éviter au maximum les containers.

      Juste là dessus : je dirai surtout que la meilleure solution est de bien choisir ses images de base. Choisir une image de base pour ses conteneurs de prod, c'est comme choisir une distribution pour ses VM de prod.

      Sur DockerHub, il y a de tout. Mais sur Distrowatch aussi.

      Quand je choisis une distribution, c'est que j'ai confiance en leur capacité à publier des correctifs de qualité et rapidement. Il faut que ça soit pareil sur les images de base utilisées par mes conteneurs de prod (cf les usages décrit par Xavier Claude)

      Je ne pense pas que le (vrai) problème soulevé dans ce journal soit un problème technologique.

    • [^] # Re: Sécu

      Posté par  . Évalué à 3.

      je me contente de systemd-nspawn unprivileged

      Et donc soit ton système hôte doit embarquer toutes les dépendances soit ton chroot doit embarquer toutes les dépendances soit ton binaire doit embarquer toutes les dépendances soit un mix de tout ça.

      ou de vm avec qemu.

      Et donc tu as les mêmes problématique de construction d'une image que pour de la containérisation.

      Ces solutions répondent à certaines problématiques (une VM plus sécursée qu'un container car par de partage du kernel ; un spawn plus simple à gérer qu'un docker) mais pas à " Comment sécurisez-vous les images [applicative] ?"

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.