From bbf0f60e2de7063211ecc8dc0d76e9de7ea6b1c9 Mon Sep 17 00:00:00 2001 From: Kenneth Jenkins <51246568+kenjenkins@users.noreply.github.com> Date: Tue, 22 Jul 2025 09:28:33 -0700 Subject: [PATCH] autocert: exclude non-https routes (#5733) Exclude non-https routes from the domains eligible for autocert. --- internal/autocert/manager.go | 22 ++++++++++++++++++++-- internal/autocert/manager_test.go | 25 ++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/internal/autocert/manager.go b/internal/autocert/manager.go index 1da2ed3b1..cd8a05263 100644 --- a/internal/autocert/manager.go +++ b/internal/autocert/manager.go @@ -496,8 +496,8 @@ func sourceHostnames(cfg *config.Config) []string { dedupe := map[string]struct{}{} for p := range cfg.Options.GetAllPolicies() { - if u, _ := urlutil.ParseAndValidateURL(p.From); u != nil && !strings.Contains(u.Host, "*") { - dedupe[u.Hostname()] = struct{}{} + if h := eligibleHostname(p); h != "" { + dedupe[h] = struct{}{} } } if cfg.Options.AuthenticateURLString != "" { @@ -520,6 +520,24 @@ func sourceHostnames(cfg *config.Config) []string { return h } +var eligibleSchemes = map[string]struct{}{ + "https": {}, + "tcp+https": {}, + "udp+https": {}, +} + +// eligibleHostname accepts a route and returns the hostname, if eligible for use +// with autocert, or the empty string if not. +func eligibleHostname(p *config.Policy) string { + u, _ := urlutil.ParseAndValidateURL(p.From) + if u == nil || strings.Contains(u.Host, "*") { + return "" + } else if _, ok := eligibleSchemes[u.Scheme]; !ok { + return "" + } + return u.Hostname() +} + func shouldEnableHTTPChallenge(cfg *config.Config) bool { if cfg == nil || cfg.Options == nil { return false diff --git a/internal/autocert/manager_test.go b/internal/autocert/manager_test.go index 8c562f62f..40518ad92 100644 --- a/internal/autocert/manager_test.go +++ b/internal/autocert/manager_test.go @@ -231,7 +231,7 @@ func TestConfig(t *testing.T) { require.NoError(t, err) p1 := config.Policy{ - From: "http://from.example.com", To: to, + From: "https://from.example.com", To: to, } _ = p1.Validate() @@ -631,6 +631,29 @@ func Test_configureTrustedRoots(t *testing.T) { } } +func Test_sourceHostnames(t *testing.T) { + t.Parallel() + + cfg := &config.Config{ + Options: config.NewDefaultOptions(), + } + cfg.Options.Policies = []config.Policy{ + {From: "https://foo.example.com"}, + {From: "http://non-https-route.example.com"}, + {From: "https://bar.example.com:5443"}, + {From: "ssh://ssh-hostname"}, + {From: "tcp+https://baz.example.com:1234"}, + {From: "udp+https://quux.example.com:5678"}, + } + + assert.ElementsMatch(t, []string{ + "foo.example.com", + "bar.example.com", + "baz.example.com", + "quux.example.com", + }, sourceHostnames(cfg)) +} + func TestShouldEnableHTTPChallenge(t *testing.T) { t.Parallel()