tui-tools

tui-wireguard

WireGuard interfaces and peers, from the terminal

A terminal UI (TUI) for wg on Linux: WireGuard interfaces and their peers from the terminal, and the host around them.

v0.6.2betavpnMIT
The interfaces screen: state, listen port, whether the host firewall opens the port and forwards for the interface, and peer counts
The interfaces screen: state, listen port, whether the host firewall opens the port and forwards for the interface, and peer counts

WireGuard interfaces and their peers from the terminal, and the host around them.

The interfaces screen reads wg show all dump: each interface's state, listen port and peer count, plus whether the host firewall lets a handshake reach the port (read from tui-firewall, nftables or iptables, so firewalld and ufw are seen as they are) and whether the host forwards for it. The peers screen shows endpoints, handshakes, transfer, allowed IPs and keepalive.

Every change is previewed as the exact command line and applied only after you confirm it: creating an interface from zero (an endpoint, or a forwarding server with its ip_forward, FORWARD and MASQUERADE rules and its listen port opened in INPUT, or a firewalld policy on firewalld), bringing one up or down, adding or removing a peer (optionally with its endpoint, a persistent keepalive and a generated pre-shared key) and saving the runtime config. A private key is never shown, typed, or put on a command line.

This tool was called tui-vpn up to 0.4.x. The Headscale control plane it used to manage moved to tui-tailscale.

Run it with --demo to see every screen with nothing installed.

Keys

KeyAction
tab / 1 / 2Switch screen (interfaces, peers)
NCreate an interface: endpoint or forwarding server (keygen, conf, ip_forward, port, up)
u / dBring the selected interface up / down
wSave the interface's runtime config (wg-quick save, keys kept out of the conf)
a / xAdd / remove a peer (add: optional endpoint, keepalive, pre-shared key file)
FA forwarding server's ip_forward: write its sysctl.d drop-in, or remove it
r / ctrl+rReload
?Help
qQuit

Press ? inside the tool for the full help screen, which is generated from the same action table as the key map.

Compatibility

This tool is a face on the program below, so its version matters. Tested is not a claim: a version lands there only after the tool's own suite passed against it on a real machine in the lab, and the run is kept as evidence in the repository. At startup the tool probes the backend once and says what it found in its header — a version nobody has run against is shown as (untested) in the warning colour, one older than the minimum as (below minimum) in the error colour. Neither stops it: the backend still refuses what it cannot do, in its own words.

wireguard-tools

wg ≥ 1.0.20200513
Binary
wg
Minimum
1.0.20200513
Probed with
wg --version
Tested
1.0.202109141.0.202505211.0.20260223

Maintain wireguard-tools? You are welcome to help shape this tool. About → maintainers

Guides

Written after the work, from a machine the commands were actually run on. Every guide that mentions tui-wireguard is listed here.

Install

Once per machine, then every tool in the family is one pacman away.

Add the repository
$ curl -fsSL https://pkgs.tui.tools/install.sh | sh
Or run the same thing yourself, one command at a time

A family whose whole promise is preview before you run is not going to insist you pipe a script into a shell. These are the commands that script runs.

The one-time setup, by hand
$ curl -fsSL -o /tmp/tui-tools.asc https://pkgs.tui.tools/pubkey.asc
  sudo pacman-key --add /tmp/tui-tools.asc
  sudo pacman-key --lsign-key \
    "$(gpg --show-keys --with-colons /tmp/tui-tools.asc | awk -F: '/^fpr:/{print $10; exit}')"
  printf '[tui-tools]\nServer = https://pkgs.tui.tools/arch/$arch\n' \
    | sudo tee -a /etc/pacman.conf
  sudo pacman -Sy
Arch Linux · tui-wireguard
$ sudo pacman -S tui-wireguard

Upgrades then arrive with the rest of your system updates.

What it can do to your machine

  • Preview, then confirm

    Every change is shown as an exact command line and confirmed before it runs. The dialog and the runner receive the same value, so the preview cannot drift from what executes.

  • Escalates for actions

    Reading WireGuard needs CAP_NET_ADMIN and the iptables ruleset is root-only, so those reads escalate; ip does not. Every mutation escalates, previewed and confirmed first.

  • No daemon, no state of its own

    Nothing keeps running after you quit, and nothing is installed to run later. The system is the source of truth; the tool re-reads it after every change.

  • No network access

    The tool opens no network connection of its own. No telemetry, no update check, no phone home.

  • Static binary

    Released statically linked, with no runtime dependencies to install.

  • Signed release, with provenance

    checksums.txt carries a keyless cosign signature from this repository's release workflow, every archive has a CycloneDX SBOM, and every archive, package and the checksum file carry SLSA build provenance. The security page shows the three commands that check it.

Reporting

Report a security issue privately, through GitHub's private vulnerability reporting on the repository's Security tab. The family-wide policy, and what counts as in scope, is on the security page.

Downloads

v0.6.2 · 2026-10-22
FileSizeSHA-256
checksums.txt1 KB—
checksums.txt.sigstore.json10 KB—
provenance.intoto.jsonl12 KB—
tui-wireguard-0.6.2-1-aarch64.pkg.tar.zst1.8 MBc10565b857ccec039ee6832b7c6c1b618716f7fccdc008f549f56273fda49e1a
tui-wireguard-0.6.2-1-x86_64.pkg.tar.zst2.0 MBe6fcd2339b096dc83f590f9c5f62c89aa7c1c3dae20c8360efbe033f5038b10e
tui-wireguard-0.6.2-1.aarch64.rpm1.8 MBb3488a66d76a1b380be5f53802d8f969ab4686cabd54e2d0746be790afc860a6
tui-wireguard-0.6.2-1.x86_64.rpm1.9 MB3a40004ef632a9183cf3fe4cdff108dd1b82bf4014a5a96fe634659b54d51417
tui-wireguard_0.6.2_amd64.deb1.9 MBfe92eec5a0c214b79267df506c3f16c4a7bbb9f01d943191f61310959e2d0f35
tui-wireguard_0.6.2_arm64.deb1.8 MB3162fb439af641a5a1ded5b63d5ac508542c0a3c8df5b8c649c9b3a64b7321c6
tui-wireguard_0.6.2_linux_amd64.tar.gz1.9 MBfc2664afd1045860c033c4ad25f7e2d48921a624ea1b0f53bb009543d9cdc4b7
tui-wireguard_0.6.2_linux_amd64.tar.gz.cyclonedx.json24 KB9682722d6ae83df64e9048c9ba75f38e9b1a3211bda62dc2a10c3b1578891dea
tui-wireguard_0.6.2_linux_arm64.tar.gz1.8 MB08dc6d7d5b9aa49bc76209f15172c2864fdffccc9a6075b8dc0e616a446efe19
tui-wireguard_0.6.2_linux_arm64.tar.gz.cyclonedx.json24 KB32106cf752188d3c8c2a9c6c38d5500c19e2b6e6817c307a75bba247ca65da27

Every release ships a checksums.txt. Download it next to the archive and run sha256sum -c checksums.txt --ignore-missing. See verifying a download.

Releases

v0.6.2

2026-10-22
## tui-wireguard v0.6.2

tui-wireguard 0.6.2

- Built with Go 1.27.3, which fixes CVE-2026-111943 in the standard library (crypto/x509), and tui-kit v0.4.5; dependencies on their latest versions. No change in behavior.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* 5bad8422064284ff0d8a4af9680272c139725995 0.6.2: Go 1.27.3 (stdlib security fixes) (#39)
* 3cbe8ba9458f098f9a6d28f85c370fea9eac276f Bump the github-actions group across 1 directory with 9 updates (#36)

v0.6.1

2026-10-20
## tui-wireguard v0.6.1

tui-wireguard 0.6.1

- Built with Go 1.27.2, which fixes CVE-2026-78667, CVE-2026-78669 and CVE-2026-97031 in the standard library (net/http, crypto/tls). No change in behavior.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* ca190c78752cb775e45b90262fa2039c1fed0e50 0.6.1: Go 1.27.2 (stdlib security fixes) (#38)

v0.6.0

2026-10-20
## tui-wireguard v0.6.0

tui-wireguard 0.6.0

- **Saving keeps the conf secret-free (#32).** `w` runs `wg-quick save` and then, in the same previewed step, removes `PrivateKey` when the conf loads it from the tool's key file, and replaces each peer's inline `PresharedKey` with a `PostUp` that loads it from its `.psk` file. Saving again changes nothing. A hand-written conf, or one whose key file is missing or different, keeps its keys inline as before.
- **Kernel forwarding outside wg-quick (#33).** A forwarding server turns on `net.ipv4.ip_forward` with a drop-in, `/etc/sysctl.d/90-tui-wireguard-<interface>-forward.conf`, and `sysctl -w`, both previewed, instead of a `PostUp` hook that Ubuntu 26.04's AppArmor profile for wg-quick denies. New confs no longer carry the hook; existing ones are left alone.
- **`F` on the interfaces screen** turns kernel forwarding on for a forwarding server that lacks it (servers made by earlier versions on Ubuntu 26.04), or removes the tool's drop-in.
- **Forwarding off is reported.** The FORWARD column shows `ip_fwd=0` and `--check` reports `kernelForwarding`, `kernelForwardingAtBoot` and per-interface `forwardingDropIn` and `problems` when rules exist but the kernel does not forward.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* 9199135041e31697ae55f4348a5f93faeb630243 Keep the conf secret-free on save; kernel forwarding via sysctl.d (#37)

v0.5.2

2026-09-26
## tui-wireguard v0.5.2

tui-wireguard 0.5.2

- **Forwarding server on firewalld (#30).** When firewalld is running, `N` as a forwarding server writes a firewalld policy into the conf instead of iptables FORWARD and MASQUERADE rules, which firewalld's own forward chain overruled. PostUp creates the policy `<interface>-fwd` (ingress ANY, egress the egress NIC's zone, accept and masquerade scoped to the peers' network and each destination) with `firewall-cmd --permanent` and reloads; PostDown deletes it and reloads, so `down` puts firewalld back as it was. The dialog says that each reload drops runtime-only firewalld changes.
- **The WireGuard interface is bound to the zone it falls into** (and unbound at `down`) only when the egress NIC is not bound to a zone either: firewalld dispatches no policy between two interfaces that are both only in the default zone's catch-all. With a NIC NetworkManager manages, nothing is bound.
- **Known limitation, Ubuntu 26.04:** its AppArmor `wg-quick` profile denies the hooks' `sysctl -w net.ipv4.ip_forward=1`, so a forwarding server there needs `ip_forward` turned on by hand (documented in the README). Not new in this release.
- **Port step on a firewalld forwarding server** is `firewall-cmd --permanent --add-port=<port>/udp`, since the interface's reload at `up` would drop a runtime-only port.
- **FORWARD column and `--check` read firewalld** (`firewall-cmd --list-all-policies` and `--list-all-zones`) when it is running. `--check` adds `forwardingChecked`, `forwardingSource` (`firewalld` or `iptables`) and `forwardingManager` (`firewalld` or `ufw`).
- ufw hosts and hosts with a plain nftables or iptables ruleset keep the iptables rules and read.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* be4edba429b5c6bb01bd8714c3f04f08124cbc74 0.5.2: forwarding server on firewalld builds a firewalld policy and reads it back (#30) (#31)

v0.5.1

2026-09-26
## tui-wireguard v0.5.1

tui-wireguard 0.5.1

- **Add peer: endpoint and persistent keepalive (#27).** After the key line, `a` asks for the peer's endpoint (`host:port` or `[v6]:port`, validated) and a persistent keepalive (0-65535 seconds, empty or 0 is off, prefilled with 25 once an endpoint is given). Both are optional and land on the one previewed `wg set … endpoint … persistent-keepalive …`, so `wg-quick save` persists them and the peers screen shows them (ENDPOINT, KEEP). A bad value reopens its step with the value as typed and the reason; a bad key line is reported before the optional steps open.
- **UDP IN reads the firewall in charge (#28).** The interfaces screen's UDP IN column and `--check`'s `listenPortInput` now read `tui-firewall --check` when tui-firewall is installed, else `nft -j list ruleset` (following jumps and gotos into user chains), else `iptables -S`. firewalld's rules, in its own nftables table, are seen at last. Undetermined (a jump that cannot be followed, a firewalld service whose ports are unknown) reads `?` / `unknown`, never closed. `--check` adds `firewallSource` and `firewallManager`.
- **Port step on firewalld.** The create wizard opens the listen port with `firewall-cmd --add-port=<port>/udp` on a firewalld host (an iptables INPUT rule sits in a table firewalld's reject never consults), and each firewall gets its own "to keep it" hint (`firewall-cmd --permanent`, `ufw allow`, `netfilter-persistent save`).
- **tui-kit v0.4.4**: runner children get no controlling terminal (a prompt fails fast instead of hanging behind the TUI); a failed step's status line goes through `runner.StatusLine`. `go get -u` on the rest.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* fd9c9b77063f82c06637adc92ab70eaf1c7b7d31 0.5.1: endpoint and keepalive on add-peer; firewall-aware UDP IN; tui-kit v0.4.4 (#27 #28) (#29)

v0.5.0

2026-09-25
## tui-wireguard v0.5.0

tui-wireguard 0.5.0: tui-vpn is now tui-wireguard

WireGuard interfaces and peers from the terminal: status, peers, a new interface as an endpoint or as a forwarding server (IP forwarding, FORWARD rules, NAT and the listen port previewed together), persistence with wg-quick, and a down interface kept on screen so it can be brought back up. The Headscale control plane moved to tui-tailscale. The package replaces tui-vpn on apt, dnf and pacman; configuration under the old tui-vpn paths is still read. Built with tui-kit v0.4.3.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* 4ed006336bde3be37a7e5a4ac77fd952b0ad5188 Become tui-wireguard: WireGuard only; Headscale moved to tui-tailscale (#26)
* cb69e9ce337e0a9cc97b777434d2ac7cc65ac0c0 Host validation, stopped-unit screens, OIDC presets, forwarding server, routes approval (#25)

v0.4.0

2026-09-24
## tui-vpn v0.4.0

Control plane from the tool: transport choice (plain http, Let's Encrypt, own certificate, reverse proxy) and MagicDNS base domain in S, enable at boot, state ownership check and fix. Validated on a real Ubuntu 24.04 host: Let's Encrypt on 443, OIDC against Google, first node registered through the browser.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* 08b566642c8e15acca99b3cfdac9f0d5f359aedb Bump anchore/sbom-action/download-syft in the github-actions group (#11)
* 2951e47b9677936c9a9f7313c071347d453d5e40 Bump the github-actions group with 4 updates (#12)
* ca09f2086ae9a48fe699d246e2f04c791b38b5c4 Control plane: transport choice, unit enable, state ownership (#20)
* a7f73deaa89f1b8157266641473dd807ee828b90 README: link the tool's page on tui.tools (#10)
* e4d32534fe6c9d40ef018044aee4bb1a9cb99992 README: point the install snippet at the current release (#9)

v0.3.0

2026-09-02
## tui-vpn v0.3.0

v0.3.0: headscale server settings and OIDC identity provider setup from the users screen

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* e305fd9bb243a155c5f7c6c362e30987fb13692a Manage the control plane's identity, not just report on it (#8)

v0.2.1

2026-09-02
## tui-vpn v0.2.1

tui-kit v0.3.0: the dialogs wrap and scroll instead of clipping the
command preview, and the picker filters as you type.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* acb05fbcbb276183df33e515d6050cf3c615e520 Bump tui-kit to v0.3.0 (#7)
* 35cc8c9bdf18225d1372b40982fcce3b97fc1271 tool.json: released (#6)

v0.2.0

2026-09-01
## tui-vpn v0.2.0

Manage, not view: create and edit from the TUI (wave 1), lab-validated on the router image.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* b40ba2f90774e40ed7a58ca7c5168f78e5dc5e55 Manage, not view: interface bootstrap, persistence, preauth create, node ops (#5)