Docker et Portainer part 3 – Stack Docker Guacamole

Docker et Portainer

Salut à tous, dans le dernier TP on s’est penché sur la définition d’une Stack dans Portainer pour un service VSFTPD. Aujourd’hui on va regarder comment déployer une Stack Docker Guacamole avec plusieurs images docker, toujours dans Portainer. L’objectif du jour étant d’avoir un service Guacamole sur notre serveur à la fin du TP.

Rappel des articles de la série « Docker et Portainer » :

Guacamole ? bon appétit !

Apache Guacamole plus exactement, et qui n’a rien à voir avec la recette mexicaine de purée d’avocat, est un client VNC, RDP, et SSH (comme un PuTTY ou mremoteng) qui à la particularité d’être « client-less » ou plus exactement « full-web ».

On installe donc Guacamole sur un serveur et on y accède avec son navigateur web comme dans la capture ci-dessous.

Docker Guacamole

Le gros intérêt au delà d’avoir un client SSH dans son navigateur, c’est que c’est le serveur qui effectue la connexion VNC, RDP ou SSH sur le port concerné. Et donc d’un point de vu réseau le poste client ne fait donc que du HTTPS sur le 443 vers le serveur.

Le gros avantage c’est que lorsque vous bossez dans un environnement « sécurisé », ou soit-disant :-), qui n’autorise pas ces ports en sortie (pour rappel TCP/22 pour SSH, TCP/3389 pour RDP et TCP/5900 pour VNC par défaut). C’est que si vous avez accès au net, vous aurez accès à votre guacamole, qui lui aura accès à votre ou vos serveur(s) sur ces ports.

Et d’un point de vu réseau c’est beaucoup plus « propre » (et discret…) que de faire du SSH sur le port 443, que soit en direct (on a vu… qui a dit proxy SOCKS ?) ou avec un frontal SSLH devant votre serveur par exemple.

Stack Docker Guacamole

Alors la bonne nouvelle c’est que la doc du projet est super complète, y compris pour docker. La mauvaise c’est qu’elle est bien verbeuse et que se la palucher tout d’un bout à l’autre demande « un certain temps« . Alors comme pour le dernier TP sur VSTFPD on pourrait aller sur le docker hub et chercher un image toute prête mono-conteneur qui implémente Guacamole.

Bon dans mon cas, je voulais m’en servir pour administrer le serveur et j’étais pas trop chaud pour reprendre une image inconnue vu que le système Guacamole reste assez complexe. Les options était donc de partir des sources ou des 2 images officielles d’Apache Guacamole sur le docker hub et regrouper le tout dans une Stack (pour vous faire ce TP).

Pour rappel un service Guacamole est composé de 3 éléments :

  1. Une base de données : MySql ou PostGreSQL
  2. Un moteur du service : Guacd
  3. L’interface Web qui fait le lient avec le service : Guacamole

La base de données : MariaDB

Le seul service qu’il faut configurer c’est la base de donnée, donc on peut commencer par construire une stack juste avec elle, la configurer puis rajouter les 2 autres éléments. Voici le code du docker-compose.yml pour faire ça :

version: "2"
services:
  guacdb:
    container_name: guacdb
    hostname: guacdb
    image: mariadb:latest
    volumes:
      - guac_db_data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=4n!R00TPasswordUmayWant
    expose:
      - "3306"

Il faut déployer cette Stack dans Portainer comme je vous l’ai montré pour VSFTPD. Une fois le service running, il faut initialiser la base de données. Heureusement l’image docker « Guacamole » intègre le script pour ça. Donc sur votre hôte, saisissez la commande suivante pour copier le script en local :

docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --mysql > initdb.sql

Il faut ensuite exécuter la succession de commandes suivantes pour initialiser la base de données (doc).

docker exec -i guac_database sh -c 'mysqladmin -u root -p"$MYSQL_ROOT_PASSWORD" create guacamole_db'

docker exec -i guac_database sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" guacamole_db -e "CREATE DATABASE guacamole;"'

docker exec -i guac_database sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" guacamole_db -e "CREATE USER \"guac\" IDENTIFIED BY \"PasswordServiceGuac\";"'

docker exec -i guac_database sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" guacamole_db -e "GRANT SELECT,INSERT,UPDATE,DELETE,CREATE ON guacamole.* TO \"guac\"@\"%\";"'

docker exec -i guac_database sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" guacamole_db -e "FLUSH PRIVILEGES;"'

docker exec -i guac_database sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" guacamole_db ' < initdb.sql

Et la base de données est configurée.

Le service : GuacD

Le service GuacD ne nécessite pas de configuration particulière donc sa partie dans la Stack est assez directe :

  guacd:
    container_name: guacd
    hostname: guacd
    image: "guacamole/guacd:latest"
    restart: always
    volumes:
      - "guacd_data:/data"
      - "guacd_conf:/conf:ro"
    expose:
      - "4822"

Notez que j’utilise ici expose et non pas ports pour décrire le port réseau sur lequel le service s’exécute. J’y reviendrai un peu après.

l’IHM : Guacamole

Enfin il nous reste à exposer le service web, et pour ça la dernière partie de notre Stack se définie ainsi, il suffit de l’ajouter dans la Stack et de déployer le tout.

  guacamole:
    image: "guacamole/guacamole:latest"
    container_name: guacamole
    hostname: guacamole
    restart: always
    depends_on:
      - guacd
      - guacdb
    volumes:
      - "guac_data:/data"
      - "guac_conf:/conf:ro"
    ports:
      - "8084:8084"
    links:
      - "guacdb:database"
      - "guacd:guacd"
    environment:
      - "GUACD_HOSTNAME=guacd"
      - "GUACD_PORT=4822"
      - "MYSQL_HOSTNAME=database"
      - "MYSQL_PORT=3306"
      - "MYSQL_DATABASE=guacamole"
      - "MYSQL_USER=guac"
      - "MYSQL_PASSWORD=PasswordServiceGuac"
      - "GUACAMOLE_HOME=/data"

Notez ici que j’utilise ports pour indiquer les ports accessibles depuis l’extérieur de docker. Qui est différent d’expose qui documente simplement les ports exposé par le conteneur, sans les rendre joignable de l’extérieur.

Premier accès à Docker Guacamole

A partir de là, vous devriez pouvoir accéder sur le port 8084 de votre serveur en HTTP et avoir cette belle page de login.

Docker Guacamole

Le login par défaut est guacadmin / guacadmin et je vous recommande de changer rapidement.

Vous pourrez ensuite allez dans Paramètres->Connexions->Nouvelle Connexion et définir les paramètre de votre serveur SSH.

Docker Guacamole

Celui-ci apparaitra alors sur la page d’accueil, et il vous suffit de cliquer dessus pour vous y connecter.

Et voilà, vous avez un client SSH accessible en Web depuis votre Serveur.

« Hey attends 2s là, on est pas sur le port HTTPS là, c’est le 8084 qui est configuré. Je pourrais pas me connecter depuis un environnement ou ce port est filtré au final. »

un type qui suit.

C’est bien il y en a qui suivent, et effectivement ici tous est configuré pour tourner sur le 8084. Mais on peut avoir un quick-fix en « NATant » ce port sur le 80 de notre serveur par exemple, directement dans notre conf docker en remplaçant notre section ports de Guacamole avec :

    ports:
      - "80:8084"

qui exposera alors le port 80 et redirigera le trafic vers le 8084 de notre Guacamole.

La stack Docker Guacamole complète

Pour les feignasses ; oui, là, vous au fond, près du radiateur :

version: "2"
services:
  guacdb:
    container_name: guacdb
    hostname: guacdb
    image: mariadb:latest
    volumes:
      - guac_db_data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=AvousdeVoir
    expose:
      - "3306"
  guacd:
    container_name: guacd
    hostname: guacd
    image: "guacamole/guacd:latest"
    restart: always
    volumes:
      - "guacd_data:/data"
      - "guacd_conf:/conf:ro"
    expose:
      - "4822"
  guacamole:
    image: "guacamole/guacamole:latest"
    container_name: guacamole
    hostname: guacamole
    restart: always
    depends_on:
      - guacd
      - guacdb
    volumes:
      - "guac_data:/data"
      - "guac_conf:/conf:ro"
    ports:
      - "80:8084"
    links:
      - "guacdb:database"
      - "guacd:guacd"
    environment:
      - "GUACD_HOSTNAME=guacd"
      - "GUACD_PORT=4822"
      - "MYSQL_HOSTNAME=database"
      - "MYSQL_PORT=3306"
      - "MYSQL_DATABASE=guacamole"
      - "MYSQL_USER=guac"
      - "MYSQL_PASSWORD=trolololo
      - "GUACAMOLE_HOME=/data"

Conclusion

Et voilà, normalement vous devriez avoir un Guacamole fonctionnel. Mais il reste quand même quelques soucis :

  • On a un seul port 80 par serveur… et si on veut exposer un autre conteneur dessus on devra choisir entre lui et Guacamole.
  • De plus le service n’est pas chiffré avec HTTPS, c’est un peu con pour un truc qui ne sert que pour des protocoles d’administration.

Mais du coup plutôt que se concentrer sur comment mettre HTTPS sur un Guacomale dockerisé, je vous proposerai la prochaine fois d’étudier une solution généralisable qui sera valable pour tous nos dockers dans la plateforme.

Et donc dans le prochain TP docker je vous parlerai Nginx Proxy Manager ou NPM pour rediriger le trafic web HTTP(S) arrivant sur la machine vers les bon services en fonction du nom de domaine utilisé et des networks pour permettre à nos différents conteneurs de se parler. Mais, stop aux spoilers, et d’ici là, Geekez-bien.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.