Files
edubox/SUIVI_VPN_ONDEMAND.md
T
EduBox Dev d090f67bff fix(agent/windows): named pipe Tailscale + hideWindow + logs
- Use Windows named pipe \.\pipe\studioe5-tailscaled instead of Unix socket
- Apply hideWindow to all child processes (tailscale, podman, docker, browser)
- Redirect agent logs to <data-dir>/agent.log and tailscaled logs to tailscaled.log
- Fix double tailscale/ tailscale dir path in startTailscaleAndReport
- Remove --operator=root on Windows
- Bump agent version to 0.3.1
2026-06-23 18:18:26 +00:00

15 KiB
Raw Blame History

Suivi VPN on-demand studioE5 (client A)

Ce qui fonctionne

  1. Agent standalone (mode console / systray)

    • Exécutable : agent/studioE5-agent
    • Config lu depuis <data-dir>/studioE5-config.json
    • Mode console : -no-tray
  2. VPN on-demand dans l'agent

    • Lagent ne démarre plus Tailscale au boot.
    • Le VPN se lance automatiquement à la création/démarrage dune instance, ou sur commande serveur.
    • Implémentation basée sur les binaires tailscaled + tailscale up (pas tsnet, car tsnet ne loguait pas automatiquement avec une authkey sur un state vierge).
  3. Commandes serveur → agent

    • Endpoint de test : POST /api/internal/send-to-node
    • Actions supportées : start_vpn, stop_vpn, start, stop, reset, delete.
  4. Resolver/serveur dans le tailnet studioe5

    • Service resolver-vpn (conteneur Tailscale) partage le netns du resolver.
    • Le resolver peut joindre les IPs Tailscale des nodes (ping 100.64.0.x OK).
  5. Instance WordPress démarrée avec succès

    • Le resolver a renvoyé une 302 WordPress via http://resolver:2020/.
  6. Activation zéro-config de lagent (modèle commercialisable)

    • Lagent démarre sans headscale_url ni headscale_auth_key.
    • Lutilisateur entre seulement un code dactivation.
    • Le serveur envoie la config Headscale, lagent la sauvegarde et démarre le VPN automatiquement.

Blocage levé

Rate limit Lets Encrypt pour edudeploy.com est levé.
Le 2026-06-23 vers 09:35 UTC, Caddy a pu obtenir un certificat Lets 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 dinstance.

🎯 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 Lets Encrypt obtenu automatiquement par Caddy (tls { on_demand }).
  • Le resolver réécrit les en-têtes Location et le contenu HTML pour passer de http:// à https://.

📁 Fichiers modifiés (non exhaustif)

  • agent/tailscale.go lancement tailscaled + tailscale up, gestion start/stop/status.
  • agent/websocket.go handlers start_vpn / stop_vpn, ensureTailscale().
  • agent/docker.go remplacement des placeholders {PORT} et {INSTANCE_ID} dans les compose.
  • docker-compose.yml ajout du sidecar resolver-vpn, suppression des cap_add/ip route obsolètes sur server/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:8001 et en HTTPS public sur https://test-wp-001.studioe5.edudeploy.com/.

🪟 Fix agent Windows v0.3.1

Problème rencontré sur le PC de test (OMEGA-GAMER-dc166b1a) :

  • Le nœud apparaissait online dans le dashboard mais sans IP Tailscale.
  • tailscale.exe ip -4 retournait une erreur de connexion au socket local.

Cause racine :

  • Lagent lançait tailscaled avec --socket=<fichier>.sock, mais Tailscale sur Windows utilise des named pipes (\\.\pipe\...), pas des sockets Unix.
  • De plus, les commandes podman/docker/tailscale ouvraient une fenêtre console à chaque exécution.

Corrections apportées (agent/tailscale.go, agent/docker.go, agent/instance.go, agent/systray.go, agent/ui.go, agent/main.go) :

  • Sur Windows, utilisation de la named pipe \\.\pipe\studioe5-tailscaled.
  • Application de hideWindow à tous les processus enfants (Tailscale, Podman, Docker, ouverture navigateur, redémarrage agent).
  • Redirection des logs agent vers <data-dir>/agent.log et des logs tailscaled vers <data-dir>/tailscale/tailscaled.log.
  • Suppression de --operator=root sur Windows (non pertinent).
  • Correction du chemin dataDir passé à startTailscale (évitait un double dossier tailscale/tailscale).

Validation manuelle sur Windows :

.\tailscaled.exe --state="C:\...\data\tailscale.state" --socket="\\.\pipe\studioe5-tailscaled" --tun=userspace-networking
.\tailscale.exe --socket="\\.\pipe\studioe5-tailscaled" status  # => Logged out (NeedsLogin)

🛠️ Commandes utiles pour reprendre

Voir lagent de test

pgrep -a studioe5-agent

Relancer lagent 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 lAPI web

Test réalisé le 2026-06-23 en utilisant le compte superadmin :

  1. Authentification NextAuth sur /api/auth/callback/credentials.
  2. Création dinstance via POST /api/instances :
    {
      "nodeId": "vps-8fc665eb",
      "templateId": "wordpress-wordpress-latest",
      "port": 8002
    }
    
    → Instance créée : cmqqgrur20001lw67t2bdgzkg.
  3. Le serveur a automatiquement envoyé laction start au node via WebSocket.
  4. Lagent a démarré le VPN (si besoin), écrit le compose et a lancé les conteneurs WordPress.
  5. Caddy a obtenu un certificat Lets Encrypt pour cmqqgrur20001lw67t2bdgzkg.studioe5.edudeploy.com.
  6. 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 lagent

Lagent 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.1-windows.zip
    • Contient studioE5-agent.exe + tailscale-bin/windows/ (tailscale.exe, tailscaled.exe, wintun.dll) + README-Windows.txt.
  • Windows (exécutable seul) : https://studioe5.edudeploy.com/studioE5-agent-v0.3.1.exe
    • Nécessite davoir installé Tailscale Windows séparément ou davoir les binaires dans tailscale-bin/windows/.
  • Linux : https://studioe5.edudeploy.com/studioE5-agent-v0.3.1

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 lagent 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 dactivation zéro-config (modèle commercialisable)

L’élève/employé na aucune configuration technique à saisir :

  1. Télécharger lagent Windows (studioE5-agent-v0.3.0-windows.zip).
  2. Extraire et lancer studioE5-agent.exe.
  3. Entrer le code dactivation à 6 caractères fourni par l’établissement (affiché dans lUI locale http://localhost:7070).
  4. Lagent contacte le serveur, le serveur vérifie le code et renvoie automatiquement :
    • lidentité de l’élève (studentName)
    • lURL Headscale
    • la clé pré-auth Headscale
  5. Lagent sauvegarde ces informations localement et démarre automatiquement le VPN.
  6. Lagent 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_key doit ê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 Lets Encrypt (levé le 2026-06-23).
  • Relancer un test HTTPS sur https://test-wp-001.studioe5.edudeploy.com/OK (HTTP/2 200).
  • Créer une branche dédiée et commiter les modifications VPN on-demand → branche feat/studioe5-vpn-ondemand, commit 124543d. Push vers Gitea à faire dès que le remote sera accessible (actuellement localhost:3001 et gitea.alfrednobel.edudeploy.com injoignables).
  • Tester le flux complet depuis linterface webOK via lAPI authentifiée (POST /api/instances), instance cmqqgrur20001lw67t2bdgzkg accessible 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 WindowsOK, download-tailscale-bins.sh + studioE5-agent-v0.3.0-windows.zip prê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 lagent

Plutôt que de laisser Windows ouvrir une fenêtre noire à chaque commande podman/docker/tailscale, rediriger le Stdout/Stderr de chaque commande vers lUI locale de lagent (http://localhost:7070).

Bénéfices :

  • Expérience utilisateur plus propre et commercialisable.
  • Diagnostic facilité : lutilisateur voit exactement ce qui se passe (téléchargement dimage, démarrage, installation PrestaShop, etc.).

Implémentation :

  1. Remplacer cmd.Stdout = os.Stdout par un io.Pipe() ou bytes.Buffer dans docker.go, tailscale.go, etc.
  2. Envoyer les lignes de log au frontend via le WebSocket existant (agent/ui/websocket).
  3. Afficher les logs dans un panneau dédié du HTML.

Barre de progression

Associer des étapes connues à une barre de progression dans lUI :

Étape Poids
Connexion au serveur 10 %
Démarrage du VPN 25 %
Téléchargement de limage Docker 50 %
Création de la base de données 70 %
Installation de PrestaShop/WordPress 90 %
Instance prête 100 %

Lagent 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 Lets Encrypt par sous-domaine dinstance. 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 dinstances 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

  1. Générer un token API Infomaniak (compte client A ou compte dédié avec accès au domaine).
  2. 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
    
  3. Modifier le Caddyfile pour gérer le wildcard :
    *.studioe5.edudeploy.com {
        tls {
            dns infomaniak {env.INFOMANIAK_API_TOKEN}
        }
        reverse_proxy resolver:2020 {
            header_up Host {host}
        }
    }
    
  4. Ajouter le token dans .env et le passer au conteneur Caddy.
  5. Supprimer ou ajuster le bloc :443 actuel qui utilise on_demand pour 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-vpn utilise network_mode: service:resolver pour partager le netns avec le resolver.
  • Lagent utilise tailscaled --tun=userspace-networking ; le resolver-vpn utilise un vrai TUN (tailscale0).
  • Le Caddyfile actuel utilise tls { on_demand } pour les instances. En cas de nouvelle rate limit, on peut temporairement remettre tls internal dans le bloc :443 pour valider le flux sans certificat public.