Salut Nal !
Je t'écris, parce que j'ai essayé de faire en sorte que n'importe quel de tes auteurs et/ou lecteurs puisse tenter de te hacker.
Bruno a accepté 3 Pull Request cette semaine qui permettent aux développeurs et autodidactes de tenter de monter l'infrastructure de LinuxFr sur sa machine perso. Les détails sont donnés en anglais sur le répertoire git.
Pour résumer en français, il faut:
- Installer Docker et l'outil docker-compose et penser à ajouter son utilisateur au groupe
docker
pour pouvoir travailler sanssudo
. - Ajouter la ligne
127.0.0.1 dlfp.lo image.dlfp.lo
dans le fichier/etc/hosts
(ou équivalent). - Télécharger les sources de LinuxFr.org et libérer le port 80 s'il est actuellement utilisé.
- Exécuter dans un premier terminal
docker-compose up
(à la racine du code source) -
Attendre que docker-compose finisse son travail et que les containers de mariadb affichent les lignes:
database-test_1 | 2020-09-21 16:03:12 140126029907968 [Note] mysqld: ready for connections.
database-test_1 | Version: '10.1.46-MariaDB-1~bionic' socket: '/var/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
database_1 | 2020-09-21 16:03:12 139820938893312 [Note] mysqld: ready for connections.
database_1 | Version: '10.1.46-MariaDB-1~bionic' socket: '/var/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
Dans un second terminal (aussi à la racine du code source), il faut préparer la base de donnée avec:
docker-compose run linuxfr.org bin/rails db:setup
Utiliser son navigateur préféré pour visiter l'adresse http://dlfp.lo et se connecter avec le compte
admin
et le mot de passeadmin
Hacker les sources de LinuxFr.org et voire les changements arriver dans votre navigateur avec un simple rafraîchissement de la page :-)
C'est une première version, ça tourne chez moi et on récupère volontiers des retours et/ou améliorations sur ce déploiement.
Dans les manques, il y a le système des fichiers Epub qui ne sont pas disponible et l'écriture de formule Latex (il y a du code à adapter). De plus, la webconsole Rails ne s'affiche pas en cas de bug. Par contre, les tribunes et le service de cache d'image doivent fonctionner.
À noter, que le fichier docker-compose.yaml
fait utiliser le port 80 à nginx pour monter l'infrastructure, parce que le code de LinuxFr ne permet pas de préciser le port pour le lien sur les images. Vous pouvez donc modifier le port de ngninx, avec cette modification:
nginx:
image: nginx:stable
env_file:
- deployment/default.env
volumes:
- ./deployment/nginx/templates:/etc/nginx/templates
- ./public/fonts:/var/linuxfr/fonts
- data-uploads:/var/linuxfr/uploads
ports:
- - "80:80"
+ - "3000:80"
depends_on:
- linuxfr.org
- linuxfr-board
- linuxfr-img
Ensuite, il faut que le service qui utilise le port 80 redirige les requêtes pour le domaine dlfp.lo
et image.dlfp.lo
vers le nginx (et donc dans l'exemple, le port 3000).
Bref, cher lecteur, si tu as un peu de temps ce prochain trolldi ou ce weekend, les retours seront volontiers lus et, si possible, pris en compte :-)
# Root
Posté par Anonyme . Évalué à 10.
J’ai regardé rapidement les fichiers de build et de config et j’ai juste une remarque : tes containers tournent en root avec pour seule sécurité le « chroot » de Docker.
Depuis que je bosse avec Kubernetes, j’ai pris l’habitude de faire en sorte que mes containers puisse tourner dans n’importe quel utilisateur non-privilégié et dans un container en lecture seul.
Avec docker-compose, ça serait par exemple pouvoir ajouter ça dans la définition des containers (ce que je te conseille de faire dans ta config) :
De ce que je vois, ça ne devrait pas poser de problème et ça éviterait de faire tourner du RoR en root. Pour nginx c’est un peux plus compliqué, faut lui faire écrire ses fichier dans un dossier où il a les droit d’écrire, mais ça se fait aussi (au besoin je peux te donner un coup de main).
Aussi, vu que
linuxfr-image
est un binaire, tu pourrais utiliser le muti-stage de Docker et avoir une image final qui ne contienne que ce binaire (par exemple avec distroless de Google) :Pas testé, c’est juste pour l’exemple.
En tout cas, c’est cool si ça permet de faciliter le développement :)
[^] # Re: Root
Posté par Adrien Dorsaz (site web personnel, Mastodon) . Évalué à 10.
Pour le coup du root, j'avoue que je ne comprends pas bien comment faire pour le faire comme il faut.
J'ai essayé au début de mettre l'instruction
USER 1001
dans le Dockerfile pourlinuxfr.org
, mais ça m'a empêché de faire fonctionner l'upload d'avatars.Le problème, c'est que
docker-compose
fait monter le dossierpublic
etupload
, mais comme les fichiers ont mon UID (genre20000
sur mon poste), et bien l'utilisateur du container est incapable de créer le dossierpublic/tmp/upload
et ensuite de faire les dossiers dansupload
.Ensuite, j'ai abandonné, car justement nginx a aussi besoin d'accéder à ces dossiers et que du coup, il fallait commencer à coordonner les UID entre l'hôte et tout ces containers.
Finalement, j'ai laissé tomber, car ce n'est pas un déploiement pour de la production (avec Kubernetes et/ou OpenShift/okd), mais uniquement pour faire des tests sur sa machine.
Ma conclusion sur ce sujet, c'est que je tombe exactement sur le même os que lorsque j'essaie de faire une clé USB partagée entre différents postes Linux avec des UID/GID différents. La seule solution viable, ça serait de travailler avec un système de fichier sans permissions, genre FAT32.
Au vu de mes recherches sur le web, j'ai l'impression que tout le monde sait qu'il faudrait éviter d'utiliser root pour exécuter des Docker, mais que personne ne propose de solution pour permettre de partager les fichiers entre le host et le container.
Si j'ai bien compris, même OpenShift essaie de forcer à ne pas utiliser l'utilisateur root, mais il fait utiliser le groupe
0
et du coup, j'ai l'impression que ça ne change rien.C'est une bonne idée pour les binaires, je ne connaissais pas le projet "distroless". Je n'ai pas cherché à faire plus, parce que j'utilise déjà une debian slim et le minimum de paquet nécessaire pour faire tourner les services.
Peut être que dans l'exemple que tu as donné j'aurais pu enlevé le paquet
golang
, mais par contre, leca-certificates
est nécessaire pour que le service puisse se connecter aux sites exeternes en HTTPS.Merci beaucoup pour le retour, je vais faire des tests avec les pistes que tu m'as donné sur ces questions.
[^] # Re: Root
Posté par Letho . Évalué à 4.
Je suis passé de Docker à Podman récemment. Il permet (entre autres) de faire tourner des containers en tant que simple utilisateur.
Il n'est pas directement compatible avec docker-compose (bien qu'il existe podman-compose), mais il intègre la notion de pods de Kubernetes, et permet de les gérer avec systemd.
Peut-être une piste à creuser ?
[^] # Re: Root
Posté par gnumdk (site web personnel) . Évalué à 5.
Ou comment donner un accès root complet à sa machine… Ne jamais faire ça! En mettant ça pour un vacataire, on s'est fait hacker nos postes de travail.
Et pour le coup, vive Podman, à mort Docker!
[^] # Re: Root
Posté par ckyl . Évalué à 6.
Pour les problèmes liés au non alignement des UID dans le container et sur l'host avec les bind mount, une solution est d'utiliser https://github.com/boxboat/fixuid. Basiquement c'est un entrypoint qui aligne l'UID utilisé dans le container par celui que tu passes à docker run.
C'est bien plus compliqué que ce que n'importe qui voudrait. Mais pour les workflows de dev où tu as besoin de bind mount c'est la seule solution que je connaisse.
[^] # Re: Root
Posté par Cyrille Pontvieux (site web personnel, Mastodon) . Évalué à 4.
Ah excellent, ça ressemble au hack que j’ai mis plus bas sauf que:
fixuid
est avec le bitmasksetuid
(se lance avec les droits du fichier, iciroot
, et pas les droits de l’utilisateur qui lance le fichier)C’est top, merci beaucoup c’est exactement ça qu’il me fallait.
Il va quand même falloir que j’étudie le code source de ce binaire, car vu qu’il est
setuid
root
ça peut être un moyen de devenirroot
dans le conteneur (ce qui est un peu con vu que c’est ce qu’on évite de faire).N.B. mais pourquoi n’ai-je pas pensé avant à faire un binaire setuid root ??
[^] # Re: Root
Posté par Cyrille Pontvieux (site web personnel, Mastodon) . Évalué à 4.
Pour ce qui est du mapping des uid/gid, quand on veut utiliser un bind-mount (c'est à dire monter un répertoire depuis l'hôte dans le conteneur), c'est vraiment la merde car y'a pas d'API.
Pourquoi alors que ce ne serait pas très compliqué (il y a un namespace pour les uid/gid dans le noyau Linux, donc ça serait sûrement assez peu de code) ? À mon avis parce que les personnes/entreprises qui développent pour docker/compose/kubernetes/whatever sont orientés vers du déploiement sur des infrastructure avec orchestrateur et pas pour un déploiement « dev local » comme ici.
Cette situation dure depuis longtemps et il n'y a pas d'amélioration à l'horizon.
Et pour cause, certains pensent aussi que pour du « dev local » c'est pas si grave de faire tourner des services en root. Le hic c'est que ça oblige à avoir un système de conteneurs différent pour le dev et pour la prod, ce qui en soit est forcément source de problème (si on fait tourner des conteneurs en prod).
Il existe des hacks, plus ou moins réussis. En voici un :
.env
pour il déclarer deux variables pour compose,UID
etGID
comme suit :environments
d'un service :Utiliser un
docker
entrypoint
qui va faire ce travail :id -u
est 0 (root), alors :UID
/GID
Avec cette solution, le conteneur démarre en root, mais perd ses privilèges dès l'entrypoint, ce qui fait qu'au final les processus dans le conteneurs ne tournent pas en root (et c'est ça qui compte).
Par contre c'est assez casse-pied à mettre en place, surtout le rappel de l'entrypoint par lui-même : à base de
exec
et desu user /docker-entrypoint arg1 arg2 …
Si quelqu'un a un meilleur hack, je suis preneur ;-)
# À propos de docker-compose
Posté par Yuul B. Alwright . Évalué à 10.
Merci beaucoup ce travail. ;)
J'en profite pour partager mon expérience sur l'utilisation de docker-compose.
J'utilise docker-compose depuis des années et je me suis vite rendu compte de ses limitations.
Si il permet de définir facilement une stack de containers, il n'est pas adapté pour effectuer nombre de tâches lors du lancement de l'application "containerisée".
Par exemple, docker-compose n'est pas adapté pour:
- Lancer l'initialisation des tables de la base de donnée
- Générer des clés
- Ajouter un ou plusieurs utilisateurs d'administration dans l'application "containerisée"
- etc
Si on essaye, on se retrouve à devoir jouer avec les scriptes de points d'entrée (entrypoint) des containers et ça peut vite devenir complexe.
Comme au niveau pro je n'ai pas le choix des outils, je l'utilise malgré tout.
Mais à coté, depuis longtemps, j'utilise aussi Ansible pour l'intégration des applications ("containerisée" ou pas) dans l'infrastructure:
- Déploiement de l'application (ou de sa stack)
- Déploiement des configurations
- Initialisation des tables de la base de donnée
- Génération de clés (et stockage pour plus tard)
- Ajout d'utilisateurs
- Configuration de reverse proxy ou load balancer
- Ajout d'un sous-domaine
- Configuration du système de backup
- Configuration du système de teste de l'infra
- Etc
Les possibilités sont immense.
Mais récemment j'ai décidé de me passer de docker-compose sur mon infrastructure personnelle et d'utiliser directement Ansible pour la définition de la stack de containers.
L'idée c'est d'avoir un rôle Ansible qui déploie l'application et d'utiliser un playbook pour appliquer le rôle, personnaliser l'installation et l'intégrer dans l'infra.
Le rôle s'occupe, par exemple, de:
- Créer les containers
- Déployer les fichiers de configuration avec la config par défaut
- Initialiser la base de données
Les paramètres de l'application ainsi que du déploiement sont personnalisable par des variables dans Ansible.
Le playbook s'occupe de l'intégration dans mon infrastructure:
- Il définit sur quel hôte l'application sera déployée
- Personnalise l'installation
- Créer des utilisateurs
- Configure le reverse proxy
- Configure un sous-domaine pour la nouvelle application
Le rôle est réutilisable et facilement partageable tandis que le playbook est dépendant de l'infrastructure.
Et si je crée un rôle qui déploie son application via des containers Docker, il peut être utilisé sur n'importe quel système où Docker est installé (ou presque).
Et à coté, je crée aussi un playbook qui déploie l'application en locale pour du dev. Mais avec le système de tags d'Ansible ou pourrait avoir un seul playbook qui s'adapte en fonction de la cible (dev/test/prod).
En plus avec l'arrivée des collections Ansible, on a un système qui permet de distribuer en une fois des rôles, des modules, des exemples de playbook et la doc en rapport avec un projet ou une application.
En bref, Ansible m'apporte une plus grand liberté et flexibilité que docker-compose et ce commentaire est beaucoup trop long, j'aurai du créer un journal. :(
[^] # Re: À propos de docker-compose
Posté par 16aR . Évalué à 1.
Pourquoi ? C'est quoi le problème ?
[^] # Re: À propos de docker-compose
Posté par Nicolas Boulay (site web personnel) . Évalué à 3.
Et kubernetes ou Swarm n'aide pas pour ce que tu cherches à faire ?
"La première sécurité est la liberté"
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.