WireGuard#
VPN → WireGuard manages the router's own in-kernel WireGuard: interfaces under
interfaces wireguard <name> and their peers. Nothing here is a container or a second
daemon — a tunnel is an interface with a key and a port, a peer is a public key and the
prefixes allowed through it, and both are configuration that stages, diffs, commits and
rolls back like any other. The page shows what the configuration declares beside what the
router reports about the interfaces, and it is honest about the gap: it has no handshake
times and no transfer counters.
Getting to the page#
The WireGuard entry carries the wireguard feature id in the navigation model, so it
appears when the feature is switched on in Apps or when interfaces wireguard already
exists in the configuration. A router that already runs WireGuard shows the page regardless
of the switch — the product does not hide configuration that exists
(ui/src/components/nav.ts,
agent/catalog.json).
Where the page gets its data#
GET /api/wireguard, re-read every 10 seconds, returns three things
(agent/opmode.go handleWireGuard):
| Key | From |
|---|---|
config | The interfaces wireguard subtree, read as a tag node so each tunnel is its own entry rather than one bogus wireguard tunnel. |
interfaces | The parsed table of show interfaces wireguard. |
raw | That command's text output. |
The CLI view is GET /api/config/commands?path=["interfaces","wireguard"], which is the
subtree as set commands — and, below the admin role, redacted the same way.
The tunnel cards#
One card per tunnel, titled with the interface name and a badge:
- up — the interface appears in
show interfaces wireguard. - not reported — it does not. That is a configured tunnel the router is not reporting, which usually means the interface failed to come up.
Each card lists Address, Listen port, MTU (default when unset), Description
and the peer count, and carries two buttons: + Peer, and Delete, which stages
delete interfaces wireguard wg0 — the tunnel and every peer on it.
Above the cards are three tiles: the number of tunnels, the number of peers, and the number of interfaces the router reports.
The peer table#
Every peer across every tunnel, in one table.
| Column | From |
|---|---|
| Peer | The peer's name — the tag it is configured under. |
| Tunnel | The interface it belongs to. |
| Public key | The first 16 characters of public-key, with an ellipsis. The full value is in the panel. |
| Endpoint | address:port, or the address alone, or roaming when the peer declares neither. |
| Allowed IPs | Every allowed-ips value, comma separated. |
| Keepalive | persistent-keepalive in seconds, or a dash. |
Clicking a row opens a panel with the full public key, the endpoint, the allowed prefixes,
the keepalive, and one Delete peer button that stages
delete interfaces wireguard wg0 peer laptop.
Creating a tunnel#
+ Add tunnel takes four fields and stages up to three operations:
| Field | Command |
|---|---|
Interface name (default wg0) | the tag in every path below |
Listen port (default 51820) | set interfaces wireguard wg0 port 51820 |
| Address | set interfaces wireguard wg0 address 10.10.0.1/24 |
| Private key | set interfaces wireguard wg0 private-key <key> |
set interfaces wireguard wg0 port 51820
set interfaces wireguard wg0 address 10.10.0.1/24
set interfaces wireguard wg0 private-key <key>The private key's hint says where to get one: generate it on the router with
run generate pki wireguard key-pair. The page does not generate keys, and it does not
paste a private key anywhere except into the operation you are staging — which is then
visible in the Commit Bar to the operator who typed it, and redacted from a viewer's read
of the configuration afterwards.
A tunnel with no address is legal — the field is optional here — but it will not carry routed traffic.
Adding a peer#
+ Peer on a tunnel card asks for six fields. A name and a public key are required; the button stays disabled without them.
| Field | Command |
|---|---|
| Peer name | the tag: … peer laptop … |
| Public key | set interfaces wireguard wg0 peer laptop public-key <key> |
| Allowed IPs | one set … allowed-ips <cidr> per comma-separated value |
| Endpoint address | set … peer laptop address <host> — leave blank for a roaming client |
| Endpoint port | set … peer laptop port <port> |
| Persistent keepalive | set … peer laptop persistent-keepalive 25 |
A road-warrior laptop, staged in full:
set interfaces wireguard wg0 peer laptop public-key <peer-public-key>
set interfaces wireguard wg0 peer laptop allowed-ips 10.10.0.2/32
set interfaces wireguard wg0 peer laptop persistent-keepalive 25The Allowed IPs hint is the sentence people most often need: this is the routing table for the tunnel. A prefix listed here is both what the peer may send from and what the router will route to it. The keepalive hint is the other one: 25 seconds for peers behind NAT.
What this page will not do#
- No handshake times and no transfer counters. The peer panel says so itself: those
need
wg showon the router, and the agent does not expose it. What you get is configuration, plus whether the router reports the interface at all (ui/src/pages/WireGuard.tsx). - No key generation.
run generate pki wireguard key-pairon the router, and paste. - No client configuration file or QR code. The peer's side is yours to write.
- No editing of an existing tunnel or peer. The panels create and delete. Changing a
peer's allowed prefixes means staging the
setyourself — from the Config tree, the console, or the API — or deleting the peer and adding it back. - No firewall rules. A WireGuard interface forwards nothing by itself: traffic out of the tunnel still meets the forward chain's default action. The catalogue entry puts that reminder on the Firewall page as an integration hint, and it is worth repeating here.
Making a tunnel useful#
Three things beyond the tunnel itself, each documented elsewhere:
- Let the peers in. The
inputchain has to accept UDP on the listen port from the uplink — see firewall rules. - Let their traffic through. The forward chain has to accept traffic in and out of the tunnel interface, or from the peers' prefixes.
- Give them a route back. The peer's
allowed-ipsis the routing table for the tunnel; anything not listed there is not routed to that peer.
See also#
- Firewall — rules — the two rules a tunnel needs.
- Worked rulesets — the shape of a permissive-inbound rule.
- Security, VPN and accounts — the rest of this section.
- Apps — the feature module that reveals this page.
- Interfaces — where a tunnel appears beside every other interface.
Checked against#
ui/src/pages/WireGuard.tsx,
ui/src/components/nav.ts,
ui/src/lib/api.ts,
agent/opmode.go,
agent/main.go,
agent/security.go,
agent/catalog.json.