14 KiB
Suivi – VPN on-demand studioE5 (client A)
✅ Ce qui fonctionne
-
Agent standalone (mode console / systray)
- Exécutable :
agent/studioE5-agent - Config lu depuis
<data-dir>/studioE5-config.json - Mode console :
-no-tray
- Exécutable :
-
VPN on-demand dans l'agent
- L’agent ne démarre plus Tailscale au boot.
- Le VPN se lance automatiquement à la création/démarrage d’une instance, ou sur commande serveur.
- Implémentation basée sur les binaires
tailscaled+tailscale up(pastsnet, cartsnetne loguait pas automatiquement avec une authkey sur un state vierge).
-
Commandes serveur → agent
- Endpoint de test :
POST /api/internal/send-to-node - Actions supportées :
start_vpn,stop_vpn,start,stop,reset,delete.
- Endpoint de test :
-
Resolver/serveur dans le tailnet studioe5
- Service
resolver-vpn(conteneur Tailscale) partage le netns duresolver. - Le resolver peut joindre les IPs Tailscale des nodes (
ping 100.64.0.xOK).
- Service
-
Instance WordPress démarrée avec succès
- Le resolver a renvoyé une 302 WordPress via
http://resolver:2020/.
- Le resolver a renvoyé une 302 WordPress via
-
Activation zéro-config de l’agent (modèle commercialisable)
- L’agent démarre sans
headscale_urlniheadscale_auth_key. - L’utilisateur entre seulement un code d’activation.
- Le serveur envoie la config Headscale, l’agent la sauvegarde et démarre le VPN automatiquement.
- L’agent démarre sans
✅ Blocage levé
Rate limit Let’s Encrypt pour edudeploy.com est levé.
Le 2026-06-23 vers 09:35 UTC, Caddy a pu obtenir un certificat Let’s Encrypt pour test-wp-001.studioe5.edudeploy.com :
tls.obtain: certificate obtained successfully identifier=test-wp-001.studioe5.edudeploy.com issuer=acme-v02.api.letsencrypt.org-directory
Le flux complet HTTPS public est désormais validé :
curl -sS -I -L https://test-wp-001.studioe5.edudeploy.com/
# => HTTP/2 302 -> HTTP/2 200 (WordPress install.php)
Le DNS wildcard *.studioe5.edudeploy.com est en place. Caddy utilise toujours tls { on_demand } et émet un certificat par sous-domaine d’instance.
🎯 Validation du flux HTTPS public
Le 2026-06-23 09:39 UTC, le flux complet a été validé :
Client (HTTPS) → Caddy (:443) → resolver (:2020) → Tailnet (100.64.0.8) → agent → WordPress (:8001)
Résultat :
$ curl -sS -I -L https://test-wp-001.studioe5.edudeploy.com/
HTTP/2 302
location: https://test-wp-001.studioe5.edudeploy.com/wp-admin/install.php
...
HTTP/2 200
- Certificat Let’s Encrypt obtenu automatiquement par Caddy (
tls { on_demand }). - Le resolver réécrit les en-têtes
Locationet le contenu HTML pour passer dehttp://àhttps://.
📁 Fichiers modifiés (non exhaustif)
agent/tailscale.go– lancementtailscaled+tailscale up, gestion start/stop/status.agent/websocket.go– handlersstart_vpn/stop_vpn,ensureTailscale().agent/docker.go– remplacement des placeholders{PORT}et{INSTANCE_ID}dans les compose.docker-compose.yml– ajout du sidecarresolver-vpn, suppression descap_add/ip routeobsolètes surserver/resolver.Caddyfile– configuration on-demand TLS pour les instances..env– clé pré-auth Headscale mise à jour (clé réutilisable).
🧪 Tests / environnement de test actuel
Agent de test lancé en arrière-plan :
- data-dir :
/tmp/studioe5-test-clienta - node-id :
vps-8fc665eb - tailnet IP actuelle :
100.64.0.8 - PID :
3151830(lancé le 2026-06-23 09:36 UTC)
Instance de test créée :
- ID :
test-wp-001 - Node :
vps-8fc665eb - Port :
8001 - Template :
wordpress-wordpress-latest - État : WordPress répond sur
http://127.0.0.1:8001et en HTTPS public surhttps://test-wp-001.studioe5.edudeploy.com/.
🛠️ Commandes utiles pour reprendre
Voir l’agent de test
pgrep -a studioe5-agent
Relancer l’agent de test (si besoin)
mkdir -p /tmp/studioe5-test-clienta
cat > /tmp/studioe5-test-clienta/studioE5-config.json <<EOF
{
"server": "wss://studioe5.edudeploy.com/api/websocket",
"headscale_url": "https://headscale.studioe5.edudeploy.com",
"headscale_auth_key": "$(grep HEADSCALE_AUTH_KEY /opt/studioe5-client-a/.env | cut -d= -f2)",
"node_id": "vps-8fc665eb",
"data_dir": "/tmp/studioe5-test-clienta"
}
EOF
cd /opt/studioe5-client-a/agent
./studioE5-agent -no-tray -data-dir /tmp/studioe5-test-clienta
Démarrer le VPN manuellement
curl -sS -X POST https://studioe5.edudeploy.com/api/internal/send-to-node \
-H "Content-Type: application/json" \
-d '{"nodeId":"vps-8fc665eb","message":{"action":"start_vpn"}}'
Voir les nodes Headscale
cd /opt/studioe5-client-a
docker compose exec -T headscale headscale nodes list studioe5
Tester le resolver (depuis Caddy)
cd /opt/studioe5-client-a
docker exec studioe5-caddy curl -sS -I -H "Host: test-wp-001.studioe5.edudeploy.com" http://resolver:2020/
Tester en HTTPS public (dès que la limite sera levée)
curl -sS -I -L https://test-wp-001.studioe5.edudeploy.com/
🌐 Flux complet testé via l’API web
Test réalisé le 2026-06-23 en utilisant le compte superadmin :
- Authentification NextAuth sur
/api/auth/callback/credentials. - Création d’instance via
POST /api/instances:→ Instance créée :{ "nodeId": "vps-8fc665eb", "templateId": "wordpress-wordpress-latest", "port": 8002 }cmqqgrur20001lw67t2bdgzkg. - Le serveur a automatiquement envoyé l’action
startau node via WebSocket. - L’agent a démarré le VPN (si besoin), écrit le compose et a lancé les conteneurs WordPress.
- Caddy a obtenu un certificat Let’s Encrypt pour
cmqqgrur20001lw67t2bdgzkg.studioe5.edudeploy.com. - Validation HTTPS :
curl -sS -I -L https://cmqqgrur20001lw67t2bdgzkg.studioe5.edudeploy.com/ # => HTTP/2 302 -> HTTP/2 200 (WordPress install.php)
Le flux UI → API → WebSocket → agent → Docker → VPN → Caddy → HTTPS public est fonctionnel.
💻 Téléchargement de l’agent
L’agent est servi par Caddy depuis le dossier agent/ monté dans le conteneur Caddy (./agent:/usr/share/caddy/agent).
Binaires disponibles
- Windows (archive complète) :
https://studioe5.edudeploy.com/studioE5-agent-v0.3.0-windows.zip- Contient
studioE5-agent.exe+tailscale-bin/windows/(tailscale.exe,tailscaled.exe,wintun.dll) +README-Windows.txt.
- Contient
- Windows (exécutable seul) :
https://studioe5.edudeploy.com/studioE5-agent-v0.3.0.exe- Nécessite d’avoir installé Tailscale Windows séparément ou d’avoir les binaires dans
tailscale-bin/windows/.
- Nécessite d’avoir installé Tailscale Windows séparément ou d’avoir les binaires dans
- Linux :
https://studioe5.edudeploy.com/studioE5-agent-v0.3.0
Builder / préparer les binaires
cd /opt/studioe5-client-a/agent
# 1. Télécharger les binaires Tailscale Windows (nécessite msitools)
./download-tailscale-bins.sh 1.98.4
# 2. Builder l’agent pour Windows et Linux (macOS nécessite CGO)
./build.sh
Le build.sh génère automatiquement studioE5-agent-v0.3.0-windows.zip et copie les binaires versionnés dans server/public/.
Flow d’activation zéro-config (modèle commercialisable)
L’élève/employé n’a aucune configuration technique à saisir :
- Télécharger l’agent Windows (
studioE5-agent-v0.3.0-windows.zip). - Extraire et lancer
studioE5-agent.exe. - Entrer le code d’activation à 6 caractères fourni par l’établissement (affiché dans l’UI locale
http://localhost:7070). - L’agent contacte le serveur, le serveur vérifie le code et renvoie automatiquement :
- l’identité de l’élève (
studentName) - l’URL Headscale
- la clé pré-auth Headscale
- l’identité de l’élève (
- L’agent sauvegarde ces informations localement et démarre automatiquement le VPN.
- L’agent est alors visible dans le dashboard et peut recevoir des instances.
Configuration manuelle (mode debug / admin)
Si besoin, on peut toujours forcer une config via data/studioE5-config.json :
{
"server": "wss://studioe5.edudeploy.com/api/websocket",
"headscale_url": "https://headscale.studioe5.edudeploy.com",
"headscale_auth_key": "CLE_PREAUTH_ICI",
"node_id": "IDENTIFIANT_DU_POSTE",
"data_dir": "C:\\studioE5-agent\\data"
}
⚠️
headscale_auth_keydoit être une clé pré-auth réutilisable valide pour le tailnet studioe5. Ne jamais commiter cette clé.
Lancement :
.\studioE5-agent.exe -no-tray -data-dir C:\studioE5-agent\data
📋 Prochaines étapes à faire
Attendre la fin du rate limit Let’s Encrypt(levé le 2026-06-23).Relancer un test HTTPS sur→ OK (HTTP/2 200).https://test-wp-001.studioe5.edudeploy.com/Créer une branche dédiée et commiter les modifications VPN on-demand→ branchefeat/studioe5-vpn-ondemand, commit124543d. Push vers Gitea à faire dès que le remote sera accessible (actuellementlocalhost:3001etgitea.alfrednobel.edudeploy.cominjoignables).Tester le flux complet depuis l’interface web→ OK via l’API authentifiée (POST /api/instances), instancecmqqgrur20001lw67t2bdgzkgaccessible en HTTPS public.- Obtenir un certificat wildcard pour
*.studioe5.edudeploy.com(voir étude ci-dessous). - Nettoyer les instances/agent de test une fois le wildcard en place et le push effectué.
Packager les binaires Tailscale pour Windows→ OK,download-tailscale-bins.sh+studioE5-agent-v0.3.0-windows.zipprêt.- Nettoyer les anciens nodes/volumes Headscale créés pendant les tests.
- Documenter la procédure de mise en production pour le client A (config agent, clés Headscale, ports, etc.).
💡 Améliorations UI envisagées
Console / log intégré dans l’agent
Plutôt que de laisser Windows ouvrir une fenêtre noire à chaque commande podman/docker/tailscale, rediriger le Stdout/Stderr de chaque commande vers l’UI locale de l’agent (http://localhost:7070).
Bénéfices :
- Expérience utilisateur plus propre et commercialisable.
- Diagnostic facilité : l’utilisateur voit exactement ce qui se passe (téléchargement d’image, démarrage, installation PrestaShop, etc.).
Implémentation :
- Remplacer
cmd.Stdout = os.Stdoutpar unio.Pipe()oubytes.Bufferdansdocker.go,tailscale.go, etc. - Envoyer les lignes de log au frontend via le WebSocket existant (
agent/ui/websocket). - Afficher les logs dans un panneau dédié du HTML.
Barre de progression
Associer des étapes connues à une barre de progression dans l’UI :
| Étape | Poids |
|---|---|
| Connexion au serveur | 10 % |
| Démarrage du VPN | 25 % |
| Téléchargement de l’image Docker | 50 % |
| Création de la base de données | 70 % |
| Installation de PrestaShop/WordPress | 90 % |
| Instance prête | 100 % |
L’agent envoie des messages progress au frontend à chaque étape franchie.
🔒 Étude certificat wildcard *.studioe5.edudeploy.com
Pourquoi passer en wildcard ?
Avec tls { on_demand }, Caddy émet un certificat Let’s Encrypt par sous-domaine d’instance. Cela expose au rate limit de 50 certificats par domaine principal (edudeploy.com) sur 7 jours. Un certificat wildcard unique (*.studioe5.edudeploy.com) couvre tous les sous-domaines d’instances et évite ce problème.
Contrainte technique
Un certificat wildcard nécessite le challenge DNS-01 (le challenge HTTP-01 ne permet pas de valider *.domain.tld). Caddy doit donc pouvoir créer un enregistrement TXT automatiquement chez le registrar DNS.
Infomaniak (registrar actuel)
Le DNS de edudeploy.com est chez Infomaniak :
dig NS edudeploy.com +short
# nsany1.infomaniak.com.
# nsany2.infomaniak.com.
Il existe un module Caddy DNS pour Infomaniak :
- Repository :
github.com/caddy-dns/infomaniak - Nécessite un token API Infomaniak avec droits DNS.
Implémentation à envisager
- Générer un token API Infomaniak (compte client A ou compte dédié avec accès au domaine).
- Builder une image Caddy custom avec le module :
FROM caddy:2-builder AS builder RUN xcaddy build --with github.com/caddy-dns/infomaniak FROM caddy:2-alpine COPY --from=builder /usr/bin/caddy /usr/bin/caddy - Modifier le
Caddyfilepour gérer le wildcard :*.studioe5.edudeploy.com { tls { dns infomaniak {env.INFOMANIAK_API_TOKEN} } reverse_proxy resolver:2020 { header_up Host {host} } } - Ajouter le token dans
.envet le passer au conteneur Caddy. - Supprimer ou ajuster le bloc
:443actuel qui utiliseon_demandpour les instances.
Alternative sans module DNS
Obtenir le certificat wildcard manuellement (Certbot DNS-01, acheté, etc.) et le charger dans Caddy :
*.studioe5.edudeploy.com {
tls /data/certs/wildcard.crt /data/certs/wildcard.key
reverse_proxy resolver:2020 {
header_up Host {host}
}
}
Inconvénient : renouvellement manuel.
🔧 Notes techniques
- Le conteneur
resolver-vpnutilisenetwork_mode: service:resolverpour partager le netns avec le resolver. - L’agent utilise
tailscaled --tun=userspace-networking; le resolver-vpn utilise un vrai TUN (tailscale0). - Le
Caddyfileactuel utilisetls { on_demand }pour les instances. En cas de nouvelle rate limit, on peut temporairement remettretls internaldans le bloc:443pour valider le flux sans certificat public.