Salut à tous, dans le dernier TP on s’est penché sur docker et plus particulièrement son intégration avec Portainer. Aujourd’hui on va regarder comment déployer une Stack vsftpd dans Portainer. L’objectif étant d’avoir un serveur (VS)FTP accessible en read-only pour quelques utilisateurs à la fin du TP.
Rappel des articles de la série « Docker et Portainer » :
- Docker et Portainer part 1 – Les conteneurs pour les nuls ;
- Docker et Portainer part 2 – Stack vsftpd mono-image ;
- Docker et Portainer part 3 – Docker Guacamole via une Stack multi-images ;
- Docker et Portainer part 4 – OpenVPN, Network et Splunk ;
- Docker et Portainer part 5 – Customiser un conteneur PHP-FPM ;
- Docker et Portainer part 6 – NextCloud avec Docker, Déployer un « Cloud » personnel ;
- Docker et Portainer part 7 – Mettre à jour Portainer ;
- Docker et Portainer part 8 – Déployer un jitsi meet avec docker ;
- Docker et Portainer part 9 – Monitoring des performances docker avec Splunk.
- Docker et Portainer part 10 – The Hive & Cortex et installation Docker….
Les stacks docker
Les stacks sont une de mes fonctions préférées de docker, elles permettent de définir la configuration d’une ou plusieurs image dans un fichier docker-compose.yml
. En effet, si un image docker permet de configurer un système, un logiciel ou encore un ensemble d’application dans un conteneur ; une image n’est pas adaptée à la configuration qui varie entre chaque utilisateur de l’image : création de comptes utilisateur, gestion des variables d’environnements, gestion du réseau, volumes, logging, etc.
C’est là qu’intervient la stack et le fichier docker-compose.yml, qui permettent de spécifier ces éléments pour une image (en accord avec ce qui est prévu par l’image).
Je vais beaucoup utiliser les snacks dans la suite des TP sur docker et Portainer car elles permettent :
- d’industrialiser facilement les déploiements des conteneurs ;
- de conserver la configuration de vos images dans un fichier simplifiant backup et mise à jour ;
- de lier entre-elles plusieurs images dans un seul fichier de configuration.
Dans ce TP je vais vous présenter une stack « mono-conteneur » pour introduire le concept simplement. Vous verrez par la suite que c’est très utile (indispensable) lorsque vos images deviennent complexes (au hasard, un site WordPress avec un nginx, un php, une DB et un serveur de cache qui doivent tous se parler…).
La Stack VSFTPD
Un bon exemple valant toujours mieux qu’un long discours on va s’attaquer à notre Stack VSFTPD sans transition. Mon objectif était d’avoir à la fin un serveur FTP avec les caractéristiques suivantes :
- Plusieurs utilisateurs ;
- Accès FTPS sécurisé par certificats ;
- accès aux logs ; et
- un répertoire commun à tous les users, en lecture seule.
Trouver un image VSFTPD ou en construire une ?
La première chose à faire avant de construire notre stack c’est déjà de trouver l’image docker qu’on va faire tourner, deux options :
- on part de zéro et on construit notre propre image « from scratch » ; ou
- on repart d’un image existante sur le hub docker (en vérifiant dans les sources qu’elle ne fait pas n’importe nawak), et si nécessaire en la customisant pour nos besoins.
C’est cette seconde options que j’ai pris, donc direction hub.docker.com et rechercher vsftpd (382 images trouvées…). Après il faut prendre un peu de temps pour regarder ce que fait chaque image.
J’ai fini par m’arrêter sur celle-ci panubo/vsftpd qui répondait à mon besoin et pour lesquels j’ai trouvé que les sources étaient propre.
Construire une stack vsftpd.
Bon alors la base d’un fichier de stack dans portainer c’est :
version: 2
services:
vsftpd:
Après il faut définir les éléments qu’on veut mettre en place dans notre Stack. on va commencer par le minimum, l’image du conteneur à utiliser, les noms et le comportement à avoir en cas d’arrêt :
version: "2"
services:
vsftpd:
image: panubo/vsftpd:latest
container_name: vsftpd
hostname: vsftpd
restart: always
Maintenant, on peut passer aux aspects réseaux, le bloc ports nous permet de spécifier les ports qui seront exposés à l’extérieur du réseau privée docker :
ports:
- 21:21
- 4559-4564:4559-4564
On passe ensuite à la persistance des données maintenant en définissant nos volumes (rappels sur les volumes dans la partie 1) :
volumes:
- "vsftpd_cert:/etc/ssl:ro"
- "shared_ftp:/srv:ro"
- "vsftpd_logs:/var/log"
- "vsftpd_conf:/etc/vsftpd"
Notez qu’on a pas besoin de créer les volumes s’ils n’existent pas, docker/portainer s’en occupera tout seul à l’instanciation si besoin. Remarquez aussi le :ro
en fin de ligne pour spécifier que le volume est en read only pour le conteneur.
Maintenant il nous reste un peu de configuration à faire pour créer les utilisateurs et mettre en place le chiffrement des communications. Pour les utilisateurs, l’image de panubo passe par des variables d’environnement dans le docker.
environment:
- FTP_USER_1=toto:$$6$$R3h09ywl$$QBf0HtgHgwDejoruGviab1Ogo4PiGrXbXSSM4Hx4zu3ZnfreHeDEjxxSPMexod0G/ekznFmSyswVwQvKDTcO/
- FTP_USER_2=tata:$$6$$ZE.GMXwY9mFaCDQ$$b5vfJ5ThglxZmjZbyibsaQulIS0rxszUp9DHZ8mQi2zwrfYFGhtg.x7QKP/ANdx.FQiY8UMGzKCHPN1lnGvq1
Et le hash du mot de passe est à générer avec la commande suivante :
mkpasswd -m sha-512 monSuperMot2Passe $6$HsHpgRecjOX13/$wc5ExJnkcwEaIshtgp5OmRXqT7ORTrC0ZSsvAxPV0kqAK4kUmdZBsEWFFvG9BqxnLgZRc/c4rNs4rA3aedikF.
Notez qu’il faut doubler les $
(pour les échapper) dans le fichier par rapport au retour de la commande.
Mettre en place le chiffrement FTPS
Il nous reste ce dernier point à mettre en place. Pour ça il faut d’abord générer un certificat et sa clé privée :
openssl genrsa -out vsftpd.key 2048 openssl rsa -in vsftpd.key -pubout -out vsftpd.crt
Ici vous allez avoir besoin de créer le volume vsftpd_certs avant de lancer votre stack pour placer les certificats dedans. Pour cela rendez-vous dans Volume-> Create
dans Portainer.
A partir de là, sur votre hôte vous trouverez dans /var/lib/docker/volumes/vsftpd_cert/_data/
votre volume. IL vous faut alors y créer les dossiers suivants et déplacer vos certificats dedans ainsi.
mkdir /var/lib/docker/volumes/vsftpd_cert/_data/certs mkdir /var/lib/docker/volumes/vsftpd_cert/_data/private mv vsftpd.crt /var/lib/docker/volumes/vsftpd_cert/_data/certs mv vsftpd.key /var/lib/docker/volumes/vsftpd_cert/_data/private
Il faut ensuite changer la commande de démarrage de notre image vsftpd pour utiliser le fichier de configuration « ssl » comme documenté par le projet. Et pour cela vous devez rajouter la ligne suivante dans votre docker compose.
command: "vsftpd /etc/vsftpd_ssl.conf"
Stack vsftpd : docker-compose.yml
Au final vous devriez vous retrouver avec un fichier comme ça :
version: "2"
services:
vsftpd:
image: panubo/vsftpd:latest
container_name: vsftpd
hostname: vsftpd
command: "vsftpd /etc/vsftpd_ssl.conf"
restart: always
environment:
- FTP_USER_1=toto:$$6$$R3h09ywl$$QBf0SHtgHgwDejoSBDviab1Ogo4PiGrXbXSSM4Hx4zu3Znfdl2eDEjxxSPMexod0G/ekznFmSyswVwQvKDTcO/
- FTP_USER_2=tata:$$6$$ZE.GMXwY9mFaCDQ$$b5vfJ5rVBlxZmjZbyibsaQulIS0rxszUp9DHZ8tmQi2zwrfYFarqg.x7QKP/ANdx.FQiY8UMGzKCHPN1lnGvq1
ports:
- 21:21
- 4559-4564:4559-4564
volumes:
- "vsftpd_cert:/etc/ssl:ro"
- "shared_ftp:/srv:ro"
- vsftpd_logs:/var/log
- vsftpd_conf:/etc/vsftpd
Il faudra copier cette Stack dans Portainer dans Stack-> Add Stack
.
Et c’est tout, vous cliquez sur Deploy the stack
et vous devriez avoir un beau serveur vsftpd tout bien configuré qui sera accessible sur le port 21 et en mode « passif » sur les ports 4559 à 4564.
Vous pouvez tester avec un filezilla par exemple en configurant dans le gestionnaire de site :
Conclusion
Voilà c’est tout pour aujourd’hui, on a eufleré ici la construction d’une stacks docker. J’aurais aussi pu vous parler du networking de vos conteneurs ou de la manière dont on peut remonter les logs des conteneurs dans un Splunk, mais ce sera pour la suite.
Dans les prochains TP on verra comment modifier une image docker à partir d’une image existante, et surtout comment déclarer et lier plusieurs conteneurs dans un même Stack.
A bientôt pour la suite et geekez bien (et chez vous donc) d’ici là.
Bonjour,
Merci pour cette série de tuto qui va me servir à me lancer dans une utilisation plus réfléchie et mieux organisée.
est-ce que cela demande de l’adaptation pour la mise en place sur un raspberry ?
j’ai adapté l’installation de docker / portainer, c’est fonctionnel. Tout semble s’être bien passé également pour vsftpd mais j’ai une erreur à la connexion :
Statut : Échec de la tentative de connexion avec « ECONNREFUSED – Connexion refusée par le serveur ».
Erreur : Impossible d’établir une connexion au serveur
tout est en local, pas de nom de domaine, filezilla résout bien le nom (j’avais essayé via l’IP aussi)
Les tests avec l’assistant de configuration réseau ne remonte pas de soucis côté filezilla…
c’est la première fois que j’essaie de créer un ftp sur le raspberry, je ne sais pas où peux se situer le soucis ni comment troubleshooter mieux que ça
Est-ce que vous auriez une idée ?
Hello Corly,
Je n’ai jamais testé Docker sur ARM et RasPi mais si c’est supporté il n’y a pas de raisons que ça fonctionne différemment.
Pour ton « ECONNREFUSED » : ça signifie que la connexion TCP n’arrive pas à s’établir (TCP SYN en « reject »). Tu peux avoir plusieurs causes qu’il faut contrôler :
netstat -tunlp
« , le port 21 devrait être en écoute.listen=YES
listen_ipv6=NO
Note que vsftpd ne supporte pas les 2 piles IP simultanément : il faut choisir entre V4 et V6.
« ipv6 »: true,
Voilà pour mes pistes à froid, je me rappel avoir un peu galérer avec le support ipv6 sur le serveur mais rien d’insurmontable dans mes souvenirs. Hésites pas à nous dire ce que c’était quand du aura trouvé. @+
Salut,
merci pour la réponse.
j’avoue avoir laissé un peu tomber pour le moment mais je me note ça, je vérifie au plus vite et je fais un retour 🙂
Bonjour,
Merci pour cette série d’articles très bien faits.
Suite à une légère baisse de glycémie lors de la rédaction, vous avez glissé ce magnifique lapsus: « Je vais beaucoup utiliser les snacks dans la suite des TP sur docker « … savoureux.
Et le lien vers la partie 3 renvoie sur une erreur 404, ce qui est bien dommage.
Encore merci et bravo
Hello,
Merci pour les infos, je crois que je vais laisser le snack finalement : on ne sait jamais si j’ai un petit creux je ferai un coup de :
docker snack compose-salade.yml
qui sait ? 🙂Je corrige les liens de ce pas (edit: c’est fait), merci pour l’info et @+