Files
umn/README.md
2026-08-31 17:21:07 -05:00

118 lines
6.3 KiB
Markdown

# Ultra Mesh Network
Ultra Mesh Network is a small, user-space mesh for macOS. Every running laptop gets a stable IPv6-looking overlay address, discovers nearby nodes over regular Wi-Fi and Apple peer-to-peer Wi-Fi, and can relay encrypted traffic for nodes that are not directly connected.
It installs a narrowly routed IPv6 `utun` interface. Ordinary applications can reach live mesh nodes directly while existing logical streams, text commands, `expose`, and the SOCKS5 proxy remain available for compatibility.
## Requirements and installation
- macOS 14 or newer on a personally controlled laptop
- Apple Command Line Tools with Swift 6
- Wi-Fi enabled on both Macs
Copy this project to each laptop and run:
```sh
./scripts/test.sh
./scripts/install.sh
umn status
umn address
```
The installer builds locally, asks for administrator authorization once, installs a minimal root LaunchDaemon for `utun` and `/128` route management, installs the scoped `.mesh` resolver, then starts `umnd` as a per-user LaunchAgent. Peer networking, keys, packet parsing, firewall state, and DNS remain in the unprivileged daemon. If prompted, allow local-network access. All persistent state lives in `~/Library/Application Support/UltraMesh`. The cryptographic identity in `identity.plist` determines the machine's mesh IPv6, and the same value is recorded as plain text in `address`; both files are mode `0600`.
Use `./scripts/uninstall.sh` to remove both daemons, the interface/routes, binaries, and installer-managed resolver. It deliberately preserves the entire state directory so reinstalling keeps the same mesh address. Do not edit or separately replace `identity.plist` or `address`: if either is corrupt, missing from an established identity/address pair, or mismatched, startup fails instead of silently assigning a new address.
To verify the persistent address after installation or a restart:
```sh
test "$(umn address)" = "$(tr -d '[:space:]' < "$HOME/Library/Application Support/UltraMesh/address")"
```
## Native IPv6
Set a local alias, then use standard applications without proxy settings:
```sh
umn alias set alice <mesh-address>
ping6 alice.mesh
ssh alice.mesh
curl http://alice.mesh:8080/
umn interface status
```
Only currently reachable, authenticated mesh addresses are installed as exact IPv6 `/128` routes. The interface never installs a default route or a broad ULA prefix. The local DNS server listens on TCP and UDP `127.0.0.1:53535`; `/etc/resolver/mesh` scopes only `.mesh` lookups to it. Aliases remain explicitly local and AAAA-only.
For development, run `swift run umnd` in one terminal and `swift run umn status` in another.
## Text communication
On the receiving laptop:
```sh
umn address
umn firewall allow overlay 7000 --from any
umn text listen 7000
```
On the sender:
```sh
umn ping <receiver-mesh-address>
umn text send <receiver-mesh-address> 7000 "hello over the mesh"
```
Replace `any` with a specific mesh address to restrict the port. Opening a firewall port is not sufficient by itself: a local service must also be bound. When `umn text listen` exits, the binding disappears but the firewall rule remains.
Useful diagnostics:
```sh
umn peers
umn routes
umn firewall list
umn alias set alice <mesh-address>
umn ping alice.mesh
```
Aliases are stored locally and are not claimed network-wide.
## HTTP and HTTPS
Run a local server and expose it on a logical mesh port:
```sh
# Host laptop
python3 -m http.server 8080 --bind 127.0.0.1
umn firewall allow overlay 80 --from any
umn expose 80 --to 127.0.0.1:8080
```
Start the client-side proxy:
```sh
umn alias set host <host-mesh-address>
umn proxy --listen 127.0.0.1:1080
curl --proxy socks5h://127.0.0.1:1080 http://host.mesh/
```
The proxy implements SOCKS5 `CONNECT` and binds only to loopback. A browser can use the same proxy after its SOCKS settings are pointed at `127.0.0.1:1080` with proxy-side DNS enabled.
HTTPS is passed through unchanged. The web server remains responsible for its TLS certificate, and a self-signed certificate will still produce the usual trust warning.
## Design and current limits
- Bonjour and Network.framework discover peers over infrastructure and Apple peer-to-peer Wi-Fi (`includePeerToPeer`). New routes recover automatically when an access-point path disappears while Wi-Fi remains enabled.
- The local mesh IPv6 is derived only from the persistent signing identity. Wi-Fi path changes, peer-to-peer fallback, route updates, `utun` recreation, reboots, and reinstalls do not select or alter it.
- Signed link-state announcements and shortest-hop routing support multi-hop topologies. The implementation is bounded and tested for 32 live nodes and 16 hops.
- Service payloads are authenticated and encrypted end-to-end with Curve25519, HKDF-SHA256, and ChaCha20-Poly1305. Relays see routing metadata but cannot read ports or content.
- Streams use sequence numbers, acknowledgements, retransmission, and a 60-second recovery window. An active stream can continue after a route change if another path appears within that window.
- The endpoint firewall permits outbound native connections and their bounded TCP/UDP return state. New inbound TCP/UDP flows require explicit rules such as `umn firewall allow tcp 8080 --from any`; logical services use `overlay`. ICMPv6 echo is rate-limited and related errors are admitted conservatively. Transit traffic is independent of endpoint rules.
- Native packets are complete, signed, replay-protected IPv6 packets encrypted end-to-end. TCP retransmission and flow control are supplied by macOS; retransmissions use the current shortest-hop route.
- IPv6 fragments, multicast, malformed packets, unsafe routing headers, and unsupported next headers are dropped. The native peer queue is bounded and control traffic takes priority.
- Text is limited to 4 KiB. A logical stream is limited to 1 MiB total and the daemon supports at most 32 simultaneous streams.
- There is no durable offline queue: a new operation with no live route fails immediately.
- Membership is open. Identities are self-authenticating, but there is no global authority, revocation service, or Sybil resistance yet.
- Apple peer-to-peer Wi-Fi works only between Apple devices. The documented mesh protocol is transport-independent so other bearers can be added later.
The on-wire details are in [docs/protocol.md](docs/protocol.md).