DO NOT SYNC THIS BEFORE MIGRATING. Removing fancy-dns-zones and fancy-dns-rpz from the kustomization lets a pruning GitOps tool delete them, and they hold the only copy of the zones and address redirects until the objects exist. Follow deploy/MIGRATION.md: install the definitions, run `fancy-dns-console migrate` against the live cluster, then roll this out. The StatefulSet starts the resolver with -kube and no longer mounts the two ConfigMaps; its service account loses the ConfigMap role and keeps only the read-only Role on the fancy-dns objects (crds/rbac.yaml). The kustomization now installs the definitions and that Role. The shipped config no longer lists the migrated sources. Config validation no longer refuses an enabled blocklist with no sources in the file, because BlockList, DomainRule and AddressOverride objects can supply every rule and the file cannot know. The existing "no source" warning says so. That removed the only validation message the settings tests used as a fixture; they now use an invalid acl.default_policy, and an empty settings document is refused by the handler instead of by that check. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
134 lines
3.9 KiB
YAML
134 lines
3.9 KiB
YAML
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: dns
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: fancy-dns-config
|
|
namespace: dns
|
|
labels:
|
|
app.kubernetes.io/name: fancy-dns
|
|
data:
|
|
config.yaml: |
|
|
# Rendered by the deployment below; kept in a ConfigMap so a change is a
|
|
# `kubectl apply` rather than a rebuild.
|
|
server:
|
|
max_concurrent: 2048
|
|
timeouts:
|
|
upstream: 2s
|
|
list_fetch: 60s
|
|
|
|
dns:
|
|
# Use high ports in the pod so the container needs no privileged-port
|
|
# capability. Services expose the standard DNS ports to clients.
|
|
udp: ["0.0.0.0:1053", "[::]:1053"]
|
|
tcp: ["0.0.0.0:1053", "[::]:1053"]
|
|
max_udp_size: 1232
|
|
dot:
|
|
enabled: true
|
|
listen: ["0.0.0.0:1853"]
|
|
cert_file: /etc/fancy-dns/tls/tls.crt
|
|
key_file: /etc/fancy-dns/tls/tls.key
|
|
doh:
|
|
enabled: true
|
|
listen: ["0.0.0.0:8443"]
|
|
cert_file: /etc/fancy-dns/tls/tls.crt
|
|
key_file: /etc/fancy-dns/tls/tls.key
|
|
base_path: /dns-query
|
|
|
|
upstream:
|
|
forward_zones:
|
|
- zone: local
|
|
servers:
|
|
- addr: 10.10.0.1:53
|
|
proto: udp
|
|
policy: parallel
|
|
max_attempts: 3
|
|
healthcheck_interval: 30s
|
|
servers:
|
|
- addr: 9.9.9.9:53
|
|
proto: udp
|
|
- addr: 1.1.1.1:53
|
|
proto: tls
|
|
server_name: cloudflare-dns.com
|
|
- addr: 9.9.9.9:853
|
|
proto: tls
|
|
server_name: dns.quad9.net
|
|
|
|
# Memory envelope. The container limit (1Gi, in the StatefulSet) is the
|
|
# hard ceiling; this tells the process about it so the collector works to
|
|
# a target instead of being OOM-killed. `limit` is the soft GOMEMLIMIT and
|
|
# must be at or below the container limit; `reserve` covers what the Go
|
|
# heap does not account for — goroutine stacks, runtime metadata, and the
|
|
# mmapped cache snapshot and query log.
|
|
#
|
|
# The cache byte budget is derived (60% of limit - reserve) unless it is
|
|
# set explicitly. cache.size below is an *entry count*, so this is what
|
|
# actually bounds the cache's memory: 500k entries of a few hundred bytes
|
|
# each is well past 384MiB, and the byte budget is what will bite first.
|
|
memory:
|
|
limit: 1GiB
|
|
reserve: 256MiB
|
|
cache_max_bytes: 384MiB
|
|
|
|
cache:
|
|
enabled: true
|
|
size: 500000
|
|
max_ttl: 1h
|
|
serve_stale: 30m
|
|
persist:
|
|
enabled: true
|
|
path: /var/lib/fancy-dns/cache.db
|
|
interval: 30s
|
|
|
|
blocklist:
|
|
enabled: true
|
|
default_action: nxdomain
|
|
# Lists, zones, address redirects, inline rules and client groups are
|
|
# cluster objects now (BlockList, DNSZone, AddressOverride, DomainRule,
|
|
# ClientGroup); see deploy/MIGRATION.md. `fancy-dns-console migrate`
|
|
# converts what was here.
|
|
|
|
acl:
|
|
default_policy: allow
|
|
groups: []
|
|
|
|
# JSON lines on stdout for blocked and failed queries; the metrics cover
|
|
# the rest. See deploy/config.example.yaml.
|
|
access_log:
|
|
enabled: true
|
|
log_blocked: true
|
|
log_errors: true
|
|
sample_rate: 0
|
|
|
|
api:
|
|
enabled: true
|
|
listen: ["0.0.0.0:8080"]
|
|
base_path: /api
|
|
ui: true
|
|
allow_config_write: false
|
|
# The key comes from the environment (a Secret mounted into the pod), not
|
|
# from this ConfigMap, so `kubectl get cm` never prints it. The loader
|
|
# substitutes ${VAR} before parsing and *fails to start* if the variable
|
|
# is unset, so a missing secret is a crash loop rather than an
|
|
# unauthenticated console.
|
|
auth:
|
|
mode: oidc
|
|
api_keys: ["${FANCYDNS_API_KEY}"]
|
|
oidc_issuer: https://users.k6n.net
|
|
oidc_audience: https://dns.k6n.net
|
|
oidc_client_id: fancy-dns
|
|
oidc_write_roles: [admin]
|
|
trust_loopback: false
|
|
|
|
metrics:
|
|
enabled: true
|
|
path: /metrics
|
|
protect: true
|
|
|
|
log:
|
|
level: info
|
|
format: json
|