Skip to content

Commit 381784e

Browse files
committed
fix(core): swap bind-only 0.0.0.0 SSH gateway host for cluster URL host
CLI's resolve_ssh_gateway treated 0.0.0.0 as a loopback "keep as-is" when the cluster URL was also loopback, so the SSH proxy connected to 0.0.0.0:port. The unspecified address is never a valid connect target and is not present in any TLS cert SAN, which produced BadCertificate TLS handshake failures during `openshell sandbox create -- ...` in docker/podman e2e (e.g. bypass_detection). Resolution: when the server returns 0.0.0.0 or :: as the gateway host and both endpoints are loopback, fall back to the cluster URL's host (which the CLI is already using to reach the gateway, so it must resolve and match the cert).
1 parent 2e1430c commit 381784e

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

‎crates/openshell-core/src/forward.rs‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,13 @@ pub fn resolve_ssh_gateway(
462462
// Remote cluster: use the remote host but keep the cluster URL port.
463463
return (host.to_string(), cluster_port);
464464
}
465-
// Local cluster: both loopback — use cluster URL's port (Docker-mapped).
465+
// Both endpoints loopback. The unspecified addresses (0.0.0.0 / ::)
466+
// are bind-only — they aren't valid connect targets and aren't in TLS
467+
// cert SANs, so fall back to the cluster URL's host (which the CLI
468+
// is already using to reach the gateway).
469+
if gateway_host == "0.0.0.0" || gateway_host == "::" {
470+
return (host.to_string(), cluster_port);
471+
}
466472
return (gateway_host.to_string(), cluster_port);
467473
}
468474

@@ -693,6 +699,16 @@ mod tests {
693699
assert_eq!(port, 8080);
694700
}
695701

702+
#[test]
703+
fn resolve_ssh_gateway_swaps_zeros_for_loopback_cluster_host() {
704+
// The gateway binds 0.0.0.0 but advertises that bind address via the
705+
// SSH session response. 0.0.0.0 is not a valid connect target and is
706+
// not in any TLS cert SAN; fall through to the cluster URL's host.
707+
let (host, port) = resolve_ssh_gateway("0.0.0.0", 8080, "https://127.0.0.1:9000");
708+
assert_eq!(host, "127.0.0.1");
709+
assert_eq!(port, 9000);
710+
}
711+
696712
#[test]
697713
fn resolve_ssh_gateway_handles_invalid_cluster_url() {
698714
let (host, port) = resolve_ssh_gateway("127.0.0.1", 8080, "not-a-url");

0 commit comments

Comments
 (0)