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>
This commit is contained in:
sysops
2026-07-12 23:26:30 +02:00
co-authored by Claude Sonnet 5
parent 5a7709bc6e
commit fc0d192e59
15 changed files with 640 additions and 30 deletions
+526
View File
@@ -1593,3 +1593,529 @@ Keine Commits in dieser Session.
- templates/servers.html | 4 ++--
---
## 2026-07-12 16:27 16:27 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- 58db683 Remove legacy default-server page, unify on multi-server registry
### Geänderte Dateien
- DEVLOG.md | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- handler/routes.go | 108 ++++++++++++++++++----------------------------------
- main.go | 7 ++--
- router/router.go | 6 ---
- store/jsondb/jsondb.go | 57 +++++-----------------------
- store/store.go | 3 --
- templates/base.html | 10 -----
- templates/server.html | 255 --------------------------------------------------------------------------------------------------------------------------
- templates/servers.html | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- util/util.go | 4 +-
---
## 2026-07-12 16:28 16:29 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- DEVLOG.md | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- handler/routes.go | 108 ++++++++++++++++++----------------------------------
- main.go | 7 ++--
- router/router.go | 6 ---
- store/jsondb/jsondb.go | 57 +++++-----------------------
- store/store.go | 3 --
- templates/base.html | 10 -----
- templates/server.html | 255 --------------------------------------------------------------------------------------------------------------------------
- templates/servers.html | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- util/util.go | 4 +-
---
## 2026-07-12 16:31 16:31 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- DEVLOG.md | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- handler/routes.go | 108 ++++++++++++++++++----------------------------------
- main.go | 7 ++--
- router/router.go | 6 ---
- store/jsondb/jsondb.go | 57 +++++-----------------------
- store/store.go | 3 --
- templates/base.html | 10 -----
- templates/server.html | 255 --------------------------------------------------------------------------------------------------------------------------
- templates/servers.html | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- util/util.go | 4 +-
---
## 2026-07-12 16:31 16:32 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- 9c90e3f Rewrite About page for the fork, drop upstream GitHub API calls
### Geänderte Dateien
- templates/about.html | 104 +++++++-------------------------------------------------------------------------------------------------
---
## 2026-07-12 16:32 16:33 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- templates/about.html | 104 +++++++-------------------------------------------------------------------------------------------------
---
## 2026-07-12 16:34 16:35 (1m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- templates/about.html | 104 +++++++-------------------------------------------------------------------------------------------------
---
## 2026-07-12 16:36 16:38 (2m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- 0000643 Add missing server delete: handler, route, and UI button
### Geänderte Dateien
- handler/routes.go | 13 +++++++++++++
- main.go | 1 +
- templates/servers.html | 31 +++++++++++++++++++++++++++++++
---
## 2026-07-12 16:39 16:39 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 13 +++++++++++++
- main.go | 1 +
- templates/servers.html | 31 +++++++++++++++++++++++++++++++
---
## 2026-07-12 16:41 16:51 (9m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 13 +++++++++++++
- main.go | 1 +
- templates/servers.html | 31 +++++++++++++++++++++++++++++++
---
## 2026-07-12 16:52 16:52 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- 28eb08d Add nftables firewall ruleset preview per server (review-only)
### Geänderte Dateien
- firewall/nftables.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- handler/routes.go | 18 ++++++++++++++++++
- main.go | 1 +
- model/setting.go | 7 ++++++-
- templates/servers.html | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
---
## 2026-07-12 16:57 17:31 (33m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- 1d08090 Add live firewall rule management per server (nftables)
### Geänderte Dateien
- firewall/apply.go | 44 ++++++++++++++++++++++++++++++
- firewall/nftables.go | 76 +++++++++++++++++++++++++++++++++++++++-------------
- handler/routes.go | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
- main.go | 5 ++++
- model/firewall.go | 21 +++++++++++++++
- store/jsondb/jsondb.go | 59 +++++++++++++++++++++++++++++++++++++++++
- store/store.go | 4 +++
- templates/servers.html | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
---
## 2026-07-12 17:33 17:35 (2m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- bdcf1ec Add read-only OS package update status (apt) on the About page
### Geänderte Dateien
- handler/routes.go | 9 +++++++++
- main.go | 1 +
- system/updates.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- templates/about.html | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 17:36 17:36 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 9 +++++++++
- main.go | 1 +
- system/updates.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- templates/about.html | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 17:36 17:36 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- handler/routes.go | 9 +++++++++
- main.go | 1 +
- system/updates.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- templates/about.html | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 17:40 17:45 (5m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- eb1913d Add central host-wide firewall allow/block lists
### Geänderte Dateien
- firewall/apply.go | 28 ++++++++++++------
- firewall/global.go | 63 ++++++++++++++++++++++++++++++++++++++++
- handler/routes.go | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- main.go | 6 ++++
- model/iplist.go | 15 ++++++++++
- router/router.go | 6 ++++
- store/jsondb/jsondb.go | 30 +++++++++++++++++++
- store/store.go | 3 ++
- templates/base.html | 8 +++++
- templates/firewall_lists.html | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 17:47 17:48 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- firewall/apply.go | 28 ++++++++++++------
- firewall/global.go | 63 ++++++++++++++++++++++++++++++++++++++++
- handler/routes.go | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- main.go | 6 ++++
- model/iplist.go | 15 ++++++++++
- router/router.go | 6 ++++
- store/jsondb/jsondb.go | 30 +++++++++++++++++++
- store/store.go | 3 ++
- templates/base.html | 8 +++++
- templates/firewall_lists.html | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 17:49 17:51 (1m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- 77ba2b4 Add bulk import for global firewall allow/block lists
### Geänderte Dateien
- handler/routes.go | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- main.go | 1 +
- templates/firewall_lists.html | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 17:52 17:55 (3m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- 0f92317 Fix "no such file or directory" on first use of new collections
### Geänderte Dateien
- store/jsondb/jsondb.go | 17 ++++++++++++++---
---
## 2026-07-12 19:58 19:59 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- store/jsondb/jsondb.go | 17 ++++++++++++++---
---
## 2026-07-12 20:01 20:02 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- a9649f6 Add .gitignore for private/ - local-only files never pushed to gitea
### Geänderte Dateien
- .gitignore | 4 ++++
---
## 2026-07-12 20:03 20:13 (9m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- .gitignore | 4 ++++
---
## 2026-07-12 20:14 20:15 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- .gitignore | 4 ++++
---
## 2026-07-12 20:16 20:16 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- .gitignore | 4 ++++
---
## 2026-07-12 20:18 20:34 (15m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- .gitignore | 4 ++++
---
## 2026-07-12 20:36 20:38 (2m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- .gitignore | 4 ++++
---
## 2026-07-12 20:38 20:44 (5m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- 00d084a Fix nftables auto-merge syntax and block private/reserved ranges
### Geänderte Dateien
- firewall/global.go | 4 ++--
- handler/routes.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 20:45 20:45 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- firewall/global.go | 4 ++--
- handler/routes.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 20:48 20:52 (3m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
- 5a7709b Add enable/disable toggle for the global firewall allow/block lists
### Geänderte Dateien
- firewall/apply.go | 20 ++++++++++++++++++++
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
- main.go | 2 ++
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 23:00 23:00 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- firewall/apply.go | 20 ++++++++++++++++++++
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
- main.go | 2 ++
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 23:00 23:01 (1m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- firewall/apply.go | 20 ++++++++++++++++++++
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
- main.go | 2 ++
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 23:02 23:02 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- firewall/apply.go | 20 ++++++++++++++++++++
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
- main.go | 2 ++
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 23:03 23:04 (1m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- firewall/apply.go | 20 ++++++++++++++++++++
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
- main.go | 2 ++
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 23:05 23:06 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- firewall/apply.go | 20 ++++++++++++++++++++
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
- main.go | 2 ++
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 23:14 23:14 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- firewall/apply.go | 20 +++++++++++++
- handler/routes.go | 32 +++++++++++++++++++++
- main.go | 2 ++
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 23:15 23:15 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- firewall/apply.go | 20 +++++++++++++
- handler/routes.go | 32 +++++++++++++++++++++
- main.go | 2 ++
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 23:17 23:21 (4m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- firewall/apply.go | 20 ++++++++++++++++++++
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
- main.go | 2 ++
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 23:22 23:22 (0m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- firewall/apply.go | 20 ++++++++++++++++++++
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
- main.go | 2 ++
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
## 2026-07-12 23:24 23:26 (1m)
**Beschreibung:** Claude Code Session
**Projekt:** wireguard-ui-multi
### Commits
Keine Commits in dieser Session.
### Geänderte Dateien
- firewall/apply.go | 20 ++++++++++++++++++++
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
- main.go | 2 ++
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---
+1
View File
@@ -0,0 +1 @@
0.9.0
+23 -15
View File
@@ -1,3 +1,11 @@
/*
Hack using jQuery's text() method and a temporary element to escape html()
utilizing jQuery.
*/
function escapeHtml(unsafe) {
return $('<div/>').text(unsafe).html();
}
function renderClientList(data) {
$.each(data, function(index, obj) {
// render telegram button
@@ -6,13 +14,13 @@ function renderClientList(data) {
telegramButton = `<div class="btn-group">
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
data-target="#modal_telegram_client" data-clientid="${obj.Client.id}"
data-clientname="${obj.Client.name}">Telegram</button>
data-clientname="${escapeHtml(obj.Client.name)}">Telegram</button>
</div>`
}
let telegramHtml = "";
if (obj.Client.telegram_userid && obj.Client.telegram_userid.length > 0) {
telegramHtml = `<span class="info-box-text" style="display: none"><i class="fas fa-tguserid"></i>${obj.Client.telegram_userid}</span>`
telegramHtml = `<span class="info-box-text" style="display: none"><i class="fas fa-tguserid"></i>${escapeHtml(obj.Client.telegram_userid)}</span>`
}
// render client status css tag style
@@ -24,13 +32,13 @@ function renderClientList(data) {
// render client allocated ip addresses
let allocatedIpsHtml = "";
$.each(obj.Client.allocated_ips, function(index, obj) {
allocatedIpsHtml += `<small class="badge badge-secondary">${obj}</small>&nbsp;`;
allocatedIpsHtml += `<small class="badge badge-secondary">${escapeHtml(obj)}</small>&nbsp;`;
})
// render client allowed ip addresses
let allowedIpsHtml = "";
$.each(obj.Client.allowed_ips, function(index, obj) {
allowedIpsHtml += `<small class="badge badge-secondary">${obj}</small>&nbsp;`;
allowedIpsHtml += `<small class="badge badge-secondary">${escapeHtml(obj)}</small>&nbsp;`;
})
let subnetRangesString = "";
@@ -40,7 +48,7 @@ function renderClientList(data) {
let additionalNotesHtml = "";
if (obj.Client.additional_notes && obj.Client.additional_notes.length > 0) {
additionalNotesHtml = `<span class="info-box-text" style="display: none"><i class="fas fa-additional_notes"></i>${obj.Client.additional_notes.toUpperCase()}</span>`
additionalNotesHtml = `<span class="info-box-text" style="display: none"><i class="fas fa-additional_notes"></i>${escapeHtml(obj.Client.additional_notes.toUpperCase())}</span>`
}
// render client html content
@@ -56,12 +64,12 @@ function renderClientList(data) {
<div class="btn-group">
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
data-target="#modal_qr_client" data-clientid="${obj.Client.id}"
data-clientname="${obj.Client.name}" ${obj.QRCode != "" ? '' : ' disabled'}>QR code</button>
data-clientname="${escapeHtml(obj.Client.name)}" ${obj.QRCode != "" ? '' : ' disabled'}>QR code</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
data-target="#modal_email_client" data-clientid="${obj.Client.id}"
data-clientname="${obj.Client.name}">Email</button>
data-clientname="${escapeHtml(obj.Client.name)}">Email</button>
</div>
${telegramButton}
<div class="btn-group">
@@ -72,22 +80,22 @@ function renderClientList(data) {
<div class="dropdown-menu" role="menu">
<a class="dropdown-item" href="#" data-toggle="modal"
data-target="#modal_edit_client" data-clientid="${obj.Client.id}"
data-clientname="${obj.Client.name}">Edit</a>
data-clientname="${escapeHtml(obj.Client.name)}">Edit</a>
<a class="dropdown-item" href="#" data-toggle="modal"
data-target="#modal_pause_client" data-clientid="${obj.Client.id}"
data-clientname="${obj.Client.name}">Disable</a>
data-clientname="${escapeHtml(obj.Client.name)}">Disable</a>
<a class="dropdown-item" href="#" data-toggle="modal"
data-target="#modal_remove_client" data-clientid="${obj.Client.id}"
data-clientname="${obj.Client.name}">Delete</a>
data-clientname="${escapeHtml(obj.Client.name)}">Delete</a>
</div>
</div>
<hr>
<span class="info-box-text"><i class="fas fa-user"></i> ${obj.Client.name}</span>
<span class="info-box-text" style="display: none"><i class="fas fa-key"></i> ${obj.Client.public_key}</span>
<span class="info-box-text" style="display: none"><i class="fas fa-subnetrange"></i>${subnetRangesString}</span>
<span class="info-box-text"><i class="fas fa-user"></i> ${escapeHtml(obj.Client.name)}</span>
<span class="info-box-text" style="display: none"><i class="fas fa-key"></i> ${escapeHtml(obj.Client.public_key)}</span>
<span class="info-box-text" style="display: none"><i class="fas fa-subnetrange"></i>${escapeHtml(subnetRangesString)}</span>
${telegramHtml}
${additionalNotesHtml}
<span class="info-box-text"><i class="fas fa-envelope"></i> ${obj.Client.email}</span>
<span class="info-box-text"><i class="fas fa-envelope"></i> ${escapeHtml(obj.Client.email)}</span>
<span class="info-box-text"><i class="fas fa-clock"></i>
${prettyDateTime(obj.Client.created_at)}</span>
<span class="info-box-text"><i class="fas fa-history"></i>
@@ -95,7 +103,7 @@ function renderClientList(data) {
<span class="info-box-text"><i class="fas fa-server" style="${obj.Client.use_server_dns ? "opacity: 1.0" : "opacity: 0.5"}"></i>
${obj.Client.use_server_dns ? 'DNS enabled' : 'DNS disabled'}</span>
<span class="info-box-text"><i class="fas fa-file"></i>
${obj.Client.additional_notes}</span>
${escapeHtml(obj.Client.additional_notes)}</span>
<span class="info-box-text"><strong>IP Allocation</strong></span>`
+ allocatedIpsHtml
+ `<span class="info-box-text"><strong>Allowed IPs</strong></span>`
+2
View File
@@ -22,6 +22,8 @@ require (
gopkg.in/go-playground/validator.v9 v9.31.0
)
require github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
require (
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
+2
View File
@@ -1,5 +1,7 @@
github.com/NicoNex/echotron/v3 v3.27.0 h1:iq4BLPO+Dz1JHjh2HPk0D0NldAZSYcAjaOicgYEhUzw=
github.com/NicoNex/echotron/v3 v3.27.0/go.mod h1:LpP5IyHw0y+DZUZMBgXEDAF9O8feXrQu7w7nlJzzoZI=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/coreos/bbolt v1.3.1-coreos.6.0.20180223184059-4f5275f4ebbf/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+3 -1
View File
@@ -106,7 +106,7 @@ func Login(db store.IStore) echo.HandlerFunc {
dbuser, err := db.GetUserByName(username)
if err != nil {
log.Infof("Cannot query user %s from DB", username)
log.Warnf("Invalid credentials. Cannot query user %s from DB (%s)", username, c.Request().RemoteAddr)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Invalid credentials"})
}
@@ -161,9 +161,11 @@ func Login(db store.IStore) echo.HandlerFunc {
cookie.SameSite = http.SameSiteLaxMode
c.SetCookie(cookie)
log.Infof("Logged in successfully user %s (%s)", username, c.Request().RemoteAddr)
return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Logged in successfully"})
}
log.Warnf("Invalid credentials user %s (%s)", username, c.Request().RemoteAddr)
return c.JSON(http.StatusUnauthorized, jsonHTTPResponse{false, "Invalid credentials"})
}
}
+6 -1
View File
@@ -27,7 +27,7 @@ import (
var (
// command-line banner information
appVersion = "development"
appVersion = strings.TrimSpace(embeddedVersion)
gitCommit = "N/A"
gitRef = "N/A"
buildTime = fmt.Sprintf(time.Now().UTC().Format("01-02-2006 15:04:05"))
@@ -74,6 +74,11 @@ var embeddedTemplates embed.FS
//go:embed assets/*
var embeddedAssets embed.FS
// embed the VERSION file
//
//go:embed VERSION
var embeddedVersion string
func init() {
// command-line flags and env variables
flag.BoolVar(&flagDisableLogin, "disable-login", util.LookupEnvOrBool("DISABLE_LOGIN", flagDisableLogin), "Disable authentication on the app. This is potentially dangerous.")
+1
View File
@@ -25,6 +25,7 @@ type ServerInterface struct {
Addresses []string `json:"addresses"`
ListenPort int `json:"listen_port,string"` // ,string to get listen_port string input as int
UpdatedAt time.Time `json:"updated_at"`
PreUp string `json:"pre_up"`
PostUp string `json:"post_up"`
PreDown string `json:"pre_down"`
PostDown string `json:"post_down"`
+2
View File
@@ -2,6 +2,7 @@ package router
import (
"errors"
"html"
"io"
"io/fs"
"reflect"
@@ -124,6 +125,7 @@ func New(tmplDir fs.FS, extraData map[string]interface{}, secret [64]byte) *echo
// create template list
funcs := template.FuncMap{
"StringsJoin": strings.Join,
"attrescaper": html.EscapeString,
}
templates := make(map[string]*template.Template)
templates["login.html"] = template.Must(template.New("login").Funcs(funcs).Parse(tmplLoginString))
+2
View File
@@ -70,7 +70,9 @@ func (o *JsonDB) Init() error {
serverInterface := new(model.ServerInterface)
serverInterface.Addresses = util.LookupEnvOrStrings(util.ServerAddressesEnvVar, []string{util.DefaultServerAddress})
serverInterface.ListenPort = util.LookupEnvOrInt(util.ServerListenPortEnvVar, util.DefaultServerPort)
serverInterface.PreUp = util.LookupEnvOrString(util.ServerPreUpScriptEnvVar, "")
serverInterface.PostUp = util.LookupEnvOrString(util.ServerPostUpScriptEnvVar, "")
serverInterface.PreDown = util.LookupEnvOrString(util.ServerPreDownScriptEnvVar, "")
serverInterface.PostDown = util.LookupEnvOrString(util.ServerPostDownScriptEnvVar, "")
serverInterface.UpdatedAt = time.Now().UTC()
o.conn.Write("server", "interfaces", serverInterface)
+6
View File
@@ -143,6 +143,10 @@ All Servers
<input type="text" class="form-control" id="_iface_listen_port" name="_iface_listen_port"
placeholder="e.g. 51822">
</div>
<div class="form-group">
<label for="_iface_pre_up" class="control-label">Pre Up Script</label>
<input type="text" class="form-control" id="_iface_pre_up" placeholder="Pre Up Script">
</div>
<div class="form-group">
<label for="_iface_post_up" class="control-label">Post Up Script</label>
<input type="text" class="form-control" id="_iface_post_up" placeholder="Post Up Script">
@@ -439,6 +443,7 @@ All Servers
modal.find("#_iface_server_id").val(serverId);
modal.find("#_iface_addresses").val((obj.Interface && obj.Interface.addresses) ? obj.Interface.addresses.join(", ") : "");
modal.find("#_iface_listen_port").val(obj.Interface ? obj.Interface.listen_port : "");
modal.find("#_iface_pre_up").val(obj.Interface ? obj.Interface.pre_up : "");
modal.find("#_iface_post_up").val(obj.Interface ? obj.Interface.post_up : "");
modal.find("#_iface_pre_down").val(obj.Interface ? obj.Interface.pre_down : "");
modal.find("#_iface_post_down").val(obj.Interface ? obj.Interface.post_down : "");
@@ -455,6 +460,7 @@ All Servers
const data = {
"addresses": addresses,
"listen_port": $("#_iface_listen_port").val(),
"pre_up": $("#_iface_pre_up").val(),
"post_up": $("#_iface_post_up").val(),
"pre_down": $("#_iface_pre_down").val(),
"post_down": $("#_iface_post_down").val()
+2 -2
View File
@@ -90,7 +90,7 @@
<button type="button"
class="btn btn-outline-primary btn-sm btn_modify_wake_on_lan_host"
data-toggle="modal" data-target="#modal_wake_on_lan_host"
data-name="{{ .Name }}" data-mac-address="{{ .MacAddress }}">Edit
data-name="{{ .Name | attrescaper }}" data-mac-address="{{ .MacAddress }}">Edit
</button>
<button type="button" class="btn btn-outline-danger btn-sm" data-toggle="modal"
data-target="#modal_remove_wake_on_lan_host"
@@ -98,7 +98,7 @@
</button>
</div>
<hr>
<span class="info-box-text"><i class="fas fa-address-card"></i> <span class="name">{{ .Name }}</span></span>
<span class="info-box-text"><i class="fas fa-address-card"></i> <span class="name">{{ .Name | attrescaper }}</span></span>
<span class="info-box-text"><i class="fas fa-ethernet"></i> <span class="mac-address">{{ .MacAddress }}</span></span>
<span class="info-box-text"><i class="fas fa-clock"></i>
<span class="latest-used">
+9 -1
View File
@@ -8,6 +8,7 @@ Address = {{$first :=true}}{{range .serverConfig.Interface.Addresses }}{{if $fir
ListenPort = {{ .serverConfig.Interface.ListenPort }}
PrivateKey = {{ .serverConfig.KeyPair.PrivateKey }}
{{if .globalSettings.MTU}}MTU = {{ .globalSettings.MTU }}{{end}}
PreUp = {{ .serverConfig.Interface.PreUp }}
PostUp = {{ .serverConfig.Interface.PostUp }}
PreDown = {{ .serverConfig.Interface.PreDown }}
PostDown = {{ .serverConfig.Interface.PostDown }}
@@ -27,7 +28,14 @@ Table = {{ .globalSettings.Table }}
[Peer]
PublicKey = {{ .Client.PublicKey }}
{{if .Client.PresharedKey}}PresharedKey = {{ .Client.PresharedKey }}{{end}}
AllowedIPs = {{$first :=true}}{{range .Client.AllocatedIPs }}{{if $first}}{{$first = false}}{{else}},{{end}}{{.}}{{end}}{{range .Client.ExtraAllowedIPs }},{{.}}{{end}}
AllowedIPs = {{ $first := true }}
{{- range .Client.AllocatedIPs -}}
{{- if not $first}}, {{ end -}}{{ . -}}{{ $first = false -}}
{{- end -}}
{{- range .Client.ExtraAllowedIPs -}}
{{- if not $first}}, {{ end -}}{{ . -}}{{ $first = false -}}
{{- end }}
{{"\n"}}
{{if $.globalSettings.PersistentKeepalive}}PersistentKeepalive = {{ $.globalSettings.PersistentKeepalive }}{{end}}
{{if .Client.Endpoint}}Endpoint = {{ .Client.Endpoint }}{{end}}
{{end}}{{end}}
+2
View File
@@ -62,7 +62,9 @@ const (
LogLevel = "WGUI_LOG_LEVEL"
ServerAddressesEnvVar = "WGUI_SERVER_INTERFACE_ADDRESSES"
ServerListenPortEnvVar = "WGUI_SERVER_LISTEN_PORT"
ServerPreUpScriptEnvVar = "WGUI_SERVER_PRE_UP_SCRIPT"
ServerPostUpScriptEnvVar = "WGUI_SERVER_POST_UP_SCRIPT"
ServerPreDownScriptEnvVar = "WGUI_SERVER_PRE_DOWN_SCRIPT"
ServerPostDownScriptEnvVar = "WGUI_SERVER_POST_DOWN_SCRIPT"
DefaultClientAllowedIpsEnvVar = "WGUI_DEFAULT_CLIENT_ALLOWED_IPS"
DefaultClientExtraAllowedIpsEnvVar = "WGUI_DEFAULT_CLIENT_EXTRA_ALLOWED_IPS"
+52 -9
View File
@@ -21,6 +21,7 @@ import (
"text/template"
"time"
"github.com/asaskevich/govalidator"
"github.com/ngoduykhanh/wireguard-ui/store"
"github.com/ngoduykhanh/wireguard-ui/telegram"
"github.com/skip2/go-qrcode"
@@ -61,17 +62,10 @@ func BuildClientConfig(client model.Client, server model.Server, setting model.G
peerAllowedIPs := fmt.Sprintf("AllowedIPs = %s\n", strings.Join(client.AllowedIPs, ","))
desiredHost := setting.EndpointAddress
desiredPort := server.Interface.ListenPort
if strings.Contains(desiredHost, ":") {
split := strings.Split(desiredHost, ":")
desiredHost = split[0]
if n, err := strconv.Atoi(split[1]); err == nil {
desiredPort = n
} else {
desiredHost, desiredPort, err := ParseEndpoint(setting.EndpointAddress, server.Interface.ListenPort)
if err != nil {
log.Error("Endpoint appears to be incorrectly formatted: ", err)
}
}
peerEndpoint := fmt.Sprintf("Endpoint = %s:%d\n", desiredHost, desiredPort)
peerPersistentKeepalive := ""
@@ -900,3 +894,52 @@ func GetCookiePath() string {
}
return cookiePath
}
func RemoveIPv6Brackets(host string) string {
ipv6 := host
if matchBrackets, _ := regexp.MatchString(`^\[.*\]$`, ipv6); matchBrackets {
ipv6 = strings.Replace(ipv6, "[", "", -1)
ipv6 = strings.Replace(ipv6, "]", "", -1)
// only remove brackets if valid ipv6 address
if govalidator.IsIPv6(ipv6) {
return ipv6
}
}
return host
}
func AddIPv6Brackets(host string) string {
ipv6 := host
// only add brackets if valid ipv6 address
if govalidator.IsIPv6(ipv6) {
ipv6 = "[" + ipv6 + "]"
return ipv6
}
return host
}
func ParseEndpoint(host string, defaultPort int) (string, int, error) {
port := defaultPort
// remove brackets from standalone IPv6 address
host = RemoveIPv6Brackets(host)
if govalidator.IsIPv4(host) || govalidator.IsIPv6(host) || govalidator.IsDNSName(host) {
return AddIPv6Brackets(host), port, nil
}
// check if specific port contained
host, strPort, err := net.SplitHostPort(host)
if err != nil {
return "", -1, errors.New("invalid Host")
}
port, err = strconv.Atoi(strPort)
if err != nil || port > 65535 || port < 0 {
return "", -1, errors.New("invalid Port")
}
return AddIPv6Brackets(host), port, nil
}