feat(service): add --tls-extra-host for additional TLS cert SAN entries

The leaf cert generator already routes IP-shaped entries into the
IPAddresses SAN, and getDomains already feeds it the hostnames parsed
from --server-url and --https-server-url. Add an explicit
--tls-extra-host flag (repeatable, env TLS_EXTRA_HOST) for the
remaining cases: multi-homed hosts, reverse-proxy frontends, or
browsing the admin UI via a LAN IP that isn't part of the configured
server URLs.

Resolves the ERR_CERT_COMMON_NAME_INVALID Chrome refuses when the URL
bar hostname (e.g. the host's LAN IP) isn't in any cert SAN, even
when the local CA is trusted.
This commit is contained in:
Tobias Gesellchen
2026-05-18 23:09:28 +02:00
parent e1d009de04
commit 68760a8977
+20 -3
View File
@@ -342,6 +342,11 @@ func main() {
Usage: "Paths for internal requests (comma-separated or multiple flags)",
EnvVars: []string{"INTERNAL_PATHS"},
},
&cli.StringSliceFlag{
Name: "tls-extra-host",
Usage: "Additional DNS name or IP to include in the server TLS certificate SAN list (repeatable)",
EnvVars: []string{"TLS_EXTRA_HOST"},
},
&cli.BoolFlag{
Name: "migration-enabled",
Usage: "Enable device directory migration from serial to MAC-based structure",
@@ -382,7 +387,7 @@ func main() {
hostname = "localhost"
}
config.domains = getDomains(config.serverURL, config.httpsServerURL, hostname)
config.domains = getDomains(config.serverURL, config.httpsServerURL, hostname, config.tlsExtraHosts)
cm := initCertificateManager(config.dataDir, config.hostname)
sm := setup.NewManager(config.serverURL, ds, cm)
@@ -534,6 +539,7 @@ type serviceConfig struct {
dnsUpstream string
dnsBind string
internalPaths []string
tlsExtraHosts []string
discoveryEnabled bool
discoveryInterval time.Duration
domains []string
@@ -590,7 +596,8 @@ func loadConfig(c *cli.Context) serviceConfig {
httpsServerURL = "https://" + hostname + ":" + httpsPort
}
domains := getDomains(serverURL, httpsServerURL, hostname)
tlsExtraHosts := c.StringSlice("tls-extra-host")
domains := getDomains(serverURL, httpsServerURL, hostname, tlsExtraHosts)
redact := c.Bool("redact-logs")
logBody := c.Bool("log-bodies")
@@ -644,6 +651,7 @@ func loadConfig(c *cli.Context) serviceConfig {
dnsUpstream: dnsUpstream,
dnsBind: dnsBind,
internalPaths: internalPaths,
tlsExtraHosts: tlsExtraHosts,
discoveryEnabled: discoveryEnabled,
discoveryInterval: discoveryInterval,
domains: domains,
@@ -666,7 +674,7 @@ func loadConfig(c *cli.Context) serviceConfig {
}
}
func getDomains(serverURL, httpsServerURL, hostname string) []string {
func getDomains(serverURL, httpsServerURL, hostname string, extraHosts []string) []string {
domainsMap := map[string]bool{
// RFC-compliant wildcards for API patterns
"*.api.bose.io": true,
@@ -699,6 +707,15 @@ func getDomains(serverURL, httpsServerURL, hostname string) []string {
domainsMap[strings.ToLower(u.Hostname())] = true
}
// Explicit overrides / additions for multi-homed hosts, reverse proxies,
// or browsing the admin UI via a LAN IP that isn't part of serverURL.
for _, h := range extraHosts {
h = strings.ToLower(strings.TrimSpace(h))
if h != "" {
domainsMap[h] = true
}
}
domains := make([]string, 0, len(domainsMap))
for d := range domainsMap {
domains = append(domains, d)