Mesh

Mesh links your devices into a private SSH network. Stock OpenSSH carries every connection, and mesh writes the ~/.ssh/config and ~/.ssh/authorized_keys entries that keep ssh <device> working as machines move between networks. It runs on Linux, macOS and Android under Termux.

curl -fsSL https://releases.santoku.dev/mesh/0.1.5-1/install.sh | sh

How it works

Getting started

Create the key that opens your shells, and keep it in an agent:

ssh-keygen -t ed25519 -C me -f ~/.ssh/op
ssh-add ~/.ssh/op

On the first device:

mesh init desk --operator ~/.ssh/op.pub
mesh schedule

To add a laptop, run this on desk:

mesh invite --serve

It prints a one-use token and an address. The join runs over TLS 1.3 keyed by that token. On the laptop:

mesh join book 192.168.1.10:43117 --token <token>

ssh desk and ssh book now work from either machine.

Reaching a peer

ssh <peer> tries each route in turn until one answers:

  1. the last address that worked
  2. a fixed address from the peer's configuration
  3. the addresses in the peer's signed record
  4. a relay through another member that can reach it
  5. a sweep of the local subnets

Every candidate must present the host key pinned for that peer, so the wrong machine at the right address is refused. Mesh has no rendezvous server, so two peers with no shared member and no fixed address stay unreachable.

Guests

mesh guest web01 198.51.100.7 --user deploy
ssh web01

A forward alias reaches a port only the guest can see:

mesh guest web01 198.51.100.7 --user deploy --fwd db:15432:127.0.0.1:5432
ssh web01-db

A guest with a new address on every launch is declared --dynamic, and a mesh-resolve-<name> program on PATH supplies its address and host key.

Access control

Commands

CommandWhat it does
init <name> --operator <pubkey>name this device and create its identity
invite [--serve]mint a one-use join token
join <name> <addr> --token <tok>join a mesh as <name>
adopt <user@host>pull a node in from this side
guest <name> [addr]declare a dial-only node
operatorshow, add or remove a shell key
evict <node>remove a member or guest
statusshow members, guests, forwards and operators
scheduleinstall the background service

Requirements

bash, git 2.38 or later, the OpenSSH client and server, openssl, tar, timeout and flock. nmap enables the subnet sweep. On macOS, Homebrew's flock and coreutils supply the last two. Both ends of a join need a reachable sshd.

What mesh doesn't do

Mesh routes no traffic and adds nothing ssh doesn't already do. It isn't a VPN, a secret store or an access-request system: it authorizes keys you've already decided to trust.