Skip to content

Repository files navigation

FerNomade icon

FerNomade

/fɛʁ.nɔ.mad/ — from French fer (“iron”) and nomade (“nomadic”).

A pure-Rust Mosh client for stock mosh-server.

Rust 1.85+ Apache-2.0 macOS, Linux, Windows mosh-server 1.4.0

English · 简体中文

FerNomade is an independent, pure-Rust Mosh client. It speaks the standard Mosh wire protocol directly to an unmodified mosh-server, including AES-128-OCB3 authenticated datagrams, state synchronization, fragmentation, acknowledgements, roaming, and terminal paint instructions. It does not contain an SSH client or a Mosh server.

It is designed to be useful in two places:

  • as a standalone network client launched after an SSH bootstrap;
  • as an embeddable runtime inside another terminal or host application.

Project status: the protocol path interoperates with the unmodified Debian mosh-server 1.4.0 package. The API is still pre-release and compatibility claims are deliberately limited to exact versions tested in the lab.

Mosh compatibility

FerNomade occupies the same network-client position as the conventional mosh-client executable. SSH is used only to start the remote server and obtain the MOSH CONNECT port and session key; FerNomade then runs the Mosh session over authenticated UDP.

SSH or host application
        │  MOSH CONNECT <port> <key>
        ▼
FerNomade / mosh-client
        │  Mosh protocol over authenticated UDP
        ▼
stock mosh-server 1.4.x

The current compatibility target is the standard Mosh 1.4.x protocol family. Automated black-box interoperability is presently pinned to the unmodified Debian mosh-server 1.4.0 package; other 1.4.x releases remain compatibility targets until individually recorded in the lab.

Release archives include both fernomade and a mosh-client-named copy for SSH bootstrap tools and terminal applications that expect that executable name. The reusable runtime can also be embedded directly into applications such as terminal emulators.

Why FerNomade?

Remote shells tend to feel worst exactly when they matter most: on mobile networks, unstable Wi-Fi, VPN transitions, and machines waking from sleep. FerNomade synchronizes terminal state over authenticated UDP instead of treating the session as one fragile byte stream.

  • Roaming: continue after the client address or UDP source port changes.
  • Loss recovery: retransmit logical state without reusing packet nonces.
  • Fast feedback: predict only safe printable input and roll it back against the authoritative server screen.
  • Native integration: embed the protocol runtime without giving it control of SSH, sockets, clocks, or credentials.
  • Portable Rust: no bundled C or C++ protocol runtime.

Quick start

FerNomade starts after a standard server has supplied a UDP port and ephemeral key. An SSH command, terminal manager, or another host application can perform that bootstrap.

$ cargo build --release --package fernomade-client
$ MOSH_KEY='SESSION_KEY' ./target/release/fernomade SERVER_IP UDP_PORT

For example, a bootstrap typically obtains a line shaped like:

MOSH CONNECT 60001 SESSION_KEY

Pass the port and key directly to FerNomade without writing the key to disk or placing it in command-line arguments.

Local escape

Keys Action
Ctrl-^ . End the local session
Ctrl-^ ^ Send a literal Ctrl-^
Ctrl-^ Ctrl-Z Suspend locally on Unix and restore after resume
Ctrl-^ ? Show local command help

Set MOSH_ESCAPE_KEY to one literal ASCII character to choose another local command prefix. Printable prefixes follow the conventional newline-prefix behavior; control-character prefixes are recognized directly.

FerNomade uses the local alternate screen by default so the original terminal contents return after exit. Set MOSH_NO_TERM_INIT=1 to keep the current screen. If the operating system cannot report the viewport, positive COLUMNS and LINES environment variables are used as a fallback.

Environment Effect
MOSH_KEY Required 128-bit session key from MOSH CONNECT
MOSH_ESCAPE_KEY One literal ASCII local-command prefix
MOSH_PREDICTION_DISPLAY adaptive, always, or never
MOSH_PREDICTION_OVERWRITE=yes Overwrite instead of insert predicted cells
MOSH_TITLE_NOPREFIX Disable the default [mosh] remote-title prefix
MOSH_NO_TERM_INIT=1 Skip local alternate-screen initialization

What works

  • AES-128 OCB3 authenticated datagrams
  • Bounded packet replay window and fragment reassembly
  • Acknowledgements, retransmission backoff, heartbeat, and liveness tracking
  • Stale-state suppression and recoverable indefinite network interruption
  • IPv4 and IPv6 endpoints
  • Client UDP rebinding and suspend/resume recovery
  • Bounded local, peer, and simultaneous SSP shutdown handshakes
  • UTF-8 terminal output and authoritative VT screen tracking
  • Keyboard, function keys, mouse, focus, bracketed paste, and resize
  • Conservative local prediction with line-local insert rollback and an authoritative overwrite fallback
  • Terminal restoration after exit, error, panic unwinding, and supported signals
  • English and Simplified Chinese command-line diagnostics
  • Native source checks for macOS, Linux, and Windows targets
  • Static MSVC runtime in Windows release binaries
  • mosh-client -c, -v, and standard Mosh client environment parsing

-v, -vv, and -vvv enable lifecycle, SSP summary, and aggregate packet metadata diagnostics respectively. Diagnostics never include session keys, input, terminal output, authenticated plaintext, or datagram contents. Higher levels saturate at -vvv.

Without terminfo, -c is necessarily heuristic. FerNomade uses TERM, COLORTERM, and the platform-reported color capability; unknown terminals are reported conservatively. POSIX clients require the effective LC_ALL/LC_CTYPE/LANG locale to name UTF-8.

On Windows, console control events for Ctrl+C and Ctrl+Break are ignored by the local process so their input can be forwarded to the remote session. This path is compile-checked in CI but has not yet been claimed as end-to-end validated under every Windows terminal host.

Architecture

The workspace keeps protocol concerns separate from operating-system concerns:

Crate Responsibility
fernomade-wire Fragment framing, bounded Protobuf decoding, and compression
fernomade-crypto Session-key ownership and OCB3 packet envelopes
fernomade-session State numbers, acknowledgements, replay handling, and reassembly
fernomade-state Cloneable bounded remote terminal states for SSP history reconstruction
fernomade-runtime Deterministic timers, queues, retransmission, and host actions
fernomade-terminal Terminal lifecycle and input encoding
fernomade-predict Non-authoritative local prediction overlay
fernomade-client UDP and local-console command-line application
fernomade-lab Black-box compatibility probes and synthetic fixtures

The embeddable API is described in docs/EMBEDDING.md.

Compatibility

The checked-in laboratory verifies FerNomade against Debian mosh-server 1.4.0-1+b1 on arm64. It exercises bidirectional state exchange, packet loss, retransmission, reordering, and UDP rebinding.

$ ./lab/verify-fernomade-to-standard-server.sh
standard server exchanged FerNomade state: ... roamed=true

See docs/COMPATIBILITY.md for the pinned artifact and the exact scope of the compatibility claim.

Development

Rust 1.85 or later is required.

$ cargo build --workspace --locked
$ cargo test --workspace --locked
$ cargo clippy --workspace --all-targets --locked -- -D warnings
$ cargo deny check

Run the real PTY lifecycle check:

$ cargo build --package fernomade-client
$ ./lab/verify-terminal-restoration.exp

Create a self-contained release archive:

$ ./scripts/package-release.sh 0.1.0 aarch64-apple-darwin

The archive contains fernomade, a mosh-client compatibility copy, the license, copyright and attribution notices, third-party notices, and a SHA-256 checksum.

GitHub releases

Pushing a semantic version tag builds native archives for Linux x86_64/arm64, macOS x86_64/arm64, and Windows x86_64, then publishes them to a GitHub Release:

$ git tag -a v0.1.0 -m "FerNomade 0.1.0"
$ git push origin v0.1.0

The release workflow runs the test and Clippy gates before packaging. A failed platform build prevents the GitHub Release from being created.

Documentation

License and independence

FerNomade is licensed under Apache-2.0. Attribution information is recorded in NOTICE. It is an independent implementation and is not affiliated with or endorsed by the Mosh project. Mosh is a registered trademark of its respective owner.

About

A pure-Rust mosh client.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages