Reads /etc/wireguard
Every *.conf is listed and edited in place. A comment above a peer (# Alice) is used as the display name.
MIT · Linux · Python 3.11+
Reads every *.conf in /etc/wireguard. Peers, Address, and PostUp stay in that file. Writes, then wg syncconf if the interface is up.
wg-quickPostUp / NATScope
Install on a host that already runs WireGuard. [Interface] keys, PostUp / PostDown, and existing peers stay in the file. You can edit those lines; wg-admin does not invent iptables. Peer apply is wg syncconf when the interface is up.
| Behaviour | wg-admin |
|---|---|
| Installs WireGuard | No |
Replaces wg-quick |
No |
Generates PostUp / NAT |
No — existing lines are editable in the UI |
Reads existing *.conf |
Yes — every file in /etc/wireguard |
| Apply while up | wg syncconf (no bounce) |
| Backup before write | /var/lib/wg-admin/backups/, restorable from the UI |
| Disable a peer | Commented out with # wg-admin:disabled; block stays in the file |
Features
/etc/wireguardEvery *.conf is listed and edited in place. A comment above a peer (# Alice) is used as the display name.
wg syncconfPeer changes write the file, then sync if the interface is up. Address and PostUp/PostDown apply on the next wg-quick up, or Restart from the UI.
[Interface]Edit Address, ListenPort, MTU, PostUp, and PostDown in place. PrivateKey stays hidden. No generated iptables.
Add, rename, edit, disable, rotate keys, remove. New peers get the next free IPv4. Disable comments the block out; it is not deleted.
Paste a public key the client already has. No client private key is generated or stored.
.conf / QRAvailable after create or rotate, when the private key is stored here. DNS, AllowedIPs, and endpoint can be overridden per peer.
wg statusLast handshake, transfer, and endpoint. Filter and sort.
A copy is stored under /var/lib/wg-admin/backups/ before each write. Restore from the UI; the current file is backed up first.
127.0.0.1Put Caddy or nginx with TLS in front if remote access is needed.
Screenshots
Every *.conf in /etc/wireguard is listed. Status comes from wg when the interface is up. Admin password is in the header.
Generate a keypair, or paste an existing public key. Next free IPv4 in the subnet is suggested. QR and .conf are shown after create if the private key is stored here.
Shown after create or rotate. Imported peers stay in the file; they have no private key on the server, so no QR.
Existing interface files are loaded as-is. Set an admin password before the UI is usable.
Workflow
See peers, last handshake, and transfer. Filter or sort when the list grows. Existing comments become display names.
Generate keys or paste an existing public key. The next free IPv4 is picked and the server file is written.
.conf / QRShown immediately when the private key is stored here. Per-peer DNS, AllowedIPs, and endpoint overrides do not change the interface defaults.
Disable comments the peer out without deleting the block. Restore a backup to undo a write. Restart runs wg-quick down/up so PostUp/PostDown apply.
Files
/etc/wireguard vs state.json.conf[Interface] keys: Address, ListenPort, PrivateKey, PostUp / PostDown, MTU, Table, DNS — editable in the Server panel, not generated[Peer] public keys, AllowedIPs, PSK, keepalive, endpoint# Alice or # Name = Alice) used as the display name/var/lib/wg-admin/state.json, overridable per peer/var/lib/wg-admin/backups/ before each write, restorable from the UI# wg-admin:disabled so wg-quick skips them tooInstall
Requires Python 3.11+, wireguard-tools (wg), and root — or equivalent access to /etc/wireguard and CAP_NET_ADMIN.
git clone https://github.com/logimaxx/wg-admin.git
cd wg-admin
sudo ./install.sh
Then open http://127.0.0.1:8080 and set an admin password. Every *.conf already in /etc/wireguard is listed and managed in place.
/etc/wg-admin.envWG_ADMIN_HOST=127.0.0.1
WG_ADMIN_PORT=8080
WG_ADMIN_CONFIG_DIR=/etc/wireguard
WG_ADMIN_STATE_DIR=/var/lib/wg-admin
Default WG_ADMIN_HOST=127.0.0.1. Put Caddy or nginx with TLS in front if remote access is needed. Uninstall leaves WireGuard configs untouched:
sudo ./uninstall.sh