06 Déploiement

Configuration initiale (Golden Sample), industrialisation multi-CloudGate, accès distant via Cloudflare Tunnel

Stratégie en 3 phases

  1. Pilote (Golden Sample) : 1 CloudGate parfaitement configurée, validée end-to-end contre les endpoints cibles
  2. Export config + flow LuvitRED sur CloudGate Universe → version cloudgate-prod-v1.0
  3. Clones : nouvelles CG provisionnées en pulling cette version depuis CloudGate Universe

Phase 1 — Configurer le Golden Sample

1.1 Connexion initiale

Câble Ethernet entre poste d'admin et CG. IP LAN CG à 192.168.42.1 (configurable via l'admin web pour éviter les conflits LAN).

Web adminhttp://192.168.42.1 (admin / $ADMIN_PASS)
LuvitRED canvashttp://192.168.42.1:8080
SSHsshpass -p '$ADMIN_PASS' ssh admin@192.168.42.1 + algos legacy

1.2 Activer LoRa (Cloud Wizard)

Web admin → Configuration → Cloud Wizard → activer LoRa server + LoRa app + Forwarder EU868.

1.3 Déployer le canvas LuvitRED

Importer dans LuvitRED admin → menu Import → From Clipboard → coller le contenu de deploy_flow.json :

# depuis la machine d'admin
sshpass -p '$ADMIN_PASS' scp -o KexAlgorithms=+diffie-hellman-group1-sha1 \
   -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedAlgorithms=+ssh-rsa \
   deploy_flow.json admin@192.168.42.1:/tmp/

# (optionnel) backup du flow.json existant
sshpass -p '$ADMIN_PASS' ssh -o ... admin@192.168.42.1 \
   "cp /etc/luvitred/flow.json /etc/luvitred/flow.json.bak.$(date +%s)"

1.4 Configurer les globals via console Lua ou inject startup

Une seule modification du fn_startup_init avec les valeurs cibles :

global.iobase_host  = 'iobase.example.com'
global.dap_host     = 'dap.example.com'
global.iobase_site  = 'site_a'
global.iobase_datasource = 'transportation'
global.iobase_metrics_default = '["50001m_iot_pit002","50001m_iot_tt002"]'

global.asystom_url      = 'https://advisor.example.com'
global.asystom_auth_b64 = '<base64(user:password)>'
global.asystom_network  = 'cloudgate-XX'
global.asystom_client   = '<asystom_client_id>'

1.5 Enrôlement DAP

  1. Tirer inject DAP register
  2. Vérifier DAP_REGISTER_OK device_code=DC... dans le debug
  3. L'administrateur IoBase valide le device dans le portail (« Services et équipements »« Valider l'équipement »). Sans cette étape, l'appel suivant retournera HTTP 425.
  4. Tirer inject DAP get token
  5. Vérifier DAP_TOKEN_OK + /mnt/data/luvitred/dap_state.json écrit

1.6 Test E2E

Phase 2 — Export Golden Sample

2.1 Backup local

# Flow LuvitRED export
curl -b /tmp/lc.cookies http://192.168.42.1:8080/flows > cloudgate-prod-v1.0.flow.json

# Config CG export
http://192.168.42.1 → Configuration → Export → cloudgate-prod-v1.0.tar.gz

# Tokens DAP (NE PAS PARTAGER)
sshpass -p '...' scp ... admin@192.168.42.1:/mnt/data/luvitred/dap_state.json \
   ./cloudgate-prod-v1.0.dap_state.SECRET.json

2.2 Upload sur CloudGate Universe

CloudGate Universe → Devices → Configurations → New Version → upload cloudgate-prod-v1.0.tar.gz. Un compte CloudGate Universe valide est requis (à demander à l'administrateur de la flotte).

Phase 3 — Cloner sur d'autres CloudGates

3.1 Provisioning du clone

  1. Factory reset de la nouvelle CG (web admin → Reset)
  2. Câble + login admin / $ADMIN_PASS
  3. Configuration → Provisioning → Pull from CloudGate Universe → cloudgate-prod-v1.0
  4. La CG redémarre avec la même config (LoRa + forwarder + flow LuvitRED)

3.2 Spécifique au site

Modifier sur la nouvelle CG :

3.3 Enrôler les balises du site

Voir Chap. 05.

Accès distant — Cloudflare Tunnel

L'accès distant aux interfaces locales de la CG (admin web port 80, LuvitRED 8080, SSH) repose sur l'agent cloudflared. L'agent ouvre une connexion sortante persistante vers le réseau Cloudflare ; aucun port entrant n'est exposé sur la CG. L'URL publique (ex. cloudgate-XX.<domaine>) est ensuite protégée par Cloudflare Access (One-time PIN par email, ou Google/Microsoft SSO).

📦
CloudGate
cloudflared agent
localhost:80 / :8080
☁️
Cloudflare Edge
Tunnel + Access policy
One-time PIN / SSO
🌐
Opérateur
cloudgate-XX.<domaine>
auth Email PIN

Pré-requis

Limitation accès root sur CG factory
L'utilisateur admin du firmware CG par défaut n'a pas accès root, et SSH root est désactivé. L'installation persistante de cloudflared requiert soit un firmware custom (CloudGate Universe) soit un wrapping via le canvas LuvitRED (qui tourne en root) pour copier le binaire dans /mnt/data et le lancer via os.execute au boot.

Étape 1 — Installer le binaire

# Architecture CG = ARMv5 (uname -m → armv5tejl)
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm
chmod +x cloudflared-linux-arm
cp cloudflared-linux-arm /usr/local/bin/cloudflared

# Vérification
cloudflared version    # → cloudflared version 2026.x.x

Étape 2 — Login + création du tunnel

# Génère un cert.pem dans /root/.cloudflared/
cloudflared tunnel login        # ouvre une URL à autoriser dans le browser

# Crée le tunnel (1 par CG ou tunnel partagé selon stratégie)
cloudflared tunnel create cloudgate-XX
# → produit /root/.cloudflared/<UUID>.json (credentials, à conserver)

Étape 3 — config.yml (mapping ingress)

# /root/.cloudflared/config.yml
tunnel: <UUID_DU_TUNNEL>
credentials-file: /root/.cloudflared/<UUID>.json

ingress:
  - hostname: cloudgate-XX.<domaine>
    service: http://localhost:8080      # LuvitRED
  - hostname: cloudgate-XX-admin.<domaine>
    service: http://localhost:80        # admin web
  - service: http_status:404            # default catchall

Étape 4 — Routage DNS + service

# Crée le CNAME automatique sur la zone Cloudflare
cloudflared tunnel route dns cloudgate-XX cloudgate-XX.<domaine>
cloudflared tunnel route dns cloudgate-XX cloudgate-XX-admin.<domaine>

# Service système (survit au reboot)
cloudflared service install
systemctl enable cloudflared
systemctl start  cloudflared
systemctl status cloudflared    # vérifier "active (running)"

Étape 5 — Cloudflare Access (sécurisation de l'URL)

Sans Access, l'URL publique est ouverte au monde. Il faut ajouter une policy.

  1. Cloudflare Zero Trust → Access > Applications > Add an application
  2. Type : Self-hosted
  3. Application Name : CloudGate XX · Domain : cloudgate-XX.<domaine> (ou wildcard *.<domaine>)
  4. Policies : Allow · Include = Emails ending in @<votre-domaine> ou liste explicite d'emails opérateurs
  5. Identity Provider : One-time PIN par email (par défaut) ou Google/Microsoft SSO

Multi-CG : workflow d'ajout d'une nouvelle CG

  1. Installer cloudflared sur la nouvelle CG (étape 1)
  2. Lier au tunnel existant OU en créer un par CG (étape 2)
  3. Ajouter le hostname cloudgate-YY.<domaine> dans le dashboard Cloudflare (Networks > Tunnels > Edit > Public Hostname)
  4. Si Access est sur wildcard *.<domaine>, la policy s'applique automatiquement, sinon ajouter le hostname dans la liste de l'application

Points de vigilance

PointVérification
Architecture CPUuname -m sur la CG → confirmer armv5tejl avant download du binaire
Persistance servicesystemctl is-enabled cloudflared doit retourner enabled
Credentials JSON/root/.cloudflared/<UUID>.json est le secret qui authentifie le tunnel — backup chiffré, ne jamais commit en clair
Survie au reboot CGTester un reboot complet et vérifier que le tunnel remonte sans intervention (cloudflared tunnel info cloudgate-XX côté Cloudflare)
Latence opérateurCloudflare ajoute ~50–150 ms (edge le plus proche). Acceptable pour admin web/SSH, à mesurer si flux temps réel requis.