Skip to content

eznix86/mssh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mssh

Minimal rendezvous service for reaching SSH behind NAT

This enables SSH access to machines behind NAT/firewalls using a simple rendezvous server. No complex VPN setup required, works with your ssh command out of the box.

mssh diagram

Usage

Deploy the server on a publicly reachable machine, run the agent on each host behind NAT, then connect from your machines using either the built-in Go SSH client or the ProxyCommand approach described below.

Command Purpose
mssh server Runs the rendezvous service on a public host
mssh agent <node-id> Keeps a connection open from a NATed host back to the server
mssh proxy <node-id> / mssh user@node Lets you connect from your machines

Server

Run the rendezvous server:

mssh server --host 0.0.0.0 --port 8443

Production tip: Deploy behind a TLS proxy (nginx, Traefik, Caddy) with Let's Encrypt for secure public exposure.

Agent

Run on the remote host behind NAT:

# With explicit node-id
mssh agent prod-db-1 --server rendezvous.example.com:8443 --ssh-port 22

# Auto-detect node-id from primary IPv4
mssh agent --server rendezvous.example.com:8443

The agent automatically re-registers after each session ends.

Node-ID rules: May contain letters, digits, ., _, and -. If omitted, the primary IPv4 address is used.

Client

Built-in SSH client:

mssh alice@prod-db-1

# With custom server or identity
mssh alice@prod-db-1 --server other.example.net:8443 --identity ~/.ssh/prod_key

The client scans ~/.ssh/id_{ed25519,rsa,ecdsa} (with passphrase prompts) and falls back to SSH_AUTH_SOCK.

ProxyCommand integration:

ssh -o ProxyCommand="mssh proxy prod-db-1 --server rendezvous.example.com:8443" alice@localhost

To make this seamless, add it to ~/.ssh/config so ssh prod-db works without long command lines:

Host prod-db-1
    HostName localhost
    User alice
    ProxyCommand mssh proxy prod-db-1 --server rendezvous.example.com:8443

Now simply run ssh prod-db and the ProxyCommand will invoke mssh proxy ... behind the scenes.

Installation

Set VERSION=vX.Y.Z to pin a specific release (default: latest).

Binary only

curl -fsSL https://raw.githubusercontent.com/eznix86/mssh/main/install/install.sh | sudo bash

The script drops the binary at /usr/local/bin/mssh (override with BIN_DIR=/path).

Server (systemd)

curl -fsSL https://raw.githubusercontent.com/eznix86/mssh/main/install/install.sh | \
  sudo BIN_DIR=/usr/local/bin bash -s -- server --host 0.0.0.0 --port 8443

Agent (systemd)

curl -fsSL https://raw.githubusercontent.com/eznix86/mssh/main/install/install.sh | \
  sudo bash -s -- agent --server rendezvous.example.com:8443 --ssh-port 22

if node-id is omited, it defaults to auto-detected IP. Or set unique name.

Manual Build

go build ./cmd/mssh
sudo install -m 0755 mssh /usr/local/bin/mssh

Uninstall

curl -fsSL https://raw.githubusercontent.com/eznix86/mssh/main/install/uninstall.sh | sudo bash

Removes the binary and disables all systemd units.

Configuration

Only used for mssh username@node-id

Initialize your config file:

mssh config init

This creates ~/.mssh/config.yaml:

server: rendezvous.example.com:8443
identity: ~/.ssh/id_ed25519   # optional; leave blank to auto-detect keys / use ssh-agent
nodes:
  prod-db-1:
    server: prod-rendezvous.example.com:8443
    identity: ~/.ssh/prod_key

Priority: CLI flags → node-specific values → top-level defaults

Security

  • TLS termination: Place the rendezvous server behind a TLS proxy (nginx/Caddy/Traefik) with Let's Encrypt
  • Optional hardening: Add mutual TLS or IP filtering at the proxy layer

License

MIT

About

Enable SSH access to machines behind NAT without a VPN

Topics

Resources

Stars

Watchers

Forks

Contributors