fix(stream): bracket IPv6 forward host for valid nginx upstream

A Stream Host with an IPv6 address as the Forward Host was accepted and
saved but never activated. The generated stream config rendered
`proxy_pass {{ forwarding_host }}:{{ forwarding_port }}` as e.g.
`fe80::528:3c87:e7bb:ab08:25`, which nginx rejects with
"invalid port in upstream" because an IPv6 literal must be wrapped in
square brackets before the port is appended (`[fe80::...]:25`).

Normalize the stream forward host in generateConfig (alongside the existing
per-host-type data massaging) using net.isIPv6(), so IPv6 hosts render as
`[address]:port` while IPv4 addresses and hostnames are emitted unchanged.
The mutation is applied to the deep-copied render object, so persisted and
audit data are unaffected.

Fixes #5740
This commit is contained in:
addielarue
2026-07-25 22:55:58 +10:00
parent a62c2a6dc3
commit 9aa7fd5722
+9
View File
@@ -1,4 +1,5 @@
import fs from "node:fs";
import net from "node:net";
import { dirname } from "node:path";
import { fileURLToPath } from "node:url";
import _ from "lodash";
@@ -221,6 +222,14 @@ const internalNginx = {
host.forward_scheme = "$scheme";
}
// A stream forwarding to an IPv6 literal must have the address wrapped in
// square brackets before nginx appends ":<port>". Without the brackets nginx
// reads the trailing ":<port>" as part of the address and rejects the upstream
// ("invalid port in upstream"), so the stream saves but never activates (#5740).
if (nice_host_type === "stream" && net.isIPv6(host.forwarding_host)) {
host.forwarding_host = `[${host.forwarding_host}]`;
}
if (host.locations) {
//logger.info ('host.locations = ' + JSON.stringify(host.locations, null, 2));
origLocations = [].concat(host.locations);