Add per-server NAT egress, ip_forward auto-enable, OPNsense import review checklist

- ServerSetting gains WanInterface/EgressSNATIP for optional per-server
  masquerade/SNAT of client traffic, isolated in each server's own
  nftables table
- wireguard.Start/Restart now ensure net.ipv4.ip_forward and
  net.ipv6.conf.all.forwarding are enabled before bringing an interface up
- OPNsense config.xml import now parses staticroutes/filter/nat rules and
  surfaces them as a manual-review checklist in the preview UI (never
  auto-applied)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ATVUwTa4Pqwq26orW5BcDW
This commit is contained in:
sysops
2026-07-29 13:08:52 +02:00
co-authored by Claude Sonnet 5
parent cf9c136874
commit 83b1da291f
7 changed files with 1132 additions and 5 deletions
+942
View File
@@ -2519,3 +2519,945 @@ Keine Commits in dieser Session.
- wireguard/service.go | 88 +++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-25 00:36 00:42 (6m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- 34bc8f7 Add per-user TOTP 2FA, client-level user assignment, self-service portal
### Geänderte Dateien
- DEVLOG.md | 80 +++++++++++++++++++++++++++++++++++++++++
- auth/totp.go | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- auth/totp_test.go | 85 ++++++++++++++++++++++++++++++++++++++++++++
- handler/routes.go | 297 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
- handler/routes_my_access.go | 263 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- main.go | 8 +++++
- model/user.go | 10 ++++++
- templates/base.html | 8 +++++
- templates/login.html | 53 ++++++++++++++++++++++++++-
- templates/my_access.html | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- templates/profile.html | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- templates/users_settings.html | 46 +++++++++++++++++++++++-
---
## 2026-07-25 00:59 00:59 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- DEVLOG.md | 80 +++++++++++++++++++++++++++++++++++++++++
- auth/totp.go | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- auth/totp_test.go | 85 ++++++++++++++++++++++++++++++++++++++++++++
- handler/routes.go | 297 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
- handler/routes_my_access.go | 263 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- main.go | 8 +++++
- model/user.go | 10 ++++++
- templates/base.html | 8 +++++
- templates/login.html | 53 ++++++++++++++++++++++++++-
- templates/my_access.html | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- templates/profile.html | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- templates/users_settings.html | 46 +++++++++++++++++++++++-
---
## 2026-07-25 01:59 02:00 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- DEVLOG.md | 80 +++++++++++++++++++++++++++++++++++++++++
- auth/totp.go | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- auth/totp_test.go | 85 ++++++++++++++++++++++++++++++++++++++++++++
- handler/routes.go | 297 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
- handler/routes_my_access.go | 263 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- main.go | 8 +++++
- model/user.go | 10 ++++++
- templates/base.html | 8 +++++
- templates/login.html | 53 ++++++++++++++++++++++++++-
- templates/my_access.html | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- templates/profile.html | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- templates/users_settings.html | 46 +++++++++++++++++++++++-
---
## 2026-07-25 11:24 11:24 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- DEVLOG.md | 80 ++++++++++++
- auth/totp.go | 148 +++++++++++++++++++++
- auth/totp_test.go | 85 ++++++++++++
- handler/routes.go | 297 +++++++++++++++++++++++++++++++++++++-----
- handler/routes_my_access.go | 263 +++++++++++++++++++++++++++++++++++++
- main.go | 8 ++
- model/user.go | 10 ++
- templates/base.html | 8 ++
- templates/login.html | 53 +++++++-
- templates/my_access.html | 122 +++++++++++++++++
- templates/profile.html | 129 ++++++++++++++++++
- templates/users_settings.html | 46 ++++++-
---
## 2026-07-25 11:25 11:26 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- DEVLOG.md | 80 ++++++++++++
- auth/totp.go | 148 +++++++++++++++++++++
- auth/totp_test.go | 85 ++++++++++++
- handler/routes.go | 297 +++++++++++++++++++++++++++++++++++++-----
- handler/routes_my_access.go | 263 +++++++++++++++++++++++++++++++++++++
- main.go | 8 ++
- model/user.go | 10 ++
- templates/base.html | 8 ++
- templates/login.html | 53 +++++++-
- templates/my_access.html | 122 +++++++++++++++++
- templates/profile.html | 129 ++++++++++++++++++
- templates/users_settings.html | 46 ++++++-
---
## 2026-07-25 11:27 11:28 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- 9de83d7 Fix 500 error on /my-access by registering missing template
### Geänderte Dateien
- router/router.go | 6 ++++++
---
## 2026-07-25 11:32 11:34 (2m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- router/router.go | 6 ++++++
---
## 2026-07-25 11:51 11:51 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- router/router.go | 6 ++++++
---
## 2026-07-25 11:53 11:54 (1m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- router/router.go | 6 ++++++
---
## 2026-07-25 11:56 11:58 (1m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- d585d53 Write server config before starting WireGuard interface
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++-----------------------
- main.go | 2 +-
---
## 2026-07-25 12:01 12:01 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++-----------------------
- main.go | 2 +-
---
## 2026-07-25 12:11 12:11 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++-----------------------
- main.go | 2 +-
---
## 2026-07-25 12:12 12:12 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++-----------------------
- main.go | 2 +-
---
## 2026-07-25 12:20 12:23 (2m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++-----------------------
- main.go | 2 +-
---
## 2026-07-25 12:24 12:25 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 12:25 12:25 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 12:35 12:36 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 12:37 12:37 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 12:38 12:39 (1m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 12:48 12:49 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 13:00 13:02 (2m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 13:04 13:05 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 13:08 13:08 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 13:12 13:12 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 13:22 13:22 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 13:35 13:35 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 13:44 13:44 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 13:46 13:48 (1m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 14:05 14:06 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 15:10 15:10 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 15:24 15:24 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 15:26 15:27 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 15:30 15:30 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 15:32 15:32 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 15:33 15:34 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 15:34 15:35 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++------------------------
- main.go | 2 +-
---
## 2026-07-25 15:43 15:44 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 15:53 15:53 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 15:55 15:55 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 16:04 17:42 (1h 38m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 17:44 17:44 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 17:45 17:46 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 17:46 17:47 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 17:48 17:48 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 17:52 17:53 (1m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 18:05 18:05 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 18:05 18:05 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 18:12 18:12 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 18:20 18:21 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 18:27 18:27 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 18:30 18:31 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 18:33 18:34 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 ++++++++++++++++++++++++++++++++++++++++++++++----------------------------------
- main.go | 2 +-
---
## 2026-07-25 18:47 18:47 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 18:49 18:49 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 18:49 18:50 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 19:19 19:19 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 19:26 19:26 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 19:28 19:28 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 19:30 19:30 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 19:33 19:33 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 19:35 19:35 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 19:36 19:37 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 19:37 19:37 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 19:38 19:38 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 19:39 19:40 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 19:48 19:49 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 103 +++++++++++++++++++++++++++++++++++++++-----------------------------
- main.go | 2 +-
---
## 2026-07-25 19:50 19:54 (3m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- cf9c136 Replace wg-quick route management with idempotent PostUp routes
### Geänderte Dateien
- handler/routes.go | 9 ++++++++-
- main.go | 2 +-
- templates/wg.conf | 12 ++++++++++--
---
## 2026-07-25 19:55 19:56 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 9 ++++++++-
- main.go | 2 +-
- templates/wg.conf | 12 ++++++++++--
---
## 2026-07-25 19:56 19:57 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 9 ++++++++-
- main.go | 2 +-
- templates/wg.conf | 12 ++++++++++--
---
## 2026-07-29 12:08 12:47 (38m)
**Beschreibung:** Claude Code Session
**Projekt:** spesenapp
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 9 ++++++++-
- main.go | 2 +-
- templates/wg.conf | 12 ++++++++++--
---
## 2026-07-29 12:48 12:49 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 9 ++++++++-
- main.go | 2 +-
- templates/wg.conf | 12 ++++++++++--
---
## 2026-07-29 12:49 12:50 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 9 ++++++++-
- main.go | 2 +-
- templates/wg.conf | 12 ++++++++++--
---
## 2026-07-29 12:51 12:53 (1m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 9 ++++++++-
- main.go | 2 +-
- templates/wg.conf | 12 ++++++++++--
---
## 2026-07-29 12:53 12:56 (2m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 9 ++++++++-
- main.go | 2 +-
- templates/wg.conf | 12 ++++++++++--
---
+12
View File
@@ -90,6 +90,18 @@ func GenerateRuleset(server model.Server, settings model.ServerSetting, rules []
fmt.Fprintf(&b, "%s\n", line)
}
fmt.Fprintf(&b, " }\n")
if settings.WanInterface != "" {
fmt.Fprintf(&b, "\n chain postrouting {\n")
fmt.Fprintf(&b, " type nat hook postrouting priority 100; policy accept;\n")
if settings.EgressSNATIP != "" {
fmt.Fprintf(&b, " iifname \"%s\" oifname \"%s\" snat to %s comment \"wg-ui-multi: %s egress\"\n", ifaceName, settings.WanInterface, settings.EgressSNATIP, server.ID)
} else {
fmt.Fprintf(&b, " iifname \"%s\" oifname \"%s\" masquerade comment \"wg-ui-multi: %s egress\"\n", ifaceName, settings.WanInterface, server.ID)
}
fmt.Fprintf(&b, " }\n")
}
fmt.Fprintf(&b, "}\n")
return b.String()
+10
View File
@@ -29,6 +29,16 @@ type ServerSetting struct {
// Only used to generate the nftables ruleset preview; left empty means
// the preview only covers the WireGuard interface itself.
LanInterface string `json:"lan_interface,omitempty"`
// WanInterface is optional: the local interface this server's client
// traffic should be masqueraded/SNATed out through for full-tunnel
// (internet-egress) clients, e.g. "eth0". Leave empty to skip NAT
// entirely (site-to-site only, no internet egress via this server).
WanInterface string `json:"wan_interface,omitempty"`
// EgressSNATIP is optional: pins the source address used when NATing
// this server's client traffic out WanInterface, for hosts with
// multiple public IPs on the same interface. Leave empty to use
// plain masquerade (follow the interface's routed address).
EgressSNATIP string `json:"egress_snat_ip,omitempty"`
// DNSServers and MTU are optional per-server overrides of the app-wide
// GlobalSetting.DNSServers/GlobalSetting.MTU. Leave empty/zero to fall
// back to the global default (see handler.buildEffectiveSettings).
+55
View File
@@ -50,11 +50,24 @@ type PreviewServer struct {
Warnings []string `json:"warnings,omitempty"`
}
// ReviewChecklistItem is one manual-review entry surfaced from parts of
// config.xml that wireguard-ui-multi does not import or model at all
// (static routes, firewall rules, outbound NAT). These are never applied -
// they exist purely so the admin knows what else the old OPNsense config
// was doing and can recreate the equivalent manually (e.g. via
// ServerSetting.WanInterface/EgressSNATIP or a custom FirewallRule) before
// cutover, instead of discovering the gap after go-live.
type ReviewChecklistItem struct {
Kind string `json:"kind"` // "static_route" | "filter_rule" | "nat_rule"
Description string `json:"description"`
}
// PreviewResult is the full response of the preview step: every server
// OPNsense defined, mapped and ready for the admin to review/edit before
// confirming the import. It is never written to the store by itself.
type PreviewResult struct {
Servers []PreviewServer `json:"servers"`
ReviewChecklist []ReviewChecklistItem `json:"review_checklist,omitempty"`
}
var slugInvalidChars = regexp.MustCompile(`[^a-zA-Z0-9_-]+`)
@@ -210,9 +223,51 @@ func ToPreview(cfg *ParsedConfig, existingServerIDs []string) *PreviewResult {
result.Servers = append(result.Servers, ps)
}
result.ReviewChecklist = buildReviewChecklist(cfg)
return result
}
// buildReviewChecklist summarizes static routes, firewall rules, and
// outbound NAT rules found in the source config.xml that wireguard-ui-multi
// has no equivalent import path for. Purely informational.
func buildReviewChecklist(cfg *ParsedConfig) []ReviewChecklistItem {
var items []ReviewChecklistItem
for _, r := range cfg.StaticRoutes {
desc := fmt.Sprintf("route %s via %s", r.Network, r.Gateway)
if r.Descr != "" {
desc += fmt.Sprintf(" (%s)", r.Descr)
}
items = append(items, ReviewChecklistItem{Kind: "static_route", Description: desc})
}
for _, r := range cfg.FilterRules {
desc := fmt.Sprintf("%s rule on %s: %s -> %s", orDefault(r.Type, "pass"), r.Interface, orDefault(r.Source.Network, "any"), orDefault(r.Destination.Network, "any"))
if r.Descr != "" {
desc += fmt.Sprintf(" (%s)", r.Descr)
}
items = append(items, ReviewChecklistItem{Kind: "filter_rule", Description: desc})
}
for _, r := range cfg.NatRules {
desc := fmt.Sprintf("outbound NAT on %s: %s -> %s", r.Interface, orDefault(r.Source.Network, "any"), orDefault(r.Target, "interface address"))
if r.Descr != "" {
desc += fmt.Sprintf(" (%s)", r.Descr)
}
items = append(items, ReviewChecklistItem{Kind: "nat_rule", Description: desc})
}
return items
}
func orDefault(s, fallback string) string {
if strings.TrimSpace(s) == "" {
return fallback
}
return s
}
func mapClient(rc rawClient) PreviewClient {
pc := PreviewClient{
SourceUUID: rc.UUID,
+53
View File
@@ -60,6 +60,53 @@ type rawConfig struct {
} `xml:"general"`
} `xml:"wireguard"`
} `xml:"OPNsense"`
StaticRoutes struct {
Route []rawStaticRoute `xml:"route"`
} `xml:"staticroutes"`
Filter struct {
Rule []rawFilterRule `xml:"rule"`
} `xml:"filter"`
Nat struct {
Outbound struct {
Mode string `xml:"mode"`
Rule []rawNatRule `xml:"rule"`
} `xml:"outbound"`
} `xml:"nat"`
}
// rawStaticRoute mirrors <staticroutes><route> - a manually configured
// route not otherwise expressible via WireGuard's own tunneladdress/peers
// fields. Surfaced as a review item only; never auto-applied.
type rawStaticRoute struct {
Network string `xml:"network"`
Gateway string `xml:"gateway"`
Descr string `xml:"descr"`
}
// rawFilterRule mirrors <filter><rule> - a firewall rule. Only the fields
// needed to flag rules that reference a WireGuard interface are captured.
type rawFilterRule struct {
Type string `xml:"type"`
Interface string `xml:"interface"`
Descr string `xml:"descr"`
Source struct {
Network string `xml:"network"`
} `xml:"source"`
Destination struct {
Network string `xml:"network"`
} `xml:"destination"`
}
// rawNatRule mirrors <nat><outbound><rule> - a manual outbound NAT/SNAT
// rule. Surfaced as a review item so the admin can recreate the
// equivalent via ServerSetting.WanInterface/EgressSNATIP if needed.
type rawNatRule struct {
Interface string `xml:"interface"`
Source struct {
Network string `xml:"network"`
} `xml:"source"`
Target string `xml:"target"`
Descr string `xml:"descr"`
}
type rawServer struct {
@@ -96,6 +143,9 @@ type rawClient struct {
type ParsedConfig struct {
Servers []rawServer
Clients []rawClient
StaticRoutes []rawStaticRoute
FilterRules []rawFilterRule
NatRules []rawNatRule
}
// Parse reads an OPNsense config.xml document and extracts the WireGuard
@@ -116,6 +166,9 @@ func Parse(r io.Reader) (*ParsedConfig, error) {
return &ParsedConfig{
Servers: cfg.Ns.Wireguard.Server.Servers.Server,
Clients: cfg.Ns.Wireguard.Client.Clients.Client,
StaticRoutes: cfg.StaticRoutes.Route,
FilterRules: cfg.Filter.Rule,
NatRules: cfg.Nat.Outbound.Rule,
}, nil
}
+31
View File
@@ -142,6 +142,16 @@ All Servers
<input type="text" class="form-control" id="_settings_lan_interface" placeholder="e.g. eth0, br-lan">
<small class="form-text text-muted">Optional. Used only for the Firewall Preview - lets peers forward to this interface.</small>
</div>
<div class="form-group">
<label for="_settings_wan_interface" class="control-label">WAN Interface (egress)</label>
<input type="text" class="form-control" id="_settings_wan_interface" placeholder="e.g. eth0">
<small class="form-text text-muted">Optional. Set for full-tunnel/internet-egress clients - NATs this server's client traffic out this interface. Leave empty for site-to-site only (no NAT).</small>
</div>
<div class="form-group">
<label for="_settings_egress_snat_ip" class="control-label">Egress SNAT IP</label>
<input type="text" class="form-control" id="_settings_egress_snat_ip" placeholder="e.g. 203.0.113.5">
<small class="form-text text-muted">Optional. Only needed on multi-IP hosts to pin the source address; leave empty to use plain masquerade.</small>
</div>
<div class="form-group">
<label for="_settings_dns_servers" class="control-label">DNS Servers (override)</label>
<input type="text" class="form-control" id="_settings_dns_servers"
@@ -695,6 +705,8 @@ All Servers
modal.find("#_settings_firewall_mark").val("");
modal.find("#_settings_table").val("");
modal.find("#_settings_lan_interface").val("");
modal.find("#_settings_wan_interface").val("");
modal.find("#_settings_egress_snat_ip").val("");
modal.find("#_settings_dns_servers").val("");
modal.find("#_settings_mtu").val("");
@@ -710,6 +722,8 @@ All Servers
modal.find("#_settings_firewall_mark").val(settings.firewall_mark);
modal.find("#_settings_table").val(settings.table);
modal.find("#_settings_lan_interface").val(settings.lan_interface);
modal.find("#_settings_wan_interface").val(settings.wan_interface);
modal.find("#_settings_egress_snat_ip").val(settings.egress_snat_ip);
modal.find("#_settings_dns_servers").val((settings.dns_servers || []).join(", "));
modal.find("#_settings_mtu").val(settings.mtu || "");
},
@@ -733,6 +747,8 @@ All Servers
"firewall_mark": $("#_settings_firewall_mark").val(),
"table": $("#_settings_table").val(),
"lan_interface": $("#_settings_lan_interface").val(),
"wan_interface": $("#_settings_wan_interface").val(),
"egress_snat_ip": $("#_settings_egress_snat_ip").val(),
"dns_servers": dnsServers,
"mtu": parseInt($("#_settings_mtu").val(), 10) || 0
};
@@ -1099,6 +1115,21 @@ All Servers
area.append(html);
});
if (preview.review_checklist && preview.review_checklist.length) {
const kindLabels = {static_route: "Static route", filter_rule: "Firewall rule", nat_rule: "Outbound NAT"};
let checklistHtml = '<div class="card mb-3 border-warning"><div class="card-header py-1 bg-warning">' +
'<strong>Manual review needed - not imported</strong></div>' +
'<div class="card-body py-2"><p class="text-muted mb-2">' +
'These items existed in the OPNsense config.xml but have no equivalent import path. ' +
'Recreate them manually (e.g. via the WAN Interface/Egress SNAT IP server settings or a custom firewall rule) before cutover.</p>' +
'<ul class="mb-0">';
$.each(preview.review_checklist, function (i, item) {
checklistHtml += '<li><strong>' + (kindLabels[item.kind] || item.kind) + ':</strong> ' + item.description + '</li>';
});
checklistHtml += '</ul></div></div>';
area.append(checklistHtml);
}
$("#btn_opnsense_confirm").show();
}
+24
View File
@@ -3,7 +3,9 @@ package wireguard
import (
"context"
"fmt"
"os"
"os/exec"
"strings"
"github.com/ngoduykhanh/wireguard-ui/util"
)
@@ -17,6 +19,7 @@ func UnitName(iface string) string {
// Start brings up the given WireGuard interface via
// `systemctl start wg-quick@<iface>.service`.
func Start(ctx context.Context, iface string) error {
EnsureIPForwarding()
return runSystemctl(ctx, "start", iface)
}
@@ -29,9 +32,30 @@ func Stop(ctx context.Context, iface string) error {
// Restart restarts the given WireGuard interface via
// `systemctl restart wg-quick@<iface>.service`.
func Restart(ctx context.Context, iface string) error {
EnsureIPForwarding()
return runSystemctl(ctx, "restart", iface)
}
// EnsureIPForwarding turns on IPv4/IPv6 forwarding for the running kernel
// (equivalent to `sysctl -w net.ipv4.ip_forward=1`), best-effort. Without
// this, any server relying on FORWARD rules or NAT egress silently drops
// all forwarded traffic. Persistence across reboots (e.g.
// /etc/sysctl.d/*.conf) is left to install-time setup, not this runtime
// call - this only guarantees the currently running kernel is correct
// whenever a server is (re)started.
func EnsureIPForwarding() {
setSysctl("/proc/sys/net/ipv4/ip_forward")
setSysctl("/proc/sys/net/ipv6/conf/all/forwarding")
}
func setSysctl(path string) {
data, err := os.ReadFile(path)
if err == nil && strings.TrimSpace(string(data)) == "1" {
return
}
_ = os.WriteFile(path, []byte("1"), 0644)
}
func runSystemctl(ctx context.Context, action, iface string) error {
if !util.ValidateInterfaceName(iface) {
return fmt.Errorf("invalid interface name: %q", iface)