# ─────────────────────────────────────────────────────────────────────────────
# Runbound — Slave replica configuration
#
# Use-case : High-availability DNS — this node is a read-only replica of a
# master Runbound instance.
#
# How it works:
# - The slave polls the master every sync-interval seconds via HTTPS.
# - On first start: TOFU handshake — cert fingerprint is downloaded from
# GET /sync/cert, cross-verified against the TLS handshake, then saved to
# /etc/runbound/sync-master.fingerprint (chmod 640). A WARN is emitted.
# Verify the fingerprint manually: compare with `openssl x509 -fingerprint
# -sha256 -noout -in /etc/runbound/sync-cert.pem` on the master.
# - All subsequent connections pin the saved fingerprint (rustls, no CA).
# - Delta events (DNS adds/deletes, blacklist, feeds) are applied live.
# - If > 1 000 events behind (410 Gone): full snapshot sync is performed.
# - All non-GET API requests return 503 READ_ONLY on slave nodes.
#
# Companion master config: see examples/master.conf or the docs/configuration.md
# ─────────────────────────────────────────────────────────────────────────────
server:
# ── Network ──────────────────────────────────────────────────────────────
interface: 0.0.0.0
port: 53
do-ip4: yes
do-ip6: yes
do-udp: yes
do-tcp: yes
# ── Access control ────────────────────────────────────────────────────────
# Same rules as the master — LAN clients query this node identically.
access-control: 127.0.0.0/8 allow
access-control: 192.168.1.0/24 allow # adjust to your subnet
access-control: 10.0.0.0/8 allow
access-control: 0.0.0.0/0 refuse
# ── Rate limiting ─────────────────────────────────────────────────────────
rate-limit: 200
cache-max-ttl: 3600
# ── DNS rebinding protection ──────────────────────────────────────────────
private-address: 10.0.0.0/8
private-address: 172.16.0.0/12
private-address: 192.168.0.0/16
private-address: 127.0.0.0/8
private-address: fd00::/8
# ── Slave/master replication ──────────────────────────────────────────────
mode: slave
# IP:port of the master's sync HTTPS server (sync-port on the master).
sync-master: 192.168.1.10:8082
# Shared Bearer token — must match the master's sync-key.
# Prefer setting via environment variable if possible:
# export RUNBOUND_SYNC_KEY="$(cat /etc/runbound/sync.key)"
sync-key: "change-me-to-match-master"
# Poll interval in seconds (default: 30).
# Lower values reduce replication lag; higher values reduce load.
sync-interval: 30
# ── REST API ──────────────────────────────────────────────────────────────
# The REST API is available on slave nodes in read-only mode.
# GET endpoints (dns, blacklist, feeds, stats, logs, upstreams…) work normally.
# POST and DELETE requests are rejected with 503 READ_ONLY.
api-port: 8081
# api-key is auto-generated at startup and saved to /etc/runbound/api.key
# Override with RUNBOUND_API_KEY environment variable.
# ── Memory guard (always active — no config needed) ───────────────────────
# At ≥ 80 % system RAM: rate-limiter + resolver cache purged automatically.
# Inflight semaphore: max 4 096 concurrent requests → REFUSED if exceeded.
# ── Logging ───────────────────────────────────────────────────────────────
verbosity: 1
# logfile: /var/log/runbound/runbound.log
# ── Upstream resolvers ────────────────────────────────────────────────────────
# Same forward-zone as the master so both nodes resolve identically.
forward-zone:
name: "."
forward-addr: 1.1.1.1@853
forward-addr: 1.0.0.1@853
forward-tls-upstream: yes