# ─────────────────────────────────────────────────────────────────────────────
# Runbound — Home / Pi-hole replacement configuration
#
# Use-case : Raspberry Pi / home router running a LAN DNS resolver.
# - Blocks ads & telemetry via the REST API feed system
# - Serves custom local hostnames (NAS, printer, cameras…)
# - Forwards everything else to Cloudflare with DNSSEC validation
# ─────────────────────────────────────────────────────────────────────────────
server:
# Listen on all interfaces so LAN clients can reach the resolver.
# On Raspberry Pi replace 0.0.0.0 with the Pi's LAN IP for clarity.
interface: 0.0.0.0
port: 53
do-ip4: yes
do-ip6: yes
do-udp: yes
do-tcp: yes
# ── Access control ───────────────────────────────────────────────────────
# Allow only LAN + loopback; refuse everything else (internet scanners).
access-control: 127.0.0.0/8 allow
access-control: 192.168.1.0/16 allow # common home subnet
access-control: 10.0.0.0/8 allow # some ISP boxes use 10.x
access-control: 0.0.0.0/0 refuse
# ── Rate limiting ────────────────────────────────────────────────────────
# 200 q/s per source IP is generous for residential use.
rate-limit: 200
cache-max-ttl: 3600 # cap TTLs at 1 hour — faster recovery after IP change
# ── DNS rebinding protection ─────────────────────────────────────────────
# Prevents a malicious public domain from resolving to a private LAN IP.
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
# ── Local hostnames ──────────────────────────────────────────────────────
local-zone: "home." static
local-data: "nas.home. 300 IN A 192.168.1.10"
local-data: "printer.home. 300 IN A 192.168.1.20"
local-data: "camera1.home. 300 IN A 192.168.1.30"
local-data: "camera2.home. 300 IN A 192.168.1.31"
local-data: "router.home. 300 IN A 192.168.1.1"
local-data: "pi.home. 300 IN A 192.168.1.5"
# Reverse DNS for the NAS (optional but handy for logs)
local-zone: "1.168.192.in-addr.arpa." static
local-data: "10.1.168.192.in-addr.arpa. 300 IN PTR nas.home."
# ── Memory guard (always active — no config needed) ─────────────────────
# /proc/meminfo is checked every 30 s.
# At ≥ 80 % RAM usage → rate-limiter DashMap cleared + DNS resolver rebuilt
# (in-flight queries are unaffected via ArcSwap). WARN emitted in logs.
# Inflight semaphore: max 4 096 concurrent requests → REFUSED beyond that.
# ── Logging ─────────────────────────────────────────────────────────────
# Remove or set to "" to log to stdout (easier with systemd journal).
# logfile: /var/log/runbound/runbound.log
# ── Upstream resolver — Cloudflare DoT (encrypted, privacy-friendly) ─────────
forward-zone:
name: "."
forward-addr: 1.1.1.1@853
forward-addr: 1.0.0.1@853
forward-tls-upstream: yes