Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions caddyconfig/httpcaddyfile/tlsapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -703,9 +703,11 @@ func consolidateAutomationPolicies(aps []*caddytls.AutomationPolicy) []*caddytls
emptyAP.SubjectsRaw = aps[i].SubjectsRaw
if reflect.DeepEqual(aps[i], emptyAP) {
emptyAPCount++
if !automationPolicyHasAllPublicNames(aps[i]) {
// if this automation policy has internal names, we might as well remove it
// so auto-https can implicitly use the internal issuer
if !automationPolicyHasAllPublicNames(aps[i]) ||
automationPolicyCoveredByWildcard(aps[i], aps[i+1:]) {
// remove this empty policy if it has internal names (so auto-https
// can implicitly use the internal issuer), or if every subject is
// covered by a later wildcard policy with managers (#7559)
aps = slices.Delete(aps, i, i+1)
i--
}
Expand Down Expand Up @@ -836,6 +838,36 @@ func automationPolicyHasAllPublicNames(ap *caddytls.AutomationPolicy) bool {
})
}

// automationPolicyCoveredByWildcard returns true if every subject in ap is
// covered by a wildcard subject in one of the later policies that has
// managers (get_certificate).
func automationPolicyCoveredByWildcard(ap *caddytls.AutomationPolicy, laterPolicies []*caddytls.AutomationPolicy) bool {
if len(ap.SubjectsRaw) == 0 {
return false
}
for _, subj := range ap.SubjectsRaw {
covered := false
for _, other := range laterPolicies {
if len(other.ManagersRaw) == 0 {
continue
}
for _, otherSubj := range other.SubjectsRaw {
if certmagic.MatchWildcard(subj, otherSubj) {
covered = true
break
}
}
if covered {
break
}
}
if !covered {
return false
}
}
return true
}

func isTailscaleDomain(name string) bool {
return strings.HasSuffix(strings.ToLower(name), ".ts.net")
}
39 changes: 39 additions & 0 deletions caddyconfig/httpcaddyfile/tlsapp_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package httpcaddyfile

import (
"encoding/json"
"testing"

"github.com/caddyserver/caddy/v2/modules/caddytls"
Expand Down Expand Up @@ -54,3 +55,41 @@ func TestAutomationPolicyIsSubset(t *testing.T) {
}
}
}

func TestConsolidateAutomationPoliciesWildcardManager(t *testing.T) {
httpManager := json.RawMessage(`{"via":"http"}`)

for i, test := range []struct {
policies []*caddytls.AutomationPolicy
expect int // expected number of policies after consolidation; -1 means nil
}{
{
// empty subdomain policy should be removed when covered by
// a wildcard policy with get_certificate (#7559)
policies: []*caddytls.AutomationPolicy{
{SubjectsRaw: []string{"foo.example.com"}},
{SubjectsRaw: []string{"*.example.com"}, ManagersRaw: []json.RawMessage{httpManager}},
},
expect: 1,
},
{
// empty policy with no wildcard coverage should be kept
policies: []*caddytls.AutomationPolicy{
{SubjectsRaw: []string{"example.com"}},
{SubjectsRaw: []string{"*.other.com"}, ManagersRaw: []json.RawMessage{httpManager}},
},
expect: 2,
},
} {
result := consolidateAutomationPolicies(test.policies)
var got int
if result == nil {
got = -1
} else {
got = len(result)
}
if got != test.expect {
t.Errorf("Test %d: Expected %d policies but got %d", i, test.expect, got)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
*.example.com {
tls {
get_certificate http http://localhost:9000/certs
}
respond "Wildcard"
}

foo.example.com {
respond "Foo"
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"foo.example.com"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "Foo",
"handler": "static_response"
}
]
}
]
}
],
"terminal": true
},
{
"match": [
{
"host": [
"*.example.com"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "Wildcard",
"handler": "static_response"
}
]
}
]
}
],
"terminal": true
}
]
}
}
},
"tls": {
"automation": {
"policies": [
{
"subjects": [
"*.example.com"
],
"get_certificate": [
{
"url": "http://localhost:9000/certs",
"via": "http"
}
]
}
]
}
}
}
}
Loading