131b4e1695
We self-delegate `_acme-challenge.unkin.net` into an `acme.unkin.net` zone we serve ourselves, so cert-manager can solve Let's Encrypt DNS-01 over RFC2136/TSIG. That needs a publicly-reachable authoritative BIND, separate from the internal estate. - Add app `bind-external` (base + au-syd1 overlay); register it in the platform ApplicationSet and AppProject destinations (bind-operator already watches all namespaces). - Add BindCluster `bind-external`: authoritative-only, recursion off, no forwarding, transfers denied except the keyed catalog/zone AXFR; 2 replicas; primaryService is a dmz-pinned PureLB LoadBalancer at `198.18.199.53`. - Add BindZone `acme.unkin.net` (primary, dynamicUpdate) and BindTSIGKey `certmanager` (hmac-sha256), whose Secret `certmanager-tsig` reflects into the `cert-manager` namespace for the rfc2136 solver. Pairs with argocd-apps #327 (the ClusterIssuers) and a one-time Google Cloud DNS delegation + NAT of the public IP :53 to `198.18.199.53`. --------- Co-authored-by: Ben Vincent <neotheo@gmail.com> Reviewed-on: #329 Co-authored-by: Ben Vincent <ben@unkin.net> Co-committed-by: Ben Vincent <ben@unkin.net>
53 lines
1.8 KiB
YAML
53 lines
1.8 KiB
YAML
---
|
|
# Externally-reachable authoritative BIND for zones we delegate to ourselves.
|
|
# First tenant: acme.unkin.net, the DNS-01 challenge zone Let's Encrypt validates
|
|
# via a one-time _acme-challenge.unkin.net CNAME. Authoritative-only, recursion
|
|
# off, no forwarding, no open transfers -- the primaryService is the single
|
|
# dmz-pinned LoadBalancer that public NAT targets and that cert-manager writes to.
|
|
apiVersion: bind.unkin.net/v1alpha1
|
|
kind: BindCluster
|
|
metadata:
|
|
name: bind-external
|
|
namespace: bind-external
|
|
spec:
|
|
mode: authoritative
|
|
recursion: false
|
|
replicas: 2
|
|
storageClassName: cephrbd-fast-delete
|
|
storageSize: 1Gi
|
|
# Public server: answer queries from anywhere (Let's Encrypt validates over the
|
|
# internet), deny recursion and open zone transfers. localhost + pod net are
|
|
# implied by "any" and cover in-pod nsupdate and secondary SOA refresh; per-zone
|
|
# allow-transfer (catalog + acme zone) still permits key-authenticated AXFR.
|
|
extraOptions:
|
|
- "allow-query { any; }"
|
|
- "allow-transfer { none; }"
|
|
service:
|
|
type: ClusterIP
|
|
primaryService:
|
|
type: LoadBalancer
|
|
externalTrafficPolicy: Local
|
|
annotations:
|
|
purelb.io/service-group: dmz
|
|
purelb.io/addresses: 198.18.199.53
|
|
external-dns.alpha.kubernetes.io/hostname: bind-external-primary.k8s.syd1.au.unkin.net
|
|
resources:
|
|
requests:
|
|
cpu: 20m
|
|
memory: 128Mi
|
|
limits:
|
|
cpu: "1"
|
|
memory: 512Mi
|
|
---
|
|
# Catalog zone so the acme zone replicates onto the secondary (AXFR/IXFR keyed
|
|
# with the certmanager TSIG key, reused here as the transfer key).
|
|
apiVersion: bind.unkin.net/v1alpha1
|
|
kind: BindCatalogZone
|
|
metadata:
|
|
name: bind-external-catalog
|
|
namespace: bind-external
|
|
spec:
|
|
clusterRef: bind-external
|
|
zoneName: catalog.external
|
|
transferKeyRef: certmanager
|