Repository navigation
Description
Describe the Bug
A private AI Gateway resource (site resource with mode: inference) is unreachable from the Linux client. The client sets up the exit-node peer and the alias resolves, but TCP to the alias times out. Two independent causes:
1. No route to the exit node on Linux. connectExitNode (olm/exitnode.go) adds the exit-node tunnel IP as a /32 secondary address on the interface and then calls network.AddRouteForServerIPWithSource(serverIP, interfaceName, tunnelIP). In newt network/route.go (v1.19.0, v1.19.1 and main) that function only adds an OS route on darwin; the linux and windows branches are commented out:
if runtime.GOOS == "darwin" { // macos requires routes for each peer to be added but this messes with other platforms
return DarwinAddRouteWithSource(serverIP, "", interfaceName, sourceIP)
}
// else if runtime.GOOS == "windows" { ... } else if runtime.GOOS == "linux" {
// return LinuxAddRoute(serverIP, "", interfaceName)
// }
return nilWith only a /32 address there is no connected route, so traffic to the exit node's server IP leaves via the default gateway instead of the WireGuard interface:
$ ip -br addr show pangolin
pangolin UNKNOWN 100.90.128.7/20 100.89.128.44/32 ...
$ ip route get 100.89.128.1
100.89.128.1 via <lan-gateway> dev eth0 src <lan-ip>
2. No relay fallback for the exit-node peer. Pangolin's olm/sync message (server server/routers/olm/sync.ts, 1.25.3) always sends endpoint: \${clientExitNode.endpoint}:${clientExitNode.listenPort}`, i.e. :51820. connectExitNode` only uses the relay port (21820) when the endpoint has no port, so that branch is never taken and there is no switch to the relay later. On networks that drop UDP 51820 (our corporate network does; all site peers work there via the relay), the exit-node peer can never handshake, even with cause 1 fixed.
Client log (relevant lines):
INFO: Started exit node connectivity monitor for 100.89.128.1 (via 100.89.128.44)
INFO: Connected to exit node at <server-ip>:51820
INFO: Already connected to exit node <pubkey>, ignoring duplicate connect message
pangolin status:
SITE ENDPOINT STATUS LAST SEEN CONNECTION
Pangolin Server 100.89.128.1 Disconnected 1s ago Direct
site-a <ip>:51963 Connected 31s ago Relay
site-b <ip>:8269 Connected 29s ago Relay
exitnode.go is identical in olm v1.10.1, v1.10.2 and main, so pangolin-cli 0.19.1 behaves the same.
Environment
- OS Type & Version: Arch Linux, kernel 7.2.9 (workstation, pangolin-cli as a systemd service,
pangolin up client --attach) - Pangolin Version: 1.25.3 (self-hosted)
- Edition (Community or Enterprise): Enterprise image (
fosrl/pangolin:ee-1.25.3) - Gerbil Version: 1.5.2
- Traefik Version: v3.7.15
- Newt Version: 1.18.1 (site)
- Client Version: pangolin-cli 0.19.0 (olm v1.10.1, newt v1.19.0); code checked unchanged in 0.19.1 (olm v1.10.2, newt v1.19.1)
To Reproduce
- Create a Custom AI provider (Anthropic Messages, Site Targets routing) and a private resource
mode: inferencewith a full domain, granted to a user. - Connect that user with pangolin-cli on Linux.
curl -sS https://<gateway-domain>/v1/models -H 'x-api-key: none'→ TCP connect timeout.ip route get <exit node server IP>→ not via the Pangolin interface;pangolin statusshows "Pangolin Server … Disconnected".- (Cause 2) Repeat on a network that blocks UDP 51820 but allows 21820: sites connect via Relay, the exit-node peer stays disconnected.
Not tested: adding the route manually (ip route add <server-ip>/32 dev pangolin src <tunnel-ip>) on a network without the UDP block.
AI Disclosure
Yes. The investigation (reading the olm, newt, gerbil and pangolin source and the live client state) and this text were done with an AI coding agent (Claude) working on my setup; I reviewed the findings and the report. The command outputs are from my workstation, with addresses anonymised.
Expected Behavior
- On Linux (and Windows), the client adds a route for the exit node's server IP via the tunnel interface (source = the exit-node tunnel IP), as on macOS, so private AI gateway resources are reachable.
- The exit-node peer falls back to the relay (21820) like site peers do when the direct WireGuard port is blocked, so private AI gateways work wherever the client itself works.
Activity
AstralDestiny commentedon Oct 28, 2026
Olm doesn't have exit node right now, Are you using Fosrl/cli for this?
For your curl can you do a nslookup to make sure it returns the proper value?