Skip to content

fix: follow a ProxyJump declared by a jump host - #338

Open
NatLee wants to merge 2 commits into
jeanp413:masterfrom
NatLee:fix/nested-proxy-jump
Open

fix: follow a ProxyJump declared by a jump host#338
NatLee wants to merge 2 commits into
jeanp413:masterfrom
NatLee:fix/nested-proxy-jump

Conversation

@NatLee

@NatLee NatLee commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Closes #109. Stacked on #337 — both touch the ProxyJump chain, so this one's diff will shrink once that lands.

The bug

Only the target's ProxyJump was read:

const proxyJumps = sshHostConfig['ProxyJump'].split(',')...

A jump host that declares a ProxyJump of its own was therefore contacted directly. When that host is only reachable through its own proxy, the connection fails.

That's the rest of #109. With its config, reaching te needs first -> second -> te, but only second was in the chain and it was dialed directly, which is why first and second connect on their own while te doesn't. (#337 covers the other half of that report — the target's Port leaking into the first hop.)

The chain is now expanded depth first, so the hops a jump host depends on are connected to before it, matching how ssh re-reads the config for each hop it opens.

A config that jumps back to a host already being resolved is reported rather than recursed into, and a chain longer than 10 hops is refused.

Tests

  • test/resolve-proxy-jumps.test.ts — 10 unit tests: ordering, blank entries, one and several levels of nesting, per-entry expansion of a list, the config carried for each hop, user@host:port in the value, self loop, two host loop, over long chain
  • test/nested-proxy-jump.test.ts — e2e over three containers. Only the first is published; the second and the target are reachable solely inside the network, so the whole chain has to be walked. It fails on master with getaddrinfo ENOTFOUND for the middle hop.

Full suite passes locally (23 tests).

NatLee added 2 commits August 25, 2026 18:13
The port of a jump host was computed in two places with different
fallbacks: connecting to the hop fell back to the target's port, while
the forwardOut reaching the next hop fell back to 22. A jump host does
not inherit the target's Port, so a target declared on a non-default
port had its first hop dialed on that port.

Use one helper for both, falling back to 22 like ssh does, and cover the
ProxyJump path with unit tests for the resolution order plus a two
container e2e where the target is only reachable through the hop.
Only the target's ProxyJump was read, so a jump host that declares one of
its own was contacted directly. When that host is only reachable through
its own proxy the connection fails, which is what jeanp413#109 reports.

Expand the chain depth first, so the hops a jump host depends on are
connected to before it, and report a config that jumps back to a host
already being resolved instead of recursing forever.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nested proxyjump possibly broken

1 participant