Summary
devsy-org/ssh does not require a rewrite. With v1.2.7 as the corrected functional baseline, the remaining work is to harden protocol compatibility, channel/connection lifecycle invariants, race coverage, and CI so future changes do not regress OpenSSH/VS Code Remote-SSH behavior.
This issue tracks the remaining work as one implementation PR with multiple logical commits.
Goals
- Add real OpenSSH compatibility coverage for keepalive and dynamic forwarding.
- Validate the same integration suite in GitLab Runner CI in addition to GitHub Actions.
- Clarify keepalive/peer-activity semantics so comments match what the package can actually observe.
- Add race/stress tests around channel tracking, keepalive selection, and connection teardown.
- Add deterministic tests for connection callbacks and
Server.Close / Server.Shutdown behavior.
- Keep the implementation based on
golang.org/x/crypto/ssh; do not rewrite the SSH protocol layer.
Work plan
A. Keepalive semantic cleanup
B. Real OpenSSH interoperability tests
C. Channel lifecycle and race hardening
D. Connection lifecycle callbacks
E. Server shutdown hardening
F. CI and runner validation
GitHub Actions
GitLab Runner
Suggested integration command:
go test -tags=openssh_integration ./...
Suggested race command:
Required invariants
Non-goals
- rewriting the SSH library;
- replacing
golang.org/x/crypto/ssh;
- implementing transparent reconnect;
- moving Devsy workspace/provider concerns into this library;
- packet-level inspection solely to imitate OpenSSH internals.
Delivery
Implement this issue as one pull request with multiple logical commits. Suggested commit sequence:
refactor(keepalive): clarify peer activity and liveness semantics
test: add OpenSSH interoperability coverage
test(server): harden channel lifecycle and keepalive races
test(server): harden connection and shutdown lifecycle
ci: run OpenSSH integration and race tests in GitHub and GitLab
docs: document keepalive and lifecycle callback contracts
Commit-signing CI can be ignored during implementation; signing will be handled separately before merge.
Summary
devsy-org/sshdoes not require a rewrite. Withv1.2.7as the corrected functional baseline, the remaining work is to harden protocol compatibility, channel/connection lifecycle invariants, race coverage, and CI so future changes do not regress OpenSSH/VS Code Remote-SSH behavior.This issue tracks the remaining work as one implementation PR with multiple logical commits.
Goals
Server.Close/Server.Shutdownbehavior.golang.org/x/crypto/ssh; do not rewrite the SSH protocol layer.Work plan
A. Keepalive semantic cleanup
notePeerActivitydocumentation so it no longer claims packet-level visibility.B. Real OpenSSH interoperability tests
ClientAliveInterval/ClientAliveCountMax.ssh -T -N -D <port>dynamic-forwarding regression test.C. Channel lifecycle and race hardening
openChannelSetadd/remove/any semantics and concurrent access.trackingNewChannelcancellation/backpressure behavior.D. Connection lifecycle callbacks
ConnectionFailedCallback == 0,ConnectionCompleteCallback == 1.ConnectionFailedCallback == 1,ConnectionCompleteCallback == 0.ConnectionClosingCallbackordering and semantics.E. Server shutdown hardening
Server.Close()with active connections/channels.Server.Shutdown()preserves existing connections while rejecting new ones.Close()/Shutdown()and verify goroutines exit cleanly.F. CI and runner validation
GitHub Actions
go test ./...job.go test -race ./...gate.openssh_integrationbuild tag.GitLab Runner
.gitlab-ci.ymlso a GitLab runner executes the OpenSSH integration suite.openssh-clientavailable or installs it explicitly.Suggested integration command:
go test -tags=openssh_integration ./...Suggested race command:
go test -race ./...Required invariants
Server.Close()terminates active transports.Server.Shutdown()preserves active transports until they close or the caller context expires.Non-goals
golang.org/x/crypto/ssh;Delivery
Implement this issue as one pull request with multiple logical commits. Suggested commit sequence:
refactor(keepalive): clarify peer activity and liveness semanticstest: add OpenSSH interoperability coveragetest(server): harden channel lifecycle and keepalive racestest(server): harden connection and shutdown lifecycleci: run OpenSSH integration and race tests in GitHub and GitLabdocs: document keepalive and lifecycle callback contractsCommit-signing CI can be ignored during implementation; signing will be handled separately before merge.