7 Commits
Author SHA1 Message Date
sysopsandClaude Sonnet 5 1539c589a1 Normalize AllocatedIPs/ExtraAllowedIPs to network address before ip route replace
A client CIDR with nonzero host bits (e.g. 10.66.120.1/30 instead of the
network 10.66.120.0/30) is tolerated by wg's own AllowedIPs/setconf, which
just warns, but plain iproute2 rejects it with "Invalid prefix for given
prefix length" and aborts the whole PostUp chain, taking the interface
down on start. Added a routeNet template func that clears host bits via
net.ParseCIDR before generating each PostUp route line.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ATVUwTa4Pqwq26orW5BcDW
2026-07-29 14:30:53 +02:00
sysopsandClaude Sonnet 5 388a8377cd Add per-server Interface/KeyPair edit hardening and OPNsense config import
Redact the private key from the /servers/:id/keypair response body -
the UI never rendered it, but the raw key was still returned over the
wire (json:"private_key,omitempty" plus explicit clearing before the
JSON response).

Add a new import flow: an admin can upload an OPNsense config.xml,
preview the WireGuard servers/clients it defines (editable before
committing), and confirm to create the corresponding
Server/ServerSetting/Client records. Nothing is auto-applied - no
wg-quick/systemctl call happens, matching the existing manual "Apply"
step for regular server management.

Schema verified against OPNsense core (WireGuard has been in core
since 22.1, not a plugin) - see opnsense/parse.go for the confirmed
tag reference. Public keys are always re-derived from private keys
rather than trusted from the export; client public-key collisions
against existing store data are skipped and reported per-batch rather
than aborting the whole import.

Since OPNsense stores DNS/MTU per-server and keepalive per-client, but
this fork only had those app-wide (GlobalSetting), extended
ServerSetting with DNSServers/MTU and Client with PersistentKeepalive
as optional overrides that fall back to the global default when unset
- existing single-server behavior is unchanged when the override is
empty/zero. Manual UI editing of the per-client keepalive override
outside the import flow is left for a later pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019VjwLYRA87o8m9a9zztgs3
2026-07-24 00:05:08 +02:00
sysopsandClaude Sonnet 5 0dbb916866 Fix nil-pointer crash generating QR codes for non-default servers
GetClients, GetClientByID, and SendRequestedConfigsToTelegram all
looked up the legacy "wg0" server unconditionally when building a
client's QR code / config, ignoring which server the client actually
belongs to. On any multi-server setup without a migrated wg0, the
server lookup returned a zero-value model.Server (error discarded),
and BuildClientConfig then dereferenced its nil KeyPair pointer,
panicking whenever a client's QR code was rendered.

Now looks up the client's own ServerID (falling back to wg0 only for
legacy clients with no ServerID set) and surfaces the lookup error
instead of silently continuing with an empty server.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 23:42:36 +02:00
sysopsandClaude Sonnet 5 fc0d192e59 Port upstream security fixes and features from ngoduykhanh/wireguard-ui
- Escape HTML in client list and wake-on-LAN names to prevent XSS
- Log successful/failed login attempts with remote address
- Fix leading-comma bug in AllowedIPs template when only extra allowed IPs are set
- Add PreUp script support for server interfaces (alongside existing PostUp/PreDown/PostDown)
- Fix endpoint parsing to support IPv6 addresses (upstream PR #223)

Cherry-picked from upstream PRs #656, #653, #680, #673, #223.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 23:26:30 +02:00
sysopsandClaude Sonnet 5 58db6839c3 Remove legacy default-server page, unify on multi-server registry
Deletes /wg-server (route, handlers, template) entirely and adds generic
/servers/:id/interface and /servers/:id/keypair endpoints + UI in the
All Servers page, so every server (including the default one) is managed
through the same per-server registry. Drops the write-through dual-write
hacks that kept the old single-server collection in sync - the registry
is now the single source of truth. One-time legacy-install migration path
is untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 16:27:17 +02:00
sysops 7eca2d01b8 Add server-registry store methods with record-ID validation (step 1)
New IStore methods for a per-server registry (GetServers, GetServerByID,
CreateServer, DeleteServer, GetServerSettings/SaveServerSettings,
GetServerHashes/SaveServerHashes), all additive - existing single-server
methods untouched. Adds util.ValidateRecordID/ValidateInterfaceName and
applies them to every new method taking a server ID, closing a path-
traversal gap before serverID is ever driven by user input (flagged by
a security review pass).
2026-07-11 22:39:53 +02:00
sysopsandClaude Sonnet 5 867dc7740a Replace from-scratch rewrite with real ngoduykhanh/wireguard-ui fork
The from-scratch Go rewrite had unresolved bugs (missing go.sum, UI
404s, path issues) from being built without a working local Go
toolchain to verify against. Switching strategy: use the actual
upstream wireguard-ui codebase (proven, battle-tested single-server
manager) as the base, and extend it for multi-server support instead
of re-deriving everything from zero.

Kept our own installers (bootstrap.sh, update.sh, scripts/install.sh,
scripts/proxmox-install.sh) - these still apply, just need updating
to build/install the upstream module layout instead of the old
cmd/wireguard-ui-multi structure.

Module path intentionally left as upstream's own
(github.com/ngoduykhanh/wireguard-ui) for now to avoid touching every
internal import; revisit if this needs to be fully rebranded.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-10 18:34:44 +02:00