fix(certmanager#514): check DNS configuration before starting ACME

Signed-off-by: MustafaAamir <mustafa.290101@gmail.com>
This commit is contained in:
MustafaAamir
2025-11-09 02:18:22 +00:00
committed by Bryan Frimin
parent a3fcd522ca
commit 60a3402b24
7 changed files with 48 additions and 13 deletions

View File

@@ -25,11 +25,11 @@ import (
"fmt"
"time"
"go.gearno.de/kit/httpclient"
"go.gearno.de/kit/log"
"go.probo.inc/probo/pkg/crypto/keys"
"go.probo.inc/probo/pkg/crypto/pem"
"go.probo.inc/probo/pkg/version"
"go.gearno.de/kit/httpclient"
"go.gearno.de/kit/log"
"golang.org/x/crypto/acme"
)

View File

@@ -19,10 +19,10 @@ import (
"net/http"
"strings"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/crypto/cipher"
"go.gearno.de/kit/log"
"go.gearno.de/kit/pg"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/crypto/cipher"
)
type ACMEChallengeHandler struct {

View File

@@ -19,10 +19,10 @@ import (
"fmt"
"time"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/crypto/cipher"
"go.gearno.de/kit/log"
"go.gearno.de/kit/pg"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/crypto/cipher"
)
type (

View File

@@ -20,10 +20,10 @@ import (
"strings"
"time"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/crypto/cipher"
"go.gearno.de/kit/log"
"go.gearno.de/kit/pg"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/crypto/cipher"
)
type (
@@ -31,6 +31,7 @@ type (
pg *pg.Client
acmeService *ACMEService
encryptionKey cipher.EncryptionKey
cnameTarget string
interval time.Duration
logger *log.Logger
}
@@ -40,6 +41,7 @@ func NewProvisioner(
pg *pg.Client,
acmeService *ACMEService,
encryptionKey cipher.EncryptionKey,
cnameTarget string,
interval time.Duration,
logger *log.Logger,
) *Provisioner {
@@ -47,6 +49,7 @@ func NewProvisioner(
pg: pg,
acmeService: acmeService,
encryptionKey: encryptionKey,
cnameTarget: cnameTarget,
interval: interval,
logger: logger.Named("certmanager.provisioner"),
}
@@ -75,6 +78,28 @@ func (p *Provisioner) Run(ctx context.Context) error {
}
}
func (p *Provisioner) checkDNSConfiguration(domain string) error {
if p.cnameTarget == "" {
return nil
}
cnameRecords, err := net.LookupCNAME(domain)
if err != nil {
return fmt.Errorf("DNS lookup Failed: %w", err)
}
expectedTarget := strings.TrimSuffix(p.cnameTarget, ".")
actualTarget := strings.TrimSuffix(cnameRecords, ".")
if !strings.EqualFold(actualTarget, expectedTarget) {
return fmt.Errorf(
"DNS configuration mismatch: domain %q resolves to %q, expected %q",
domain,
actualTarget,
expectedTarget,
)
}
return nil
}
func (p *Provisioner) checkPendingDomains(ctx context.Context) error {
return p.pg.WithConn(
ctx,
@@ -208,7 +233,17 @@ func (p *Provisioner) provisionDomainCertificate(
domain *coredata.CustomDomain,
) error {
if domain.SSLStatus == coredata.CustomDomainSSLStatusPending {
p.logger.InfoCtx(ctx, "initiating HTTP challenge for domain", log.String("domain", domain.Domain))
if err := p.checkDNSConfiguration(domain.Domain); err != nil {
p.logger.WarnCtx(
ctx,
"DNS configuration check failed, skipping ACME challenge",
log.String("domain", domain.Domain),
log.Error(err),
)
return fmt.Errorf("DNS configuration not ready: %w", err)
}
p.logger.InfoCtx(ctx, "DNS configuration verified, initiating HTTP challenge for domain", log.String("domain", domain.Domain))
challenge, err := p.acmeService.GetHTTPChallenge(ctx, domain.Domain)
if err != nil {

View File

@@ -20,10 +20,10 @@ import (
"fmt"
"time"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/crypto/cipher"
"go.gearno.de/kit/log"
"go.gearno.de/kit/pg"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/crypto/cipher"
)
type (

View File

@@ -21,9 +21,9 @@ import (
"sync"
"time"
"go.gearno.de/kit/pg"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/crypto/cipher"
"go.gearno.de/kit/pg"
)
type (

View File

@@ -634,7 +634,7 @@ func (impl *Implm) runTrustCenterServer(
if certProvisioningInterval == 0 {
certProvisioningInterval = 30 * time.Second
}
certProvisioner := certmanager.NewProvisioner(pgClient, acmeService, impl.cfg.EncryptionKey, certProvisioningInterval, l)
certProvisioner := certmanager.NewProvisioner(pgClient, acmeService, impl.cfg.EncryptionKey, impl.cfg.CustomDomains.CnameTarget, certProvisioningInterval, l)
g, ctx := errgroup.WithContext(ctx)