Hermes Agent con Tailscale non si connette: le soluzioni
Hermes Desktop non raggiunge il tuo gateway remoto via Tailscale? Quattro cause coprono quasi tutti i casi, dal bind su localhost al regex CORS.
La Tailnet È Su e Hermes Continua a Non Rispondere
Hai installato Tailscale sul VPS, sei entrato nella tailnet dal laptop e hai confermato che entrambi i lati si pingano sugli indirizzi 100.x.x.x. hermes serve gira sull'host con la porta aperta e l'app Hermes Desktop sul laptop resta in loop su "Could not connect to Hermes gateway." Niente nel log del gateway sembra arrabbiato. Niente in Tailscale è in rosso.
Quel fallimento silenzioso è quasi sempre una di quattro cause, e tre falliscono in silenzio per design. Questo post scorre ognuna, come confermare quale sia la tua e il fix esatto. Parti dall'alto: la prima causa acchiappa la maggior parte dei setup remoti appena avviati, e ogni causa sotto assume che quelle sopra siano state escluse.
Causa 1: hermes serve È Bindato su 127.0.0.1
hermes serve fa il bind su 127.0.0.1 di default. È il default giusto per un setup solo-laptop e quello sbagliato per qualsiasi cosa tu voglia raggiungere via tailnet. Un processo bindato sul loopback risponde solo alle richieste che partono dalla stessa macchina, e un peer Tailscale non è la stessa macchina. La porta è aperta, il firewall va bene, il tunnel è su, e il socket rifiuta la connessione.
Sintomo: dal laptop, curl -v http://<hermes-vps>:8642/api/health restituisce Connection refused o resta appeso fino al timeout. Da una sessione SSH sul VPS, lo stesso curl http://127.0.0.1:8642/api/health risponde subito. Se il loopback risponde e la tailnet no, questa è la tua causa.
Il fix è bindare hermes serve all'IP Tailscale dell'host esplicitamente:
TAILSCALE_IP=$(tailscale ip -4)
hermes serve --host "$TAILSCALE_IP" --port 8642
Bindare sull'interfaccia della tailnet invece che su 0.0.0.0 è la forma che vuoi. 0.0.0.0 funziona anche e molte guide lo consigliano, ma espone il socket su ogni interfaccia della macchina, comprese quelle accidentalmente pubbliche, e rimette tutta la storia dell'autenticazione sul livello applicativo. Bindare all'IP Tailscale è difesa in profondità: il socket è raggiungibile solo da dentro la tailnet.
Rendi la modifica permanente mettendo lo stesso flag nella unit systemd o nel command del docker-compose.yml. Se giri in Docker, pubblica la porta direttamente sull'IP Tailscale con -p ${TAILSCALE_IP}:8642:8642 invece del -p 8642:8642 di default (che pubblica su ogni interfaccia dell'host).
Per l'installazione Tailscale iniziale completa, la guida all'accesso remoto sicuro con Hermes Agent + Tailscale scorre la ricetta da capo a fondo.
Causa 2: Il Regex CORS del Dashboard Rifiuta la tua Origin di Tailscale
Bindi il gateway all'IP Tailscale, l'API risponde su /api/health e il dashboard web carica l'HTML da http://<hermes-vps>:8642/. Poi ogni chiamata API del dashboard fallisce con un errore CORS nella console del browser: has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Cosa succede: vecchie build di Hermes portavano un allow_origin_regex hardcoded nel dashboard che matchava solo ^https?://(localhost|127\.0\.0\.1)(:\d+)?$. Il regex era sicuro sul laptop e silenziosamente inutile ovunque altro. Un hostname Tailscale come http://hermes-vps:8642 o un IP come http://100.64.1.5:8642 non matcha mai, quindi la preflight fallisce e il browser scarta la fetch. La feature request che segue il fix ha lo storico completo.
Il fix è una variabile d'ambiente:
export HERMES_DASHBOARD_CORS_ORIGINS="http://hermes-vps:8642,http://100.64.1.5:8642"
hermes serve --host "$TAILSCALE_IP" --port 8642
Elenca ogni origin da cui carichi davvero il dashboard: il nome MagicDNS, l'IP grezzo di Tailscale e ogni alias di Funnel o serve che hai aggiunto. Sono supportati i wildcard (http://*.tail1a2b3.ts.net:8642) se preferisci matchare l'intero nome della tailnet invece di elencare ogni dispositivo.
Due manopole affini su cui si inciampa:
HERMES_DASHBOARD_HOSTsovrascrive l'indirizzo che il dashboard dichiara al browser. Se l'hai lasciato sulocalhost, il dashboard rende link che riportano ahttp://localhost:8642/api/...e il browser cerca di colpire il proprio loopback invece della tailnet. Impostalo sul tuo hostname o IP Tailscale.- L'app Hermes Desktop porta anche lei una Origin. Se usi il desktop pacchettizzato invece del dashboard nel browser, il suo renderer manda
Origin: null(Electron carica viafile://). Le build vecchie lo accettavano solo se il server era bindato al loopback, che è l'esclusività mutuale descritta nell'issue #38412. Le build recenti accettanonullse è presente inHERMES_DASHBOARD_CORS_ORIGINSinsieme alle origin reali: aggiungi la stringa letteralenullalla lista per permettere il client desktop.
Riavvia hermes serve dopo ogni modifica a queste env var. I valori si leggono all'avvio, non per richiesta.
Causa 3: Il Tunnel Tailscale Cade in DERP o Non Si Alza
Se il dashboard alla fine carica ma ogni messaggio impiega diversi secondi per partire e le note vocali balbettano, il tunnel è su ma lento. Tailscale sta relayando ogni pacchetto attraverso un server DERP fino al tuo VPS, e il round-trip è dominato da quel salto extra invece che dal modello. Se non passa proprio niente, probabilmente il tunnel non è mai salito.
Conferma quale dei due è il tuo con tailscale status. Un peer in salute mostra direct <ip>:<port> sulla sua riga. Un peer relayato via DERP mostra relay "<region>". Se il peer è assente o marcato offline, il tunnel non si è mai stabilito.
Il fix cambia in ogni caso:
- Bloccato in DERP. Apri UDP
41641in uscita sia sul firewall dell'host VPS sia su quello della rete client. È la porta che Tailscale usa per i tunnel WireGuard diretti; se un lato blocca l'uscita UDP, entrambi i peer ricadono in DERP anche se la coppia è autenticata. Conferma consudo ufw allow 41641/udpsul VPS e ripingando il peer dopotailscale down && tailscale up. Reti aziendali e Wi-Fi d'albergo sono i soliti sospetti a bloccare l'uscita UDP. Se una connessione diretta resta impossibile, DERP regge sul testo ma lo senti sulla voce. - Peer marcato offline o tunnel mai salito. La chiave del nodo è scaduta. Tailscale ruota le chiavi ogni 180 giorni di default, e un dispositivo rimasto offline durante la finestra di rotazione torna come "offline" nella console admin finché non riautentichi. Sistemi con
tailscale up --force-reauthdal lato interessato e rifai login via browser. Per evitare del tutto la rotazione sulle installazioni VPS lato server, tagga il nodo (tailscale up --advertise-tags=tag:server) e disabilita la scadenza chiave per quel tag nella console admin di Tailscale: i nodi taggati saltano il controllo dei 180 giorni di default. - Il risparmio energetico ha ucciso il client sul laptop. macOS e Windows lasciano al SO mettere in pausa i servizi in background nelle modalità aggressive, e la app da menubar di Tailscale può disconnettersi da sola in silenzio. Se la tailnet si è spenta subito dopo aver staccato la spina, guarda l'icona nel tray prima di diagnosticare altro.
Causa 4: Punti a una URL Localhost da un Client Remoto
L'ultimo caso silenzioso è quello in cui ogni strato funziona e il client sta facendo la domanda sbagliata. Se hai configurato la Remote Gateway URL di Hermes Desktop come http://localhost:8642 o http://127.0.0.1:8642, l'app cerca di raggiungere la propria interfaccia di loopback invece di attraversare la tailnet, e nessun fix lato server aiuterà.
Sintomo: sul laptop, l'app desktop mostra "Could not connect." Dallo stesso laptop, curl http://<hermes-vps>:8642/api/health risponde in salute.
Il fix è un'unica impostazione. In Hermes Desktop, apri Settings poi Connection e imposta la Remote Gateway URL su una tra:
http://<magic-dns-name>:8642- preferito, sopravvive ai cambi di IP Tailscale.http://<tailscale-ip>:8642- l'indirizzo grezzo100.x.x.x. Abbastanza stabile per un setup fisso.
Il nome MagicDNS è quello che tailscale status mostra nella prima colonna per la riga del VPS. Se non hai mai abilitato MagicDNS, fallo nella console admin sotto DNS: è un solo toggle e ti risparmia ogni sessione di debug per cambio IP per tutta la vita della tailnet.
Già che sei in Settings, controlla il campo credenziali. Se il gateway sta dietro a un token (HERMES_AUTH_TOKEN), il client ha bisogno dello stesso token, e uno vecchio produce un 4403 sul WebSocket che sembra molto un fallimento di connessione. L'issue del WebSocket 4403 ha più dettagli su quel particolare modo di fallire.
Ordine Diagnostico che Fa Risparmiare Tempo
Quando la tailnet è su e Hermes non risponde, segui le cause in quest'ordine invece di ricostruire il setup Tailscale:
- hermes serve è bindato sul loopback?
curl http://<tailscale-ip>:8642/api/healthdal client risponde in un secondo. Il tasso di successo più alto sui setup remoti appena avviati. - Il regex CORS del dashboard rifiuta la tua origin? Apri le devtools del browser sul dashboard e cerca una voce CORS in rosso nella scheda network. Se c'è, imposta
HERMES_DASHBOARD_CORS_ORIGINSe riavvia. - Il tunnel è diretto o relayato?
tailscale statusmostradirectorelayper peer.Offlinesignifica che la chiave del nodo è scaduta e serve--force-reauth. - Il client chiede localhost? Apri le impostazioni di connessione dell'app desktop e conferma che la Remote Gateway URL punti al hostname della tailnet, non a
localhost.
Per la ricetta Docker sottostante sul VPS, vedi la guida Docker di Hermes Agent. Se preferisci saltare del tutto la mesh, self-hosting vs Hermes Agent gestito copre i compromessi.
Quando Preferisci Non Gestire una Mesh
Tailscale è la forma giusta per un Hermes self-hosted quando vuoi tenere la macchina sul tuo VPS e raggiungerla da qualsiasi posto. È anche un sistema in più da tenere vivo: una finestra di rotazione chiavi, una env var CORS, una regola di firewall per UDP 41641 e un'impostazione client che deve combaciare con il nome della tailnet del giorno. Se la tua lettura è che un assistente IA personale non dovrebbe richiedere una VPN mesh e una sessione di debug nella console del browser per risponderti ciao, inizia con Hermify. Hermify gestisce un Hermes Agent su Telegram con la stessa memoria e le stesse skill, attivo in circa un minuto, senza porte da aprire né tailnet da mantenere.
Fonti
- Hermes Agent Issue #38061: Can't connect to Remote Gateway via Tailscale for Hermes Desktop
- Hermes Agent Issue #10567: Add --host and CORS config for hermes dashboard to enable Tailscale/VPN access
- Hermes Agent Issue #34390: dashboard --allowed-hosts flag for reverse-proxy and Tailscale access
- Hermes Agent Issue #38412: Desktop Remote gateway can't connect over WebSocket
- Tailscale: firewall ports and UDP 41641
- Tailscale: key expiry and re-authentication
- Securely Connecting a Remote Hermes Agent to Your Local Desktop App via Tailscale (Medium)
Avvia il tuo Hermes Agent
Porta la tua chiave API, collega Telegram e ottieni un agente IA che migliora da solo, online in 60 secondi.
Inizia ora