From 9ffae221ac73978feb0b2bbcedc508eb77cb6d7c Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Wed, 22 Jul 2026 12:59:05 +0100 Subject: [PATCH] fix: Fixed server install scripts --- deploy/docker-compose.yml | 5 --- server/cmd/main.go | 7 ++++ server/internal/api/handlers.go | 18 ++--------- server/internal/api/install_ps1.go | 7 +--- server/internal/api/publichost.go | 51 ++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 26 deletions(-) create mode 100644 server/internal/api/publichost.go diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index f4594d7..94b938a 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -27,14 +27,9 @@ services: MONGO_URI: ${MONGO_URI:-} REDIS_ADDR: redis:6379 GITEA_HOST: ${GITEA_HOST} - PUBLIC_HOST: ${PUBLIC_HOST} GRPC_HOST: ${GRPC_HOST} GRPC_PORT: "9090" HTTP_PORT: "8080" - OIDC_ISSUER: ${OIDC_ISSUER:-} - OIDC_CLIENT_ID: ${OIDC_CLIENT_ID:-} - OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET:-} - OIDC_REDIRECT_URL: ${OIDC_REDIRECT_URL:-} KEY_ENCRYPTION_KEY: ${KEY_ENCRYPTION_KEY:-} VANTAGE_WORKFLOW_LOG_DIR: ${VANTAGE_WORKFLOW_LOG_DIR:-} GUACD_ADDR: guacd:4822 diff --git a/server/cmd/main.go b/server/cmd/main.go index 4e203bd..85fc665 100644 --- a/server/cmd/main.go +++ b/server/cmd/main.go @@ -19,6 +19,13 @@ func main() { mongoURI := getEnv("MONGO_URI", "mongodb://localhost:27017") dbName := getEnv("MONGO_DB", "vantage") + // Agents dial gRPC directly, so there is no sane default: falling back to the + // public web host would hand every new agent a config pointing at a port that + // does not speak gRPC. Fail loudly at boot instead of at install time. + if os.Getenv("GRPC_HOST") == "" { + log.Fatal("GRPC_HOST is required (host:port agents dial for gRPC)") + } + if err := db.Connect(mongoURI, dbName); err != nil { log.Fatalf("failed to connect to MongoDB: %v", err) } diff --git a/server/internal/api/handlers.go b/server/internal/api/handlers.go index a49ba40..3dd7164 100644 --- a/server/internal/api/handlers.go +++ b/server/internal/api/handlers.go @@ -137,10 +137,8 @@ func newServer(c *gin.Context) { if giteaHost == "" { giteaHost = "gitea.example.com" } - host := os.Getenv("PUBLIC_HOST") - if host == "" { - host = "https://vantage.example.com" - } + + host := publicHostFromRequest(c) installCmd := fmt.Sprintf( `curl -fsSL "%s/install?server_id=%s&token=%s" | bash`, @@ -494,14 +492,7 @@ func handleInstallScript(c *gin.Context) { if giteaHost == "" { giteaHost = "gitea.example.com" } - publicHost := os.Getenv("PUBLIC_HOST") - if publicHost == "" { - publicHost = "vantage.example.com" - } grpcHost := os.Getenv("GRPC_HOST") - if grpcHost == "" { - grpcHost = publicHost - } script := fmt.Sprintf(`#!/usr/bin/env bash set -euo pipefail @@ -509,9 +500,6 @@ set -euo pipefail SERVER_ID="%s" TOKEN="%s" GITEA_HOST="%s" -KM_HOST="%s" -KM_HOST="${KM_HOST#https://}" -KM_HOST="${KM_HOST#http://}" GRPC_HOST="%s" GRPC_HOST="${GRPC_HOST#https://}" GRPC_HOST="${GRPC_HOST#http://}" @@ -584,7 +572,7 @@ systemctl daemon-reload systemctl enable --now vantage-agent echo "vantage-agent installed and started." -`, serverID, token, giteaHost, publicHost, grpcHost) +`, serverID, token, giteaHost, grpcHost) c.Header("Content-Type", "text/x-shellscript") c.String(http.StatusOK, script) diff --git a/server/internal/api/install_ps1.go b/server/internal/api/install_ps1.go index 485e551..154e1b1 100644 --- a/server/internal/api/install_ps1.go +++ b/server/internal/api/install_ps1.go @@ -16,13 +16,8 @@ func handleInstallScriptWindows(c *gin.Context) { if giteaHost == "" { giteaHost = "gitea.example.com" } + // Guaranteed non-empty: main() fatals at boot if GRPC_HOST is unset. grpcHost := os.Getenv("GRPC_HOST") - if grpcHost == "" { - grpcHost = os.Getenv("PUBLIC_HOST") - } - if grpcHost == "" { - grpcHost = "vantage.example.com" - } script := fmt.Sprintf( "#Requires -RunAsAdministrator\n"+ diff --git a/server/internal/api/publichost.go b/server/internal/api/publichost.go new file mode 100644 index 0000000..c4a2f3c --- /dev/null +++ b/server/internal/api/publichost.go @@ -0,0 +1,51 @@ +package api + +import ( + "net" + "strings" + + "github.com/gin-gonic/gin" +) + +func publicHostFromRequest(c *gin.Context) string { + host := c.Request.Host + if h := firstForwarded(c.GetHeader("X-Forwarded-Host")); h != "" { + host = h + } + if host == "" { + return "https://vantage.example.com" + } + return schemeFor(c, host) + "://" + host +} + +func schemeFor(c *gin.Context, host string) string { + if p := firstForwarded(c.GetHeader("X-Forwarded-Proto")); p != "" { + return p + } + if c.Request.TLS != nil { + return "https" + } + if isLoopback(host) { + return "http" + } + return "https" +} + +func firstForwarded(v string) string { + if v == "" { + return "" + } + return strings.TrimSpace(strings.Split(v, ",")[0]) +} + +func isLoopback(host string) bool { + h, _, err := net.SplitHostPort(host) + if err != nil { + h = host + } + if h == "localhost" || strings.HasSuffix(h, ".localhost") { + return true + } + ip := net.ParseIP(h) + return ip != nil && ip.IsLoopback() +}