Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ssh-nym

SSH over the Nym mixnet — connect to any machine running sshd through a privacy-preserving onion network without exposing a public IP address or open port.

  Your machine                    Nym mixnet                 Remote machine
  ──────────────────────────────────────────────────────────────────────────
  ssh ──ProxyCommand──> ssh-nym client ──Nym packets──> ssh-nym server ──> sshd
  • The server binds a persistent Nym address and forwards connections to local sshd.
  • The client is used as an SSH ProxyCommand; it tunnels stdin/stdout through Nym.
  • SSH provides its own encryption — Nym provides network-level anonymity.
  • Packets are sequenced and retransmitted to handle mixnet reordering and loss.

Server installation

Install on the machine you want to reach over SSH.

From .deb (recommended)

sudo dpkg -i ssh-nym-server_0.1.0_amd64.deb

This installs /usr/bin/ssh-nym and a systemd service unit.

Enable and start the service:

sudo systemctl enable --now ssh-nym

Get the server's Nym address (needed by clients):

sudo journalctl -u ssh-nym | grep "Server Nym address" -A1

The address looks like:

3Cku2yn5AmyvpCeVKPruw4DxMtqnUdNW8Hj9ymkuMfkU.4QN5wd55HFoH6Ta5dxNUE9xgxXhenrQcxt6Eivnzxhau@J4FegtCGLtrybiNno2BKVpmHrgVe4X9tGgPS2rBGdDbk

This address is stable across restarts — the identity keys are stored in /root/.local/share/ssh-nym (or ~/.local/share/ssh-nym for the user running the service). Share it once; it never changes unless you delete the storage directory.

Custom sshd address or storage path

Override via a systemd drop-in:

sudo systemctl edit ssh-nym
[Service]
ExecStart=
ExecStart=/usr/bin/ssh-nym server --sshd-addr 127.0.0.1:2222 --storage-dir /var/lib/ssh-nym

Service management

sudo systemctl status ssh-nym      # check status and see the Nym address
sudo systemctl restart ssh-nym     # restart (address stays the same)
sudo systemctl stop ssh-nym        # graceful stop (flushes SURB database)
sudo journalctl -u ssh-nym -f      # live logs

Client installation

Install on the machine you SSH from.

From .deb

sudo dpkg -i ssh-nym-client_0.1.0_amd64.deb

Installs /usr/bin/ssh-nym. No extra dependencies are pulled in.

Configure SSH

Add a Host block to ~/.ssh/config, replacing <NYM_ADDRESS> with the address printed by the server:

Host my-server
    User root
    ProxyCommand ssh-nym connect <NYM_ADDRESS>

Then connect normally:

ssh my-server

Or without editing the config:

ssh -o ProxyCommand="ssh-nym connect <NYM_ADDRESS>" root@localhost

First-connection note

The Nym client initialises on each run (fetches network topology, registers with a gateway). This takes 10–30 seconds before the SSH handshake begins — this is normal. Subsequent reconnections take the same time because the client identity is ephemeral on the client side.


Building from source

Requires Rust and the x86_64-unknown-linux-musl target for static builds.

# Install the musl target if not already present
rustup target add x86_64-unknown-linux-musl

# Build both .deb packages (static binary, no glibc dependency)
./build-deb.sh

# Packages produced:
#   target/deb/ssh-nym-client_<version>_amd64.deb
#   target/deb/ssh-nym-server_<version>_amd64.deb

Note on vendored crates: Three upstream Nym crates (nym-node-requests, nym-noise, nym-api-requests) are vendored in vendor/ with a one-line fix that aliases the renamed type VersionedNoiseKeyVersionedNoiseKeyV1.


Troubleshooting

SSH hangs after running ssh my-server

  • The first 10–30 s of silence is the Nym client initialising — wait for it.
  • Enable verbose SSH output to distinguish a Nym timeout from an SSH error:
    ssh -v my-server
  • Check that the server is running:
    sudo systemctl status ssh-nym

Error: Server error: sshd unreachable

  • sshd is not listening on the address the server is configured to forward to (default 127.0.0.1:22).
  • Check with sudo systemctl status ssh on the server machine.

Warning on server startup: loaded data is inconsistent

  • The server was previously stopped with SIGKILL (e.g. kill -9) instead of systemctl stop, leaving the SURB database in an inconsistent state. The Nym SDK recovers automatically by recreating the database. The Nym address is unaffected. Use systemctl stop ssh-nym for clean shutdowns.

GLIBC_2.38 not found

  • You are running a binary built on a newer system. Rebuild with ./build-deb.sh to produce a statically linked musl binary that has no glibc dependency.

Environment variables

Variable Effect
RUST_LOG Log verbosity: error warn info debug

Logs are written to stderr so they never interfere with the SSH data stream on stdout.


Architecture

File Responsibility
src/main.rs CLI entry point (server / connect subcommands)
src/server.rs Persistent Nym identity, session multiplexing, sshd proxy, graceful shutdown
src/client.rs Ephemeral Nym identity, stdin/stdout ProxyCommand bridge
src/protocol.rs Msg enum (Connect / Data / Ack / Retransmit / Close / Error), bincode framing
src/tunnel.rs Reliable ordered delivery: sequence numbers, sliding-window ACK, retransmit
vendor/ Patched Nym crates

License

GPL-3.0-only

About

No description, website, or topics provided.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages