TLS Certificates

TLS certificates are managed by cert-manager in the Kubernetes cluster. There are currently several certificates in a broken state due to the HTTP-01 challenge solver being incompatible with the Cloudflare tunnel architecture.

Certificate Inventory

CertificateNamespaceIssuerStatusAgeNotes
kuber-cadefaultSelf-signedReady-Internal CA
traefik-dashboard-tlskube-systemletsencrypt-prodReady-Traefik admin
wildcard-sslipdefaultletsencrypt-prodReady-sslip.io wildcard
harbor-tlsregistryletsencrypt-prodNOT READY20 daysHTTP-01 failure
devtron-tlsdevtroncdletsencrypt-prodNOT READY20 daysHTTP-01 failure
wildcard-sslip-tlsmonitoringletsencrypt-prodNOT READY-HTTP-01 failure

Issuers

IssuerTypeStatusNotes
letsencrypt-prodClusterIssuer, ACME HTTP-01ActiveBROKEN behind tunnel
letsencrypt-stagingClusterIssuer, ACME HTTP-01FALSEStaging issuer in error state

The HTTP-01 Problem

The current cert-manager configuration uses HTTP-01 ACME challenges. This solver requires Let's Encrypt to make an HTTP request to http://<domain>/.well-known/acme-challenge/<token> to verify domain ownership.

This does not work behind a Cloudflare tunnel because:

Let's Encrypt ──> Cloudflare ──> tunnel ──> Traefik ──> cert-manager solver pod
                       │
                       └── Cloudflare may cache, redirect to HTTPS,
                           or otherwise interfere with the challenge

The Cloudflare tunnel and its "Always Use HTTPS" setting redirects HTTP challenges to HTTPS, causing validation to fail.

Required Fix: DNS-01 Solver

The solution is to migrate from HTTP-01 to DNS-01 challenge solver. DNS-01 verifies domain ownership by creating a TXT record in DNS, which works regardless of tunnel configuration.

Migration Steps

  1. Create a Cloudflare API token with DNS edit permissions
  2. Store the token as a Kubernetes secret
  3. Update the ClusterIssuer to use DNS-01 with Cloudflare
  4. Re-request failed certificates

See Certificate Renewal Runbook for the full procedure.

Target Configuration

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod-key
    solvers:
    - dns01:
        cloudflare:
          apiTokenSecretRef:
            name: cloudflare-api-token
            key: api-token

Affected Services

The following services have broken TLS due to the HTTP-01 issue:

ServiceCertificateImpact
Harborharbor-tlsRegistry unreachable via HTTPS from external
Devtrondevtron-tlsCI/CD dashboard TLS broken
Monitoringwildcard-sslip-tlsMonitoring dashboards may show cert warnings

Working Certificates

These certificates were issued before the problem manifested or use a different mechanism:

CertificateWhy It Works
kuber-caSelf-signed, no ACME needed
traefik-dashboard-tlsIssued when HTTP-01 was working, auto-renewed before expiry
wildcard-sslipsslip.io domain may resolve differently

Quick Commands

# List all certificates
kubectl get certificates -A

# Check certificate details
kubectl describe certificate harbor-tls -n registry

# Check cert-manager logs
kubectl logs -n cert-manager -l app=cert-manager --tail=100

# Check issuer status
kubectl get clusterissuer

# Force certificate re-request (delete and recreate)
kubectl delete certificate harbor-tls -n registry
# Then re-apply the Certificate resource

# Check ACME challenge status
kubectl get challenges -A
kubectl describe challenge -A