8000 Private AI Gateway unreachable on Linux: no route to the exit node, and no relay fallback for the exit-node peer · Issue #178 · fosrl/olm · GitHub
[go: up one dir, main page]

Skip to content

Private AI Gateway unreachable on Linux: no route to the exit node, and no relay fallback for the exit-node peer #178

Open

Description

@andimattes

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 nil

With 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

  1. Create a Custom AI provider (Anthropic Messages, Site Targets routing) and a private resource mode: inference with a full domain, granted to a user.
  2. Connect that user with pangolin-cli on Linux.
  3. curl -sS https://<gateway-domain>/v1/models -H 'x-api-key: none' → TCP connect timeout.
  4. ip route get <exit node server IP> → not via the Pangolin interface; pangolin status shows "Pangolin Server … Disconnected".
  5. (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

  1. AstralDestiny commented on Oct 28, 2026

    @AstralDestiny

    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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0