runbound 0.4.0

RFC-compliant DNS resolver — drop-in Unbound with REST API, ACME auto-TLS, HMAC audit log, and master/slave HA
# ─────────────────────────────────────────────────────────────────────────────
# Runbound — Office / SMB network configuration
#
# Use-case : Office with split-horizon DNS.
# - corp.example.com  → internal zone answered authoritatively by Runbound
# - everything else   → forwarded to ISP / public DNS
# - Blocks known-malware domains via REST API feeds (URLhaus, etc.)
# - DoT enabled for secure inter-office resolvers
# ─────────────────────────────────────────────────────────────────────────────

server:
    interface:  0.0.0.0
    port:       53

    do-ip4:     yes
    do-ip6:     yes
    do-udp:     yes
    do-tcp:     yes

    # ── Access control ───────────────────────────────────────────────────────
    access-control: 127.0.0.0/8      allow
    access-control: 10.10.0.0/16     allow   # office LAN
    access-control: 172.16.0.0/12    allow   # VPN range
    access-control: 0.0.0.0/0        refuse

    rate-limit:    1000
    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

    # ── Internal corporate zone ───────────────────────────────────────────────
    local-zone: "corp.example.com." static

    # Management plane
    local-data: "dns.corp.example.com.      300 IN A 10.10.0.5"
    local-data: "ldap.corp.example.com.     300 IN A 10.10.0.10"
    local-data: "mail.corp.example.com.     300 IN A 10.10.0.11"
    local-data: "intranet.corp.example.com. 300 IN A 10.10.0.20"
    local-data: "git.corp.example.com.      300 IN A 10.10.0.21"
    local-data: "vpn.corp.example.com.      300 IN A 10.10.0.1"

    # ── Blocked internal domains ─────────────────────────────────────────────
    # Social media during work hours (manage via REST API in production)
    # local-zone: "facebook.com." always_nxdomain
    # local-zone: "twitter.com."  always_nxdomain

    # ── 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.

    # ── TLS — DNS-over-TLS on port 853 ──────────────────────────────────────
    # Generate with: runbound --gen-cert dns.corp.example.com
    # Or use Let's Encrypt:
    #   certbot certonly --standalone -d dns.corp.example.com
    tls-service-pem: /etc/runbound/cert.pem
    tls-service-key: /etc/runbound/key.pem


# ── Corporate internal DNS → offices that have an AD/internal zone ────────────
forward-zone:
    name:         "corp.example.com."
    forward-addr: 10.10.0.5@53

# ── Everything else → Cloudflare DoT (encrypted) ─────────────────────────────
forward-zone:
    name:                 "."
    forward-addr:         1.1.1.1@853
    forward-addr:         1.0.0.1@853
    forward-tls-upstream: yes