From 5e2503ca5061666ce3238a78980d1ea9282a98c5 Mon Sep 17 00:00:00 2001 From: ryan Date: Mon, 16 Mar 2026 12:39:34 +0800 Subject: [PATCH] =?UTF-8?q?[=E4=BF=AE=E5=A4=8D]=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E9=85=8D=E7=BD=AE=E4=BB=A5=E6=94=AF=E6=8C=81?= =?UTF-8?q?=20SSL=20=E6=9C=8D=E5=8A=A1=E5=99=A8=E5=90=8D=E7=A7=B0=E5=92=8C?= =?UTF-8?q?=E4=B8=BB=E6=9C=BA=E5=A4=B4=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openflare_server/router/api_phase2_test.go | 6 +++++ openflare_server/service/config_version.go | 26 ++++++++++++++++--- openflare_server/service/https_phase1_test.go | 6 +++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/openflare_server/router/api_phase2_test.go b/openflare_server/router/api_phase2_test.go index 352e6ed3..278b8f88 100644 --- a/openflare_server/router/api_phase2_test.go +++ b/openflare_server/router/api_phase2_test.go @@ -427,6 +427,12 @@ func TestPhase2CustomHeadersPreviewAndDiffLifecycle(t *testing.T) { if !strings.Contains(renderedConfig, `proxy_set_header Host "preview-upstream.internal";`) { t.Fatalf("expected preview endpoint to return overridden host header, got %s", renderedConfig) } + if !strings.Contains(renderedConfig, "proxy_ssl_server_name on;") { + t.Fatalf("expected preview endpoint to enable proxy ssl server name, got %s", renderedConfig) + } + if !strings.Contains(renderedConfig, `proxy_ssl_name "preview-upstream.internal";`) { + t.Fatalf("expected preview endpoint to return proxy ssl name, got %s", renderedConfig) + } diffResp := performJSONRequest(t, engine, token, http.MethodGet, "/api/config-versions/diff", nil) var diff map[string]any diff --git a/openflare_server/service/config_version.go b/openflare_server/service/config_version.go index 75a68729..e917a992 100644 --- a/openflare_server/service/config_version.go +++ b/openflare_server/service/config_version.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "net/url" "openflare/common" "openflare/model" "sort" @@ -749,7 +750,7 @@ func nextVersionNumber(now time.Time) (string, error) { } func renderHTTPProxyServer(domain string, originURL string, originHost string, customHeaders []ProxyRouteCustomHeaderInput) string { - return fmt.Sprintf("server {\n listen 80;\n server_name %s;\n%s\n location / {\n%s proxy_pass %s;\n }\n}\n\n", domain, renderExactHostGuard(domain), renderProxyHeaderBlock(originHost, customHeaders), originURL) + return fmt.Sprintf("server {\n listen 80;\n server_name %s;\n%s\n location / {\n%s proxy_pass %s;\n }\n}\n\n", domain, renderExactHostGuard(domain), renderProxyHeaderBlock(originURL, originHost, customHeaders), originURL) } func renderHTTPRedirectServer(domain string) string { @@ -759,20 +760,24 @@ func renderHTTPRedirectServer(domain string) string { func renderHTTPSServer(domain string, originURL string, originHost string, certificateID uint, customHeaders []ProxyRouteCustomHeaderInput) string { certPath := fmt.Sprintf("%s/%s", nginxCertDirPlaceholder, certificateCertFileName(certificateID)) keyPath := fmt.Sprintf("%s/%s", nginxCertDirPlaceholder, certificateKeyFileName(certificateID)) - return fmt.Sprintf("server {\n listen 443 ssl;\n server_name %s;\n ssl_certificate %s;\n ssl_certificate_key %s;\n%s\n location / {\n%s proxy_pass %s;\n }\n}\n\n", domain, certPath, keyPath, renderExactHostGuard(domain), renderProxyHeaderBlock(originHost, customHeaders), originURL) + return fmt.Sprintf("server {\n listen 443 ssl;\n server_name %s;\n ssl_certificate %s;\n ssl_certificate_key %s;\n%s\n location / {\n%s proxy_pass %s;\n }\n}\n\n", domain, certPath, keyPath, renderExactHostGuard(domain), renderProxyHeaderBlock(originURL, originHost, customHeaders), originURL) } func renderExactHostGuard(domain string) string { return fmt.Sprintf(" if ($host != %q) {\n return 404;\n }\n", domain) } -func renderProxyHeaderBlock(originHost string, customHeaders []ProxyRouteCustomHeaderInput) string { +func renderProxyHeaderBlock(originURL string, originHost string, customHeaders []ProxyRouteCustomHeaderInput) string { var builder strings.Builder if strings.TrimSpace(originHost) != "" { builder.WriteString(fmt.Sprintf(" proxy_set_header Host %s;\n", quoteNginxHeaderValue(originHost))) } else { builder.WriteString(" proxy_set_header Host $host;\n") } + if upstreamServerName := resolveUpstreamServerName(originURL, originHost); upstreamServerName != "" { + builder.WriteString(" proxy_ssl_server_name on;\n") + builder.WriteString(fmt.Sprintf(" proxy_ssl_name %s;\n", quoteNginxHeaderValue(upstreamServerName))) + } builder.WriteString(" proxy_set_header X-Real-IP $remote_addr;\n") builder.WriteString(" proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n") builder.WriteString(" proxy_set_header X-Forwarded-Proto $scheme;\n") @@ -790,6 +795,21 @@ func renderProxyHeaderBlock(originHost string, customHeaders []ProxyRouteCustomH return builder.String() } +func resolveUpstreamServerName(originURL string, originHost string) string { + parsed, err := url.Parse(originURL) + if err != nil || !strings.EqualFold(parsed.Scheme, "https") { + return "" + } + if strings.TrimSpace(originHost) != "" { + parsedHost, err := url.Parse("//" + originHost) + if err == nil && parsedHost.Hostname() != "" { + return parsedHost.Hostname() + } + return originHost + } + return parsed.Hostname() +} + func quoteNginxHeaderValue(value string) string { escaped := strings.ReplaceAll(value, `\`, `\\`) escaped = strings.ReplaceAll(escaped, `"`, `\"`) diff --git a/openflare_server/service/https_phase1_test.go b/openflare_server/service/https_phase1_test.go index da82edb4..6e4f9528 100644 --- a/openflare_server/service/https_phase1_test.go +++ b/openflare_server/service/https_phase1_test.go @@ -160,6 +160,12 @@ func TestPublishConfigVersionOverridesOriginHostHeader(t *testing.T) { if !strings.Contains(result.Version.RenderedConfig, `proxy_set_header Host "git.arctel.net";`) { t.Fatal("expected rendered config to override host header for origin routing") } + if !strings.Contains(result.Version.RenderedConfig, "proxy_ssl_server_name on;") { + t.Fatal("expected rendered config to enable proxy ssl server name for https origin") + } + if !strings.Contains(result.Version.RenderedConfig, `proxy_ssl_name "git.arctel.net";`) { + t.Fatal("expected rendered config to set proxy ssl name from origin host override") + } if !strings.Contains(result.Version.SnapshotJSON, `"origin_host":"git.arctel.net"`) { t.Fatal("expected snapshot to include origin_host override") }