From 7716d1657223c1ec2d8283838bb590a85dc0d510 Mon Sep 17 00:00:00 2001 From: Danijel Simeunovic Date: Thu, 28 May 2026 09:28:29 +0200 Subject: [PATCH] dns01 --- cluster-resources/letsencrypt-issuer.yaml | 122 ++++++++++++++++++ .../wildcard-certificate-example.yaml | 92 +++++++++++++ 2 files changed, 214 insertions(+) create mode 100644 cluster-resources/wildcard-certificate-example.yaml diff --git a/cluster-resources/letsencrypt-issuer.yaml b/cluster-resources/letsencrypt-issuer.yaml index c62ca32..49148f7 100644 --- a/cluster-resources/letsencrypt-issuer.yaml +++ b/cluster-resources/letsencrypt-issuer.yaml @@ -12,6 +12,18 @@ spec: privateKeySecretRef: name: letsencrypt-staging-key solvers: + # DNS-01 solver for wildcard certificates (*.example.com) + - dns01: + cloudflare: + email: danijels@gmail.com + apiTokenSecretRef: + name: cloudflare-api-token-secret + key: api-token + selector: + dnsNames: + - '*.example.com' + - 'example.com' + # HTTP-01 fallback for non-wildcard certificates - http01: ingress: class: traefik @@ -30,6 +42,116 @@ spec: privateKeySecretRef: name: letsencrypt-prod-key solvers: + # DNS-01 solver for wildcard certificates (*.example.com) + - dns01: + cloudflare: + email: danijels@gmail.com + apiTokenSecretRef: + name: cloudflare-api-token-secret + key: api-token + selector: + dnsNames: + - '*.example.com' + - 'example.com' + # HTTP-01 fallback for non-wildcard certificates - http01: ingress: class: traefik + +# ============================================================================= +# DNS PROVIDER EXAMPLES - Uncomment and configure based on your provider: +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Option 1: Cloudflare (recommended - supports API tokens with limited scope) +# ----------------------------------------------------------------------------- +# Create secret with: kubectl create secret generic cloudflare-api-token-secret \ +# --from-literal=api-token=YOUR_CLOUDFLARE_API_TOKEN -n cert-manager +# +# dns01: +# cloudflare: +# email: your-cloudflare-email@example.com +# apiTokenSecretRef: +# name: cloudflare-api-token-secret +# key: api-token + +# ----------------------------------------------------------------------------- +# Option 2: AWS Route53 +# ----------------------------------------------------------------------------- +# Create secret with: kubectl create secret generic route53-credentials \ +# --from-literal=secret-access-key=YOUR_SECRET_KEY -n cert-manager +# +# dns01: +# route53: +# region: us-east-1 +# hostedZoneID: ZXXXXXXXXXXXXX # Optional: auto-detected if not specified +# accessKeyID: YOUR_ACCESS_KEY_ID +# secretAccessKeySecretRef: +# name: route53-credentials +# key: secret-access-key + +# ----------------------------------------------------------------------------- +# Option 3: Azure DNS +# ----------------------------------------------------------------------------- +# Create secret with: kubectl create secret generic azuredns-config \ +# --from-literal=client-secret=YOUR_CLIENT_SECRET -n cert-manager +# +# dns01: +# azureDNS: +# subscriptionID: YOUR_SUBSCRIPTION_ID +# resourceGroupName: YOUR_RESOURCE_GROUP +# hostedZoneName: example.com +# environment: AzurePublicCloud +# managedIdentity: +# clientID: YOUR_MANAGED_IDENTITY_CLIENT_ID # For AKS with pod identity +# # OR use service principal: +# # clientID: YOUR_SERVICE_PRINCIPAL_CLIENT_ID +# # clientSecretSecretRef: +# # name: azuredns-config +# # key: client-secret + +# ----------------------------------------------------------------------------- +# Option 4: Google Cloud DNS +# ----------------------------------------------------------------------------- +# Create secret with service account JSON key: +# kubectl create secret generic clouddns-service-account \ +# --from-file=service-account.json=path/to/key.json -n cert-manager +# +# dns01: +# cloudDNS: +# project: YOUR_GCP_PROJECT_ID +# hostedZoneName: example-com # Managed zone name in Cloud DNS +# serviceAccountSecretRef: +# name: clouddns-service-account +# key: service-account.json + +# ----------------------------------------------------------------------------- +# Option 5: GoDaddy +# ----------------------------------------------------------------------------- +# Requires external webhook: https://github.com/snowdrop/godaddy-webhook +# +# dns01: +# webhook: +# groupName: acme.yourcompany.com +# solverName: godaddy +# config: +# apiKeySecretRef: +# name: godaddy-api-credentials +# key: api-key +# apiSecretSecretRef: +# name: godaddy-api-credentials +# key: api-secret + +# ----------------------------------------------------------------------------- +# Option 6: Manual/Dynamic DNS (for homelab) +# ----------------------------------------------------------------------------- +# Requires RFC2136 provider or external webhook +# +# dns01: +# rfc2136: +# nameserver: your-dns-server.example.com +# tsigKeyName: cert-manager-key +# tsigAlgorithm: HMACSHA256 +# tsigSecretSecretRef: +# name: tsig-secret +# key: secret \ No newline at end of file diff --git a/cluster-resources/wildcard-certificate-example.yaml b/cluster-resources/wildcard-certificate-example.yaml new file mode 100644 index 0000000..6b3a593 --- /dev/null +++ b/cluster-resources/wildcard-certificate-example.yaml @@ -0,0 +1,92 @@ +--- +# Example: Wildcard Certificate for *.example.com +# This creates a certificate that covers ALL subdomains of example.com +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: wildcard-example-com + namespace: default # Change to your application's namespace +spec: + # The secret where the TLS certificate will be stored + secretName: wildcard-example-com-tls + + # Use the production issuer (use letsencrypt-staging for testing) + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + + # DNS names this certificate will cover + # Both wildcard AND apex domain are recommended + dnsNames: + - '*.example.com' # Covers: app.example.com, api.example.com, etc. + - 'example.com' # Also include apex domain explicitly + + # Optional: Configure certificate duration and renewal + duration: 2160h0m0s # 90 days (Let's Encrypt default) + renewBefore: 720h0m0s # Renew 30 days before expiry + + # Optional: Private key settings + privateKey: + algorithm: RSA + encoding: PKCS1 + size: 4096 + +--- +# Example: Using the wildcard certificate with a Traefik IngressRoute +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: app-ingress + namespace: default +spec: + entryPoints: + - websecure + routes: + # Match any subdomain - the wildcard cert covers all of them + - match: Host(`app.example.com`) || Host(`api.example.com`) || Host(`www.example.com`) + kind: Rule + services: + - name: my-service + port: 80 + tls: + # Reference the secret created by the Certificate + secretName: wildcard-example-com-tls + +--- +# Example: Using wildcard certificate with standard Kubernetes Ingress +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: wildcard-ingress + namespace: default + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" +spec: + tls: + - hosts: + - '*.example.com' + - 'example.com' + secretName: wildcard-example-com-tls + rules: + - host: app.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: app-service + port: + number: 80 + - host: api.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: api-service + port: + number: 80 \ No newline at end of file