127.0.0.1, vérifier un jeton partagé à chaque connexion et fusionner les deux voies dans un seul état de santé régional. C’est le cousin de l’article tunnel SSH depuis le loopback : même posture à faible exposition, autre transport.
La plupart des flottes OpenClaw sur vpshalo choisissent l’un de trois périmètres : un overlay Tailscale / MagicDNS, un tunnel SSH inverse depuis le loopback, ou — traité ici — une chaîne frp STCP. Le STCP convient lorsque les meshes overlay sont interdits et que GatewayPorts sur les bastions inquiète la sécurité : les visiteurs doivent présenter une clé secrète avant qu’un octet TCP n’atteigne votre Mac, et les deux bouts restent sur 127.0.0.1. Croisez le schéma avec la matrice GeoDNS et latence SSH pour le choix des PoP, l’article Cloudflare Tunnel lorsque le TLS public doit vivre en bordure, et le HowTo JumpHost & sondes fusionnées pour les formes de checks amont. Les CTA publiques mènent vers l’accueil, les tarifs, l’aide et l’achat — sans mur de connexion.
Trois contraintes guident le design : éviter les binds « démo » sur 0.0.0.0 (le STCP pousse le chemin simple vers le loopback), réduire la prolifération des secrets à un auth.token frps et des secretKey par proxy rotatables au calendrier, et fusionner le bruit des sondes (passerelle verte / doctor rouge) en un seul état régional pour l’astreinte.
| Exigence | Mécanisme | Signal d’acceptation |
|---|---|---|
| Masquer la passerelle à Internet | Visiteur frp STCP + jeton frps | ss -ltn : OpenClaw uniquement sur 127.0.0.1 côté builder et visiteur |
| Authentifier avant tout TCP vers OpenClaw | auth.token frps + secretKey STCP |
Compteurs de rejet en cas de dérive de clé ; journaux OpenClaw inchangés |
| Isolation par région | Un proxy_name STCP par PoP (ex. openclaw-sin-gw) |
Un visiteur Tokyo ne compose pas Singapour par faute de frappe — échec sur le nom |
| Agrégat santé gateway + doctor | Worker de fusion joint les deux voies par région | Une alerte par incident régional, pas par endpoint |
Rôles, ports et chaîne passerelle / doctor
frps sur bastion Linux : bindPort = 7000, auth.method = "token", auth.token long ; dashboard éventuel sur 7500 derrière TLS. Pare-feu : 7000/tcp vers sous-réseaux opérateurs et egress builders uniquement. frpc builder (sortie vers 7000) enregistre openclaw-{region}-gw → 127.0.0.1:18080 et openclaw-{region}-doctor → 127.0.0.1:18081, chacun avec son secretKey.
Visiteurs frpc (poste opérateur ou worker de fusion) : sortie uniquement, bindAddr sur 127.0.0.1 — ports locaux 28080 / 28081. Un curl http://127.0.0.1:28080/healthz traverse visiteur → jeton frps → secret STCP → loopback builder. La passerelle sert l’inférence ; le doctor expose un JSON plus riche (files, version, Metal) pour détecter un blocage même si /healthz reste vert.
Étapes minimales reproductibles
Exécutez la séquence une fois par région ; remplacez {region} par vos tags d’inventaire (ex. sin, tyo, hkg, icn, lax).
- Étape 1 — Ancrer OpenClaw sur le loopback. Définissez
OPENCLAW_HOME=/var/lib/openclaw/{region}(ou l’équivalent macOS sous/usr/local/var) et démarrez avec--gateway-bind 127.0.0.1:18080 --doctor-bind 127.0.0.1:18081. Vérifiezcurl http://127.0.0.1:18080/healthzetcurl http://127.0.0.1:18081/doctordepuis localhost uniquement. - Étape 2 — Installer frps sur le bastion.
frps -c frps.tomlavecbindPort = 7000,auth.method = "token"et unauth.tokenaléatoire long. Restreignez 7000/tcp aux sous-réseaux opérateurs et builders (SG, UFW,nft). - Étape 3 — Câbler frpc sur chaque builder. Deux proxys STCP,
secretKeydistincts, pas deremotePort— le STCP refuse d’ouvrir un port public par conception. Lancez frpc en unité systemd ou launchd avec redémarrage sur échec et backoff exponentiel pour que les flaps ne poussent pas à assouplir le pare-feu. - Étape 4 — Câbler le côté visiteur. Deux visiteurs STCP sur le poste opérateur ou le worker de fusion, tous deux sur
127.0.0.1(28080 passerelle, 28081 doctor). LesecretKeydu visiteur doit correspondre au proxy. Validez avec uncurllocalhost avant d’ouvrir l’accès à l’équipe. - Étape 5 — Enchaîner passerelle et doctor dans un superviseur. Un petit worker appelle
127.0.0.1:28080/healthzpuis127.0.0.1:28081/doctor, fusionne en{region, gw_ms, doctor_ms, status, error_class}et pousse vers votre TSDB. Ne pagez que si les deux voies échouent dans le même créneau de cinq minutes ; escaladez « multirégion » seulement si deux régions se dégradent ensemble.
# frpc.toml — côté builder, deux proxys STCP vers le loopback
serverAddr = "bastion-sin.vpshalo.example"
serverPort = 7000
auth.method = "token"
auth.token = "<long-random-frps-token>"
[[proxies]]
name = "openclaw-sin-gw"
type = "stcp"
secretKey = "<sk-sin-gw>"
localIP = "127.0.0.1"
localPort = 18080
[[proxies]]
name = "openclaw-sin-doctor"
type = "stcp"
secretKey = "<sk-sin-doctor>"
localIP = "127.0.0.1"
localPort = 18081
# frpc.toml — côté visiteur, les deux voies sur 127.0.0.1 uniquement
[[visitors]]
name = "v-openclaw-sin-gw"
type = "stcp"
serverName = "openclaw-sin-gw"
secretKey = "<sk-sin-gw>"
bindAddr = "127.0.0.1"
bindPort = 28080
[[visitors]]
name = "v-openclaw-sin-doctor"
type = "stcp"
serverName = "openclaw-sin-doctor"
secretKey = "<sk-sin-doctor>"
bindAddr = "127.0.0.1"
bindPort = 28081
0.0.0.0. L’objectif est que le loopback reste du loopback.Trois phrases à coller dans le runbook
- Deux scalaires à faire tourner par région : un
auth.tokenfrps partagé par les builders, plus unsecretKeySTCP par proxy — bien moins de surface qu’une forêt d’entréesssh_config. - Les scans ne touchent jamais OpenClaw. Le STCP exige que le secret visiteur corresponde avant tout segment TCP ; les échecs incrémentent les compteurs de rejet frps, pas les journaux d’accès OpenClaw.
- Loopback des deux côtés : la posture préférée de l’auditeur (« tout le trafic reste sur localhost ») est aussi votre défaut — les exceptions sont rares, documentées et revues.
Guide de dépannage
Le visiteur ne se connecte pas. Vérifiez que 7000/tcp du bastion est joignable depuis l’IP visiteur et que le sous-réseau opérateur est autorisé. Les journaux frps montrent auth failed si le jeton ne correspond pas et visitor not allowed si le secret STCP diverge — ne faites tourner qu’une variable à la fois. Passerelle 200 mais doctor bloqué. Presque toujours un fil modèle incontrôlé sur le builder ; la voie doctor fait son métier. Redémarrez le worker OpenClaw, sans toucher à frp. STCP OK mais latence élevée. Quand la traversée NAT échoue, le STCP relaie via frps ; placez les builders sur un PoP vpshalo proche du bastion (voir la matrice RTT SCP/SFTP). Dérive de jeton après rotation. Le visiteur utilise encore l’ancien secretKey ; faites tourner proxy et visiteur dans la même fenêtre de maintenance et validez avec curl 127.0.0.1:28080/healthz avant de couper les alertes. Les sondes claquent ensemble. Si passerelle et doctor tombent à la même seconde, c’est le tunnel, pas OpenClaw — contrôlez la supervision de frps et des keepalives type ServerAliveInterval sur frpc.
auth.method, l’orthographe des options STCP et bindAddr des visiteurs contre votre build. Les versions OpenClaw diffèrent sur --gateway-bind et --doctor-bind — cet article fixe l’intention, pas un SLA éditeur. Le schéma complète plutôt qu’il ne remplace les guides SSH ou Tailscale liés plus haut.
Une fois les étapes scriptées, le périmètre devient volontairement ennuyeux : loopback dans chaque région vpshalo, tunnel frp STCP authentifié, aucun listener public, rotation des jetons au calendrier, et une seule alerte fusionnée par région au lieu d’une boîte de bruit de sondes. Provisionnez des builders Mac distant sur les PoP réellement mesurés ; capacité, miroirs de registre et visiteurs frp doivent bouger ensemble pour préserver ce mode d’accès multirégion à faible exposition.