Skip to content

Repository files navigation

MoltSSH

English | 中文

CI Release License: MIT

MoltSSH is a resumable OpenSSH ProxyCommand over WebSocket.

The current MVP uses WebSocket transport. Existing relay tools provide reachability; MoltSSH provides session resume, path probing, and path switching.

View Releases · Changelog · Report Bug · Request Feature

MoltSSH architecture: OpenSSH uses MoltSSH as ProxyCommand, the client resumes across WebSocket paths, and the server keeps a stable TCP connection to sshd.

Table of Contents

  1. About The Project
  2. Built With
  3. Getting Started
  4. Usage
  5. Troubleshooting
  6. Configuration
  7. Roadmap
  8. Contributing
  9. Security
  10. License
  11. Contact
  12. Acknowledgments

About The Project

MoltSSH keeps the server-side TCP connection to sshd stable while the client reconnects through the healthiest configured WebSocket path. This lets an OpenSSH session continue through client-side network churn, relay restarts, and path changes that preserve the MoltSSH server process.

Current capabilities:

  • OpenSSH ProxyCommand compatibility.
  • TOML based proxy, server, and probe commands.
  • WebSocket subprotocol moltssh.v1 with explicit binary frames.
  • Server-side TCP bridge to a single configured target such as 127.0.0.1:22.
  • In-memory resume state with session IDs, epochs, ACKs, FIN, offsets, and replay buffers.
  • Probe driven path selection with RTT, failure threshold, success threshold, and switch cooldown settings.
  • Parallel phased dialing, reusable probe connections, advisory last-known-good path startup, in-session heartbeat, and jittered reconnect backoff.
  • GitHub Actions CI, release binaries, issue templates, and Docker SSH smoke coverage.

See docs/mvp.md for the protocol plan and ADR 0001 for the transport decision.

(back to top)

Built With

(back to top)

Getting Started

Prerequisites

  • Go 1.26.5+
  • OpenSSH client
  • Docker for scripts/docker-ssh-smoke.sh

Installation

Download a release binary from GitHub Releases.

Release assets use this naming pattern:

moltssh_<version>_<os>_<arch>
moltssh_<version>_windows_amd64.exe
SHA256SUMS

Install the latest tagged version with Go:

go install github.com/jingyijun/moltssh/cmd/moltssh@latest

The binary is installed into GOBIN when it is set, otherwise into $(go env GOPATH)/bin. Make sure that directory is on PATH. @latest follows the newest semantic-version tag, which can lag behind features listed under Unreleased.

Build from source:

git clone https://github.com/JingYiJun/MoltSSH.git
cd MoltSSH
go build -o moltssh ./cmd/moltssh

Verify any installation:

moltssh --help

For source builds and tagged releases that include the version command, inspect build provenance with:

moltssh version

Run local checks:

go test ./...
go test -race ./...
scripts/docker-ssh-smoke.sh

For a writable Go cache path:

GOCACHE=/tmp/moltssh-go-build go test ./...

(back to top)

Usage

Start a MoltSSH server beside the target sshd:

moltssh server --config /etc/moltssh/example.toml

Probe configured client paths:

moltssh probe --config ~/.config/moltssh/example.toml

Use MoltSSH as an OpenSSH ProxyCommand:

Host example-host
  HostName example-host
  User example-user
  ProxyCommand moltssh proxy --config ~/.config/moltssh/example.toml

Open an SSH session:

ssh example-host

Inspect command-specific help:

moltssh help proxy
moltssh help server
moltssh help probe

(back to top)

Troubleshooting

Start with the probe command whenever a proxy path cannot connect:

moltssh probe --config ~/.config/moltssh/example.toml

For moltssh probe, the failed_phase field narrows the failure to dns, tcp, tls, websocket_upgrade, or probe. Common checks:

  • dns: verify the endpoint hostname and resolver.
  • tcp: verify the port, relay process, firewall, and route.
  • tls: verify the certificate name, trust chain, and reverse-proxy TLS setup.
  • websocket_upgrade: verify server.http_path, reverse-proxy WebSocket forwarding, and the moltssh.v1 subprotocol.
  • probe: the WebSocket connected, but the MoltSSH ping/pong check failed; verify client/server compatibility and reverse-proxy frame forwarding.

Proxy-session logs can instead report failed_phase=moltssh_hello or unknown session. Verify client/server compatibility and confirm that the MoltSSH server process did not restart.

Run moltssh help COMMAND for required flags and command-specific guidance. Errors include a next diagnostic action where one is available.

Warning

MoltSSH has no application-layer authentication. Do not expose the raw moltssh server WebSocket listener to the public internet. Bind it to loopback or place it behind a protected private access layer or authenticated reverse proxy. See SECURITY.md.

(back to top)

Configuration

MoltSSH uses one TOML schema for client and server commands:

schema_version = 1
name = "example-host"

[server]
listen = "127.0.0.1:8080"
http_path = "/moltssh"
connect = "127.0.0.1:22"

[resume]
timeout = "60s"
buffer_bytes = 33554432

[probe]
interval = "3s"
timeout = "2s"
switch_cooldown = "10s"
active_failure_threshold = 2
candidate_success_threshold = 3
better_rtt_min_delta = "30ms"
better_rtt_ratio = 0.25

[[paths]]
name = "direct"
transport = "ws"
endpoint = "ws://127.0.0.1:8080/moltssh"
priority = 100
enabled = true

Deployment guidance:

  • Use ws:// for trusted localhost, LAN, and already protected tunnel paths.
  • Use wss:// through a reverse proxy, relay, gateway, or local tunnel endpoint that terminates TLS.
  • Place the MoltSSH server behind a protected access layer for public relay paths.
  • Keep private keys, credentials, certificates, tokens, and machine-specific host details in local deployment files.

Path performance and runtime state:

  • On a cold start, enabled paths are probed concurrently, with at most eight probes in flight. A successful probe WebSocket is promoted directly by sending hello; MoltSSH does not redial the selected path.
  • After an accepted session, proxy stores only the accepted path name in an advisory last-known-good cache. The cache is $XDG_CACHE_HOME/moltssh/path-state/<config-hash>.json when XDG_CACHE_HOME is set, otherwise it is under the operating system user cache directory. The hash identifies the canonical config-file path.
  • A warm start dials the saved path immediately while probing alternatives in the background. Missing, stale, disabled, malformed, or unwritable cache state never prevents connection fallback. Removing this cache is safe.
  • Cache directories use mode 0700, files use 0600, and the JSON contains only version and path. Sessions, epochs, offsets, payload bytes, endpoints, and credentials remain memory-only and are never cached.
  • The active session uses application ping/pong heartbeat on its existing WebSocket. Only inactive paths get new probe connections. A promoted inactive probe keeps the same WebSocket for the resume hello.
  • Reconnect uses capped exponential backoff with full jitter: a 200ms base, a 5s cap, and delays clipped to the remaining resume.timeout budget.
  • Formal attempts emit one event=proxy_dial record with dns, tcp, tls, websocket_upgrade, moltssh_hello, probe_rtt, and total. Endpoints and secret query values are not logged. These optimizations do not change the moltssh.v1 wire protocol or add TOML fields.

(back to top)

Roadmap

  • WebSocket transport.
  • TOML config validation.
  • OpenSSH ProxyCommand bridge.
  • Session resume with replay buffers.
  • Probe command and path switching.
  • Docker SSH smoke test.
  • GitHub CI and release binaries.
  • More protocol conformance tests.
  • Operational examples for common relay tools.
  • QUIC exploration after WebSocket resume and path switching mature.

See the open issues for active work items.

(back to top)

Contributing

Contributions are welcome through focused issues and pull requests. Read CONTRIBUTING.md for the development workflow and CODE_OF_CONDUCT.md before participating.

(back to top)

Security

Read SECURITY.md before deploying MoltSSH or reporting a vulnerability. Security-sensitive reports should not be filed as public issues.

(back to top)

License

Distributed under the MIT License. See LICENSE for more information.

(back to top)

Contact

Project Link: https://github.com/JingYiJun/MoltSSH

(back to top)

Acknowledgments

(back to top)

About

Resumable OpenSSH ProxyCommand over WebSocket

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages