Skip to content

Provisioning VPN WireGuard ​

Problem Statement ​

Les devices Android doivent disposer d'une IP VPN WireGuard connue du CMS pour permettre les operations reseau et support a distance. Le champ CMS source est devices.ip_vpn.

Sans provisioning automatique, un device nouvellement associe ou reinstallé peut demarrer sans IP VPN, ce qui rend l'administration distante incomplete.

Solution Overview ​

L'application provisionne un acces WireGuard quand ip_vpn est absent lors de la lecture des donnees CMS device. Un bouton dans Settings > Reseau permet aussi de relancer manuellement le provisioning en mode force.

Le mode force recree toujours un peer WireGuard, meme si devices.ip_vpn contient deja une valeur.

Startup Flow ​

Le flux automatique passe par les services de fond du layout.

  1. src/routes/+layout.svelte monte BackgroundServices.
  2. BackgroundServices detecte un contexte Android avec UID valide.
  3. createAndroidDeploymentOrchestrator().ensureDeviceCmsData() appelle getDeviceCmsData(uid).
  4. getDeviceCmsData() lit devices dans Directus avec DEVICE_FIELDS, dont ip_vpn.
  5. Si ip_vpn est vide, provisionWireGuardVpn(uid, { existingIp }) est appele.
  6. Si le provisioning reussit, la nouvelle IP est stockee dans devices.ip_vpn et dans le snapshot local deviceCmsData.

Le flux LG appelle aussi getDeviceCmsData() via src/lib/lg/orchestrator.ts, mais le provisioning reste conditionne par les controles browser, le bridge hote et la disponibilite du client VPN.

Manual Reprovisioning ​

L'onglet Settings > Reseau expose un bouton Relancer provisioning VPN dans la carte VPN.

Ce bouton appelle :

ts
provisionWireGuardVpn(uid, { force: true });

Avec force: true, l'application ignore l'IP existante et demande toujours la creation d'un nouveau peer WireGuard. La nouvelle IP retournee remplace devices.ip_vpn dans le CMS.

Implementation Guide ​

La logique principale est dans src/lib/utils/utilsCms.ts.

  • getDeviceCmsData(uid) conserve le comportement automatique au boot.
  • provisionWireGuardVpn(uid, options) execute le provisioning et retourne un resultat typĂ©.
  • updateDeviceVpnIp(uid, ip) met a jour le champ Directus devices.ip_vpn.
  • generateWireGuardAccess(baseUrl, token, uid) appelle le service WireGuard et construit le deep link d'import.

Le provisioning utilise strictement le host bridge Android pour les operations natives :

json
{ "action": "CAN_LAUNCH_APP", "params": { "appId": "fr.tvcast.vpn" } }

Puis, apres generation de la configuration WireGuard :

json
{
	"action": "LAUNCH_APP",
	"params": {
		"appId": "fr.tvcast.vpn",
		"dataUri": "vpn://import?config=<client_config_url_encoded>"
	}
}

Il n'y a pas de fallback window.open(..., '_system') : si le bridge ne peut pas lancer le client VPN, le provisioning echoue explicitement.

Le service WireGuard actuel est appele en GET :

text
https://wg2.comminter.com/generate-and-add-peer?uid=<uid>

La reponse attendue contient :

json
{
	"ip": "10.0.0.10/32",
	"client_config": "..."
}

L'application nettoie l'IP pour conserver uniquement l'IPv4, puis demande au host bridge d'ouvrir :

text
vpn://import?config=<client_config_url_encoded>

Preconditions ​

  • Execution cote browser.
  • Preview mode desactive.
  • UID normalise disponible.
  • Client VPN Android installe avec le package fr.tvcast.vpn.
  • Host bridge Android compatible avec CAN_LAUNCH_APP et LAUNCH_APP.
  • Service WireGuard accessible.
  • CMS Directus accessible pour mettre a jour devices.ip_vpn.

Troubleshooting ​

  • vpn_app_not_available : le host bridge indique que fr.tvcast.vpn ne peut pas etre lance.
  • vpn_app_check_failed : l'application n'a pas pu verifier la disponibilite du client VPN via le host bridge.
  • vpn_app_launch_failed : le host bridge n'a pas pu ouvrir le deep link d'import VPN.
  • invalid_wireguard_ip : le service WireGuard n'a pas retourne une IPv4 valide.
  • wireguard_request_failed : l'appel au service WireGuard a echoue.
  • not_browser : le provisioning a ete appele hors environnement browser.
  • preview_mode : le provisioning a ete bloque pour eviter un effet externe en preview.
  • invalid_uid : l'UID fourni est vide ou invalide apres normalisation.

Compatibility ​

La fonctionnalite vise principalement Android et le client fr.tvcast.vpn. Les plateformes sans client VPN compatible peuvent afficher l'etat reseau via GET_NETWORK_INFO, mais ne peuvent pas importer la configuration WireGuard via le deep link actuel.

Performance ​

Le provisioning automatique ne se lance que si ip_vpn est absent. La relance manuelle est explicite et ne s'execute que sur action utilisateur.

L'appel reseau WireGuard et la mise a jour CMS sont sequentiels pour garantir que l'IP stockee correspond au peer cree.

Security Notes ​

Le token WireGuard est actuellement embarque cote frontend dans utilsCms.ts. C'est une dette de securite : tout secret present dans le bundle web peut etre extrait.

La cible recommandee est de deplacer le token cote backend :

  1. Creer un endpoint controle, par exemple POST /vpn/provision.
  2. Stocker le token WireGuard dans une variable d'environnement privee du serveur.
  3. Faire appeler wg2.comminter.com par le backend uniquement.
  4. Retourner au frontend uniquement l'IP et les donnees necessaires a l'import VPN.

Ne pas utiliser PUBLIC_*, VITE_*, localStorage, constante TypeScript ou configuration embarquee pour stocker ce token.