Cet article est une sorte de PoC démontrant la possibilité d’héberger plusieurs instance de Wapt sur un même serveur.
Nous ferons dans cet article une maquette avec deux instances mais il est possible de l’adapter pour augmenter le nombre d’instances.
Wapt est un logiciel de déploiement, de mise à jour et de suppression automatisé de paquetages pour Windows edité par TranquilIT.
Wapt existe en deux versions, enterprise et community. Dans cette article nous aborderons uniquement la version community.
Nous installerons deux instances de wapt nommées wapt-dev et wapt-prod.
Pour arriver à nos fins, nous utiliserons le container docker que j’ai mis à disposition sur le docker hub. Pour simplifier la compréhension de ce PoC, le serveur nginx sera installé directement sur l’hôte et non pas dans un container.
Prérequis :
Nous utiliserons un serveur installé en version minimale de Centos 7
Le serveur doit bien évidemment posséder suffisamment de ram, d’espace disque et de puissance cpu pour supporter l’exécution de deux containers.
Deux enregistrements dns font pointer wapt-dev.be-root.com et wapt-prod.be-root.com sur l’adresse IP de notre serveur.
Configuration initiale du système :
Tout d’abord, nous configurons le firewall :
systemctl enable firewalld --now firewall-cmd --permanent --add-service http firewall-cmd --permanent --add-service https
et nous désactivons SELinux :
sed -i 's/enforcing/disabled/g' /etc/selinux/config /etc/selinux/config && setenforce 0
Initialisation des containers
Nous allons maintenant installer Docker et Docker-compose :
yum install -y yum-utils wget yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum install -y docker-ce docker-ce-cli containerd.io systemctl start docker && systemctl enable docker wget https://github.com/docker/compose/releases/download/1.25.5/docker-compose-Linux-x86_64 -O /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose && rehash
Nous allons créer l’environnement nécessaire lancer les containers ainsi que monter les volumes :
mkdir -p /opt/wapt/compose mkdir -p /opt/wapt/wapt-prod/nginx /opt/wapt/wapt-prod/html /opt/wapt/wapt-prod/ssl mkdir -p /opt/wapt/wapt-dev/nginx /opt/wapt/wapt-dev/html /opt/wapt/wapt-dev/ssl
Éditons (et créons) le fichier /opt/wapt/compose/docker-compose.yml :
version: '3' services: wapt-dev: image: clamy54/wapt-ce:latest hostname: wapt-dev.be-root.com container_name: wapt-dev privileged: true ports: - "10080:8080" volumes: - /sys/fs/cgroup:/sys/fs/cgroup:ro - /opt/wapt/wapt-dev/nginx:/etc/nginx - /opt/wapt/wapt-dev/html:/var/www/html - /opt/wapt/wapt-dev/ssl:/opt/wapt/waptserver/ssl environment: - DISABLE_NGINX=1 - WAPT_ADMIN_PASSWORD=passdev wapt-prod: image: clamy54/wapt-ce:latest hostname: wapt-prod.be-root.com container_name: wapt-prod privileged: true ports: - "11080:8080" volumes: - /sys/fs/cgroup:/sys/fs/cgroup:ro - /opt/wapt/wapt-prod/nginx:/etc/nginx - /opt/wapt/wapt-prod/ssl:/opt/wapt/waptserver/ssl - /opt/wapt/wapt-prod/html:/var/www/html environment: - DISABLE_NGINX=1 - WAPT_ADMIN_PASSWORD=passprod
Attention, nous sommes en présence d’un fichier au formal Yaml. L’indentation est donc fondamentale.
La variable d’environnement DISABLE_NGINX=1 permet de désactiver nginx dans le container car nous utiliserons un service nginx commun en frontal directement sur l’hôte.
Cette variable permet également de faire écouter le daemon waptserver sur tous les ports et non pas seulement sur le localhost.
La variable d’environnement WAPT_ADMIN_PASSWORD permet de fixer le mot de passe admin de l’instance wapt. Le port 8080 du container wapt-prod sera mappé sur le port 11080 de l’hôte
et le port 8080 du container wapt-dev sera mappé sur le port 10080 de l’hôte.
Nous pouvons ainsi démarrer les containers :
cd /opt/wapt/compose docker-compose up -d
Installation du frontal nginx
Pour des raisons de cohérence et de droits d’accès aux fichiers, nous allons faire en sorte que l’utilisateur nginx ait les mêmes uid/gid que l’utilisateur nginx à l’intérieur des containers (qui est forcé lors de l’initialisation de ces derniers).
groupadd -g 8080 nginx && useradd -d /var/lib/nginx -g nginx -G nginx -u 8080 -s /sbin/nologin -m nginx && passwd -l nginx
Nous allons maintenant installer nginx :
yum install -y epel-release yum install -y nginx
Grace aux volumes montés sur l’hôte, nous pouvons ainsi configurer facilement nginx.
Nous allons d’abord copier le fichier nginx.conf depuis l’un des container :
cp /opt/wapt/wapt-prod/nginx/nginx.conf /etc/nginx/
Nous allons ensuite créer un fichier /etc/nginx/conf.d/wapt-prod.conf inspiré du fichier /opt/wapt/wapt-prod/nginx/conf.d/wapt.conf et en y adaptant certains paramètres.
server { listen 80; listen 443 ssl; server_name wapt-prod.be-root.com; ssl_certificate "/opt/wapt/wapt-prod/ssl/cert.pem"; ssl_certificate_key "/opt/wapt/wapt-prod/ssl/key.pem"; ssl_protocols TLSv1.2; ssl_dhparam /opt/wapt/wapt-prod/ssl/dhparam.pem; ssl_prefer_server_ciphers on; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_stapling on; ssl_stapling_verify on; ssl_session_cache none; ssl_session_tickets off; #ssl_client_certificate "/opt/wapt/conf/ca-wapt-prod.be-root.com.crt"; #ssl_crl "None"; #ssl_verify_client optional; gzip_min_length 1000; gzip_buffers 4 8k; gzip_http_version 1.0; gzip_disable "msie6"; gzip_types text/plain text/css application/json; gzip_vary on; index index.html; location / { add_header Cache-Control "store, no-cache, must-revalidate, post-check=0, pre-check=0"; add_header Pragma "no-cache"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # be sure these headers are not forwarded proxy_set_header X-Ssl-Client-Dn ""; proxy_set_header X-Ssl-Authenticated ""; client_max_body_size 4096m; client_body_timeout 1800; location /static { alias "/opt/wapt/wapt-prod/html/static"; } location /ssl { alias "/opt/wapt/wapt-prod/html/ssl"; } location ~ ^/(wapt/waptsetup-tis.exe|wapt/waptagent.exe|wapt/waptdeploy.exe|sync.json)$ { root "/opt/wapt/wapt-prod/html"; } location ~ ^/(wapt/.*|wapt-host/.*|waptwua/.*|wapt-diff-repos/.*)$ { root "/opt/wapt/wapt-prod/html"; } location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; client_max_body_size 4096m; client_body_timeout 1800; location /add_host_kerberos { return 403; } location /wapt-host/Packages { return 403; } location / { add_header X-Forwarded-List $http_x_forwarded_for; add_header X-Remote-IP $remote_addr; proxy_pass http://127.0.0.1:11080; } location /socket.io { proxy_http_version 1.1; proxy_buffering off; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_pass http://127.0.0.1:11080/socket.io; } } } }
Les paramêtres à adapter par rapport au fichier initial présent dans le volume sont les chemins des aliases, le server_name correspondant au vhost, les ports référencés dans les paramètres proxy_pass et les chemins des certificats ssl.
De la même façon, nous pouvons créer un fichier /etc/nginx/conf.d/wapt-dev.conf inspiré du fichier /opt/wapt/wapt-dev/nginx/conf.d/wapt.conf :
server { listen 80; listen 443 ssl; server_name wapt-dev.be-root.com; ssl_certificate "/opt/wapt/wapt-dev/ssl/cert.pem"; ssl_certificate_key "/opt/wapt/wapt-dev/ssl/key.pem"; ssl_protocols TLSv1.2; ssl_dhparam /opt/wapt/wapt-dev/ssl/dhparam.pem; ssl_prefer_server_ciphers on; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_stapling on; ssl_stapling_verify on; ssl_session_cache none; ssl_session_tickets off; #ssl_client_certificate "/opt/wapt/conf/ca-wapt-dev.be-root.com.crt"; #ssl_crl "None"; #ssl_verify_client optional; gzip_min_length 1000; gzip_buffers 4 8k; gzip_http_version 1.0; gzip_disable "msie6"; gzip_types text/plain text/css application/json; gzip_vary on; index index.html; location / { add_header Cache-Control "store, no-cache, must-revalidate, post-check=0, pre-check=0"; add_header Pragma "no-cache"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # be sure these headers are not forwarded proxy_set_header X-Ssl-Client-Dn ""; proxy_set_header X-Ssl-Authenticated ""; client_max_body_size 4096m; client_body_timeout 1800; location /static { alias "/opt/wapt/wapt-dev/html/static"; } location /ssl { alias "/opt/wapt/wapt-dev/html/ssl"; } location ~ ^/(wapt/waptsetup-tis.exe|wapt/waptagent.exe|wapt/waptdeploy.exe|sync.json)$ { root "/opt/wapt/wapt-dev/html"; } location ~ ^/(wapt/.*|wapt-host/.*|waptwua/.*|wapt-diff-repos/.*)$ { root "/opt/wapt/wapt-dev/html"; } location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; client_max_body_size 4096m; client_body_timeout 1800; location /add_host_kerberos { return 403; } location /wapt-host/Packages { return 403; } location / { add_header X-Forwarded-List $http_x_forwarded_for; add_header X-Remote-IP $remote_addr; proxy_pass http://127.0.0.1:10080; } location /socket.io { proxy_http_version 1.1; proxy_buffering off; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_pass http://127.0.0.1:10080/socket.io; } } } }
Nous pouvons ensuite lancer nginx :
systemctl enable nginx --now
En conclusion
Nos deux containers tournent et exposent le service waptserver sur les ports 10080 et 11080 de l’hôte.
Le serveur nginx installé sur l’hôte sera reverse proxy pour ces deux services grâce à des vhosts basés sur le nom.
Grace aux volumes docker montés sur l’hôte, le serveur nginx sera également capable de servir l’ensemble des pages et binaires.
Bien évidemment d’autres possibilités ou implémentations sont possibles (par exemple restreindre l’accès à un vhost, nginx en container, automatiser la génération de la configuration nginx, etc …). Déployer un container supplémentaire est facile et rapide : il suffit de créer l’arborescence pour les volumes, d’ajouter une instance au fichier docker-compose et une fois le container lancé, de générer un nouveau vhost nginx en fonction des fichiers de configurations présent dans les volumes montés de l’instance.
Pour accéder à nos instances wapt, il suffit maintenant de lancer depuis une machine Windows la console wapt. Dans « serveur » renseigner le nom de l’instance désirée (wapt-prod.be-root.com ou wapt-dev.be-root.com), de mettre admin en tant que nom d’utilisateur et de renseigner le mot de passe correpondant à l’instance (passprod ou passdev).