From b6686a54d8b21bedbf042caa4a6c09d78d345fc7 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Thu, 22 Oct 2020 12:40:23 -0600 Subject: httpcaddyfile: Improve AP logic with OnDemand We have users that have site blocks like *.*.tld with on-demand TLS enabled. While *.*.tld does not qualify for a publicly-trusted cert due to its wildcards, On-Demand TLS does not actually obtain a cert with those wildcards, since it uses the actual hostname on the handshake. This improves on that logic, but I am still not 100% satisfied with the result since I think we need to also check if another site block is more specific, like foo.example.tld, which might not have on-demand TLS enabled, and make sure an automation policy gets created before the more general policy with on-demand... --- modules/caddytls/tls.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'modules/caddytls') diff --git a/modules/caddytls/tls.go b/modules/caddytls/tls.go index 6a635d4..12d25ad 100644 --- a/modules/caddytls/tls.go +++ b/modules/caddytls/tls.go @@ -334,10 +334,26 @@ func (t *TLS) AddAutomationPolicy(ap *AutomationPolicy) error { if err != nil { return err } - for i, other := range t.Automation.Policies { - // if a catch-all policy (or really, any policy with - // fewer names) exists, prioritize this new policy - if len(other.Subjects) < len(ap.Subjects) { + // sort new automation policies just before any other which is a superset + // of this one; if we find an existing policy that covers every subject in + // ap but less specifically (e.g. a catch-all policy, or one with wildcards + // or with fewer subjects), insert ap just before it, otherwise ap would + // never be used because the first matching policy is more general + for i, existing := range t.Automation.Policies { + // first see if existing is superset of ap for all names + var otherIsSuperset bool + outer: + for _, thisSubj := range ap.Subjects { + for _, otherSubj := range existing.Subjects { + if certmagic.MatchWildcard(thisSubj, otherSubj) { + otherIsSuperset = true + break outer + } + } + } + // if existing AP is a superset or if it contains fewer names (i.e. is + // more general), then new AP is more specific, so insert before it + if otherIsSuperset || len(existing.Subjects) < len(ap.Subjects) { t.Automation.Policies = append(t.Automation.Policies[:i], append([]*AutomationPolicy{ap}, t.Automation.Policies[i:]...)...) return nil -- cgit v1.2.3