authorgravatar for 92423096+nateEc@users.noreply.github.comYukun Shan <92423096+nateEc@users.noreply.github.com> 2026-08-04 21:34:23+08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-04 09:34:23-04:00
log37ae1abbe947f0e002d008276225e4af2248a969
tree4f283acc2f3765479766b60f383a82a407c4b4bb
parent82b76e2138db7fcf8f8c1613184dc94777b2196e
signature Signed by PGP key B5690EEEBB952194

fix(ssh): isolate managed tunnel processes (#4347)


2 files changed, 11 insertions(+), 0 deletions(-)

packages/ssh/src/tunnel.test.ts+5
...@@ -381,6 +381,11 @@ describe("ssh tunnel scripts", () => {...@@ -381,6 +381,11 @@ describe("ssh tunnel scripts", () => {
381381
382 const first = yield* manager.ensureEnvironment(target);382 const first = yield* manager.ensureEnvironment(target);
383 assert.equal(first.httpBaseUrl, "http://127.0.0.1:41773/");383 assert.equal(first.httpBaseUrl, "http://127.0.0.1:41773/");
384 const firstTunnelArgs = spawnedCommands.find((args) => args.includes("-N"));
385 assert.isDefined(firstTunnelArgs);
386 assert.include(firstTunnelArgs, "ControlMaster=no");
387 assert.include(firstTunnelArgs, "ControlPath=none");
388 assert.include(firstTunnelArgs, "ControlPersist=no");
384389
385 yield* manager.disconnectEnvironment(target);390 yield* manager.disconnectEnvironment(target);
386 assert.equal(tunnelKillCount, 1);391 assert.equal(tunnelKillCount, 1);
packages/ssh/src/tunnel.ts+6
...@@ -963,6 +963,12 @@ const startSshTunnel = Effect.fn("ssh/tunnel.startSshTunnel")(function* (input:...@@ -963,6 +963,12 @@ const startSshTunnel = Effect.fn("ssh/tunnel.startSshTunnel")(function* (input:
963 "-o",963 "-o",
964 "ExitOnForwardFailure=yes",964 "ExitOnForwardFailure=yes",
965 "-o",965 "-o",
966 "ControlMaster=no",
967 "-o",
968 "ControlPath=none",
969 "-o",
970 "ControlPersist=no",
971 "-o",
966 "ServerAliveInterval=15",972 "ServerAliveInterval=15",
967 "-o",973 "-o",
968 "ServerAliveCountMax=3",974 "ServerAliveCountMax=3",