Skip to content

Commit

Permalink
fix(certificates): check all alternative domains when discovering certs
Browse files Browse the repository at this point in the history
  • Loading branch information
LCaparelli committed May 10, 2024
1 parent 968aada commit 3969cc5
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 47 deletions.
44 changes: 26 additions & 18 deletions internal/certificate/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ var (

// Service handle the certificate actions as discovery
type Service interface {
DiscoverByHost(string) (Certificate, error)
DiscoverByHost([]string) (Certificate, error)
}

// NewService creates a new Certificate Service
Expand All @@ -44,10 +44,10 @@ type acmCertService struct {
repo Repository
}

// DiscoverByHost tries to discover a certificate given a host
func (a acmCertService) DiscoverByHost(host string) (Certificate, error) {
// DiscoverByHost tries to discover a certificate given hosts
func (a acmCertService) DiscoverByHost(hosts []string) (Certificate, error) {

certs, err := a.repo.FindByFilter(matchingDomainFilter(host))
certs, err := a.repo.FindByFilter(matchingDomainFilter(hosts))

if err != nil {
return Certificate{}, fmt.Errorf("discovery certificate: %v", err)
Expand All @@ -60,25 +60,33 @@ func (a acmCertService) DiscoverByHost(host string) (Certificate, error) {
return certs[0], nil
}

func matchingDomainFilter(host string) CertFilter {
func matchingDomainFilter(hosts []string) CertFilter {
return func(c Certificate) bool {
if host == c.DomainName() {
return true
for _, host := range hosts {
if !certMatches(host, c) {
return false
}
}
return true
}
}

for _, alterName := range c.AlternativeNames() {
hs := strings.Split(host, ".")
hostDomain := strings.Join(hs[1:], ".")

if strings.HasPrefix(alterName, "*.") {
alterName = strings.ReplaceAll(alterName, "*.", "")
}
func certMatches(distHost string, c Certificate) bool {
for _, certHost := range append(c.AlternativeNames(), c.DomainName()) {
if distHost == certHost {
return true
}
hs := strings.Split(distHost, ".")
hostDomain := strings.Join(hs[1:], ".")

if alterName == hostDomain {
return true
}
if strings.HasPrefix(certHost, "*.") {
certHost = strings.ReplaceAll(certHost, "*.", "")
}

return false
if certHost == hostDomain {
return true
}
}

return false
}
86 changes: 69 additions & 17 deletions internal/certificate/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,76 @@ type CertificateServiceTestSuite struct {
suite.Suite
}

func (s *CertificateServiceTestSuite) TestMatchDomainFilter_MainDomain() {
cert := New(
"arn:xpto",
"foo.xpto.com",
[]string{"foo.xpto.com", "*.foo.xpto.com"},
)

filter := matchingDomainFilter("foo.xpto.com")
s.True(filter(cert))
func (s *CertificateServiceTestSuite) TestMatchDomainFilters_Matches() {
testCases := []struct {
name string
certDomainName string
certAlternativeDomains []string
distrDomains []string
}{
{
name: "Matching distribution domains using all certificate alternative domains",
certDomainName: "foo.com",
certAlternativeDomains: []string{"foo.com", "*.foo.com"},
distrDomains: []string{"www.foo.com", "foo.com"},
},
{
name: "Matching distribution domains using all certificate alternative domains (alternative order on distr domains)",
certDomainName: "foo.com",
certAlternativeDomains: []string{"foo.com", "*.foo.com"},
distrDomains: []string{"foo.com", "www.foo.com"},
},
{
name: "Matching distribution domains using all certificate alternative domains (alternative order on cert domains)",
certDomainName: "foo.com",
certAlternativeDomains: []string{"*.foo.com", "foo.com"},
distrDomains: []string{"foo.com", "www.foo.com"},
},
{
name: "Matching distribution domains when certificate has additional alternative domains",
certDomainName: "bar.com",
certAlternativeDomains: []string{"*.foo.com", "bar.com", "*.baz.com"},
distrDomains: []string{"www.foo.com", "bar.com"},
},
{
name: "Matching distribution domains exactly with certificates domains",
certDomainName: "bar.com",
certAlternativeDomains: []string{"baz.com"},
distrDomains: []string{"bar.com", "baz.com"},
},
}

for _, tc := range testCases {
cert := New("arn:foo", tc.certDomainName, tc.certAlternativeDomains)
filter := matchingDomainFilter(tc.distrDomains)
s.Truef(filter(cert), "testCase: %s", tc.name)
}
}

func (s *CertificateServiceTestSuite) TestMatchDomainFilter_SubDomain() {
cert := New(
"arn:xpto",
"foo.xpto.com",
[]string{"foo.xpto.com", "*.foo.xpto.com"},
)
func (s *CertificateServiceTestSuite) TestMatchDomainFilters_DoesntMatch() {
testCases := []struct {
name string
certDomainName string
certAlternativeDomains []string
distrDomains []string
}{
{
name: "Doesn't Match anything",
certDomainName: "bar.com",
certAlternativeDomains: []string{"bar.com", "*.bar.com"},
distrDomains: []string{"www.foo.com", "foo.com"},
},
{
name: "Doesn't Match one domain",
certDomainName: "*.xpto.com",
certAlternativeDomains: []string{"*.xpto.com"},
distrDomains: []string{"www.xpto.com", "xpto.com"},
},
}

filter := matchingDomainFilter("baz.foo.xpto.com")
s.True(filter(cert))
for _, tc := range testCases {
cert := New("arn:foo", tc.certDomainName, tc.certAlternativeDomains)
filter := matchingDomainFilter(tc.distrDomains)
s.Falsef(filter(cert), "testCase: %s", tc.name)
}
}
19 changes: 7 additions & 12 deletions internal/cloudfront/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,22 +258,17 @@ func (s *Service) newDistribution(ingresses []k8s.CDNIngress, group string, shar

// discoverCert returns the first found ACM Certificate that matches any Alternate Domain Name of the input Ingresses
func (s *Service) discoverCert(ingresses []k8s.CDNIngress) (certificate.Certificate, error) {
errs := &multierror.Error{}
var matchingCert certificate.Certificate

var alternateDomains []string
for _, ing := range ingresses {
for _, dn := range ing.AlternateDomainNames {
cert, err := s.CertService.DiscoverByHost(dn)
if err != nil {
errs = multierror.Append(errs, fmt.Errorf("%q: %v", dn, err))
} else {
matchingCert = cert
}
alternateDomains = append(alternateDomains, ing.AlternateDomainNames...)
}

}
cert, err := s.CertService.DiscoverByHost(alternateDomains)
if err != nil {
return certificate.Certificate{}, fmt.Errorf("%v: %v", alternateDomains, err)
}

return matchingCert, errs.ErrorOrNil()
return cert, nil
}

func (s *Service) s3Prefix(group string) string {
Expand Down

0 comments on commit 3969cc5

Please sign in to comment.