Peer-to-peer remote access without port forwards.
Link your own machines with a one-time approval, then open a remote shell, copy files, SSH, or reach local web services over an encrypted P2P path (iroh: QUIC, NAT hole punching, relay fallback).
Inspired by Signal linked devices (explicit trust) and Syncthing (dial by device id, not IP).
| Status | v0.1.0-alpha.3 — early adopters; CLI may still change |
| License | Apache-2.0 OR MIT |
| Repo | https://github.com/jtwolfe/MyMesh |
| Capability | How |
|---|---|
| Link machines | Arm host → join by id/words → accept once (default). SPAKE local mailbox optional |
| Device ids | 64-char hex or 24 BIP39 words; QR / join URI |
| Always-up agent | mymesh install → user systemd unit + dial proxy |
| Remote shell | mymesh shell <peer> or TUI Term |
| File copy | mymesh cp + TUI dual-pane browser |
| Mesh roster | Gossip membership; kick with double confirm + pending delivery |
| Labels / aliases / groups | label, alias, group, hosts, resolve |
| SSH over mesh | ssh-config + proxy-ssh → peer 127.0.0.1:22 |
| TCP tunnels | expose, magic auto-ports, SOCKS5 for browsers |
| Userspace DNS | 127.0.0.1:5353 answers *.mym (not system-wide by default) |
| Connect-by-carrier | Phone scans QR; phone is not a mesh node |
| Firewall helpers | Explicit mymesh firewall … for ufw/firewalld (never auto-open) |
| TUI | Default when you run mymesh with no args |
| Area | Status |
|---|---|
System-wide ping laptop.mym |
Needs you to wire OS DNS to MyMesh; ICMP not tunneled |
| Full L3 VPN / TUN | Not a goal for alpha.3 |
| Desktop / remote GUI control | Stub only |
| Native GUI / web admin | Not built (TUI is the UI) |
| Android “carrier as mesh node” app | Future |
| Packages (deb/rpm/AUR) + one-line curl installer | Planned |
| CI (Linux) | Workflow present, disabled |
| Stable API / CLI freeze | No — alpha |
MyMesh is not Tailscale/WireGuard and not a drop-in public OpenSSH replacement. It is a personal mesh for machines you explicitly link.
- Linux (primary; other OSes untested)
- Rust 1.91+ to build from source
- Outbound internet on both peers for the default path (iroh relays)
- For SSH: sshd listening on the remote (
127.0.0.1:22is enough) - For browser paths: agent running + SOCKS (or magic ports + DNS)
git clone https://github.com/jtwolfe/MyMesh.git
cd MyMesh
git checkout v0.1.0-alpha.3 # or main
cargo build --release -p mymesh-cli
./target/release/mymesh init --label laptop
./target/release/mymesh install # ~/.local/bin + user unit + completions
systemctl --user enable --now mymesh.service
systemctl --user status mymesh
mymesh --versionPrefer user install (no root). Root install prints a strong warning and needs override — see docs/INSTALL-POLICY.md.
After install, the agent owns the single iroh endpoint and exposes a local dial proxy ($XDG_RUNTIME_DIR/mymesh.sock). CLI/TUI dial through that proxy — do not run a second long-lived serve as another user with the same identity.
mymesh init --label desktop # once per machine
mymesh install
systemctl --user enable --now mymesh
mymesh statusHost (already in the mesh / will approve):
mymesh connect-request allow # arms joins briefly
mymesh id # share hex or 24 wordsJoiner:
mymesh link '<host-hex-or-24-words>'Host:
mymesh requests list
mymesh requests accept <short-id>mymesh devices
mymesh ping desktop
mymesh shell desktop
mymesh cp ./file desktop:~/file
mymesh # TUI# remote must run sshd; mesh path must work (ping first)
mymesh ssh-config >> ~/.ssh/config
ssh desktop.mym# agent running on this machine
export ALL_PROXY=socks5h://127.0.0.1:18080 # socks5h = resolve *.mym via proxy
curl -v http://laptop.mym:7878/
# or configure browser: SOCKS5 127.0.0.1:18080 + proxy DNSFull command reference: docs/USAGE.md
Magic plane details: docs/ALPHA-3.md
Linking model: docs/JOIN.md
| Doc | Contents |
|---|---|
| docs/USAGE.md | Comprehensive CLI + TUI + SSH + SOCKS + ops |
| docs/ALPHA-3.md | Magic plane design & limits |
| docs/JOIN.md | Arming, ids, carrier, SPAKE |
| docs/SECURITY.md | Threat model (alpha) |
| docs/ARCHITECTURE.md | Crate layout, endpoint ownership |
| docs/INSTALL-POLICY.md | User vs root install |
| docs/ROADMAP.md | What’s next |
| docs/v0.1-promotion-goals.md | Maintainability gates before non-alpha v0.1 |
| CHANGELOG.md | Release notes |
| docs/PROTOCOL.md | Frame notes |
| docs/M1-M3.md | Early milestone design |
crates/
mymesh-cli CLI + TUI binary (`mymesh`)
mymesh-core config, devices, mesh state, paths
mymesh-crypto identity, SPAKE2, 24-word ids
mymesh-protocol frames + messages
mymesh-net iroh transport, dial proxy, mailboxes
mymesh-session join, agent, mesh sync, magic, carrier, TCP tunnel
mymesh-terminal PTY host/client
mymesh-files sandboxed transfer
mymesh-desktop stub (deferred)
- Default closed: joins fail unless the host is armed
- Trust = allowlist: only
Trustedpeers get shell/files/TCP - Agent runs as the installing user (user unit default)
- Files sandboxed (default: home)
- A compromised linked peer with Terminal+Files is powerful — unlink / kick promptly
- Firewall helper is explicit only; never opens ports by itself
| Release | Focus |
|---|---|
| v0.1.0-alpha.1 | Link + shell + cp |
| v0.1.0-alpha.2 | Install, TUI, mesh gossip, kick |
| v0.1.0-alpha.3 | Magic names, SSH, SOCKS, carrier, labels (this) |
| Later | System DNS helper, packages, GUI, desktop, CI |
Alpha: expect breakage. Issues and PRs welcome.
Dual-licensed under Apache-2.0 OR MIT.