# easywireguard (`ewg`)
> **Canonical:** [gitlab.com/safteinzz/easywireguard](https://gitlab.com/safteinzz/easywireguard) · **Mirror:** [github.com/safteinzz/easywireguard](https://github.com/safteinzz/easywireguard)
mesh, minus the mess - interfaces, keys and full-mesh configs in one CLI + TUI
## Install
```bash
cargo install easywireguard # the command you type is the shorter `ewg`
ewg self update # reinstall the latest release later on
```

## Manage every interface
Bare `ewg` opens on the interface manager: every `.conf` across the dirs you
registered, with what it is doing right now. `● up` is running, `○ down` is
stopped, `⏻ boot` starts with the machine.

## Tell whether it is actually working
`i` shows the config, and for a running interface a live `wg show` under it:
the peer, the last handshake, the bytes moved.

## See the whole mesh
Describe each node once and `ewg` lays them out hub-and-spoke, spokes nested
under the hub they dial. A hub has an endpoint and meshes with every other hub;
a spoke has none and lists only its hub, so phones never get useless peer blocks
for each other.

By default a node advertises just its own `/32`. Set `allowed-ips` to `0.0.0.0/0`
to make a hub a full-tunnel exit, or to a LAN subnet for site-to-site.
## Create a node without touching a key
`c` opens a wizard: pick **Spoke** or **Hub**, fill a couple of fields, and the
keypair is generated for you. **store** keeps the private key in the manifest so
you can re-export a working config later; **redact** leaves it only in the QR and
file handed out at create, nothing secret at rest.

## Onboard a phone by scanning
`↵` on a node renders its config as a black-on-white QR that scans on any
terminal theme. Open the WireGuard app, scan, done - no file transfer. `E`
exports the same config as `out/<name>.conf`, an install to `/etc/wireguard`, a
PNG, or an Ansible peer entry.

## Keys
| `j/k` `↑↓` | move | move |
| `h/l` `←→` `tab` | switch tab | switch tab |
| `↵` | toggle up / down | show the QR |
| `c` | new config in `$EDITOR` | create a node |
| `e` | edit it in `$EDITOR` | edit the node |
| `d` | delete (keeps a `.bak`) | remove from the manifest |
| `i` | inspect, with live `wg show` | view the generated config |
| `b` | toggle start-on-boot | |
| `R` | | rotate the keypair |
| `E` | | export (file, install, QR, Ansible) |
| `g` | | generate every node's config |
| `r` | refresh | reload the manifest |
| `q` `esc` | quit | quit |
A config pasted into `$EDITOR` is validated before it lands, so a truncated
paste is caught there rather than at `wg-quick up`.
## CLI
The TUI wraps these; call them directly to automate.
```bash
# interfaces
ewg check /etc/wireguard/*.conf # validate configs, non-zero exit if any is broken
# keys
# mesh: design, then generate each node's config
ewg mesh add flint --address 10.10.1.1/24 --pubkey <PUB> \
--endpoint vpn.example.com:51820 --allowed-ips 0.0.0.0/0 # a hub / exit
ewg mesh add phone --address 10.10.1.3/24 --pubkey <PUB> \
--hub flint --dns 192.168.10.250 --keepalive 25 [--private <PRIV>]
ewg mesh # list (-v verbose, --json; never prints private keys)
ewg mesh rm <name>
ewg mesh gen -o out/ # write every node's .conf
# QR (onboard a phone)
ewg qr <node> -m mesh.toml # QR of that node's generated config
ewg qr out/phone.conf -o phone.png # a .conf file, also written as a PNG
# the tool itself
`--hub` (repeatable) makes a node a spoke of those hubs; omit it and a spoke
reaches all hubs. `--private` is optional: omit it for a public-only manifest and
inject keys later.
## Notes
- Reading `/etc/wireguard` needs root; `ewg` auto-elevates with `sudo` (disable
with `EWG_NO_SUDO=1`). Point elsewhere with `--dir` or `$EWG_DIR`.
- `mesh.toml` may hold private keys for `store`-mode nodes, so treat it as a
secret and gitignore it; a redacted or public-only manifest is safe to commit.
`mesh list --json` never prints private keys.
- The Mesh tab reads `mesh.toml` from the directory you run `ewg` in, and `g`
writes to `./out` beside it.
- Start-on-boot uses systemd (`wg-quick@<name>`); toggling interfaces shells out
to your `wg-quick`. Keys and config generation are pure Rust, never a wrapper
around `wg`.
## License
AGPL-3.0-only.