Secret URL path for the panel
The panel port is open to the internet, and its login page and JS bundle gave it away to any scanner in one GET. The installer now generates a random UI_PREFIX: from outside the panel answers only under http://IP:PORT/<prefix>/ and gives Go's plain "404 page not found" to everything else. Loopback needs no prefix (CLI, local Prometheus, nginx on the same host); while a move code is out, POST /migrate/v1/import is let through without it, since the code carries no path. A reinstall with kept data keeps the prefix; UI_PREFIX=off or a custom value can be set before running the installer. A moved panel brings its prefix in UI_PREFIX_MOVED, so old bookmarks and API clients keep working through the relay. awg-ctrl status and credentials show the full panel address. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013bNGYiDst62wH3ZGTRPFLJ
This commit is contained in:
@@ -165,6 +165,9 @@ func New() *CLI {
|
||||
name: "ui", label: "awg-ui", cwd: filepath.Join(c.root, "awg-ui"), legacy: "server.ts",
|
||||
env: [][2]string{
|
||||
{"PORT", env("UI_PORT", "8080")},
|
||||
// Секретный путь панели; _MOVED — путь панели, переехавшей сюда (принимаются оба).
|
||||
{"UI_PREFIX", env("UI_PREFIX", "")},
|
||||
{"UI_PREFIX_MOVED", env("UI_PREFIX_MOVED", "")},
|
||||
{"AWGCTRL_PORT", env("AWGCTRL_PORT", "3005")},
|
||||
{"INTERNAL_AUTH_KEY_FILE", env("INTERNAL_AUTH_KEY_FILE", "/etc/amnezia/amneziawg/internal_auth_private.key")},
|
||||
{"BRAND", c.brand}, {"CHANNEL", c.channel}, {"VERSION", c.version},
|
||||
@@ -477,11 +480,33 @@ func (c *CLI) serviceLine(name string, menu bool) string {
|
||||
return fmt.Sprintf(" %s %-12s %s", dot, c.svc[name].label, info)
|
||||
}
|
||||
|
||||
// panelURL — адрес панели с секретным путём; без UI_PORT (нода) — пусто.
|
||||
func panelURL() string {
|
||||
port := env("UI_PORT", "")
|
||||
if port == "" {
|
||||
return ""
|
||||
}
|
||||
host := env("SUB_HOST", env("SERVER_IP", "IP"))
|
||||
if strings.Contains(host, ":") {
|
||||
host = "[" + host + "]"
|
||||
}
|
||||
u := "http://" + host + ":" + port + "/"
|
||||
if p := env("UI_PREFIX", ""); p != "" {
|
||||
u += p + "/"
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
func (c *CLI) status() {
|
||||
fmt.Println()
|
||||
for _, n := range c.all {
|
||||
fmt.Println(c.serviceLine(n, false))
|
||||
}
|
||||
if contains(c.all, "ui") {
|
||||
if u := panelURL(); u != "" {
|
||||
fmt.Println(" " + dim("Панель "+u))
|
||||
}
|
||||
}
|
||||
if c.isRunning("awgctrl") {
|
||||
h := fetchHealth("http://127.0.0.1:" + c.envOf("awgctrl") + "/health")
|
||||
if gen, ok := get(h, "gen").(string); ok && gen != "" {
|
||||
|
||||
Reference in New Issue
Block a user