Repository navigation
v0.3.0 — HTTP blocklist source
Highlights
Adds a polite, self-refreshing HTTP blocklist source so operators no longer need to bake lists into the container image or babysit git pull/SIGHUP. The default container now fetches hagezi pro.txt at startup, caches it to disk, and refreshes every 24h with conditional GET.
What's new
type: httpblocklist source — fetches lists from any HTTP(S) URL with conditional GET (ETag /If-Modified-Since). Configurable global refresh interval (blocklists.refresh_interval, default 24h).- On-disk persistent cache at
blocklists.cache_dir(default/var/cache/bns/blocklists). Bodies + sidecar metadata written atomically; readers never observe a partial write. Survives restarts. - Bootstrap dialer — fetcher resolves URL hostnames via configured upstream IPs directly, bypassing the system stub. BNS can fetch its own lists even when it's the sole resolver on the LAN.
- Always fail-open — HTTP fetch failures never block DNS service. A
bns_blocklist_last_success_timestamp_seconds{source}gauge supports staleness alerts. - Per-source observability — three new metric families:
bns_blocklist_fetch_total{source,outcome}(success/not_modified/failure)bns_blocklist_last_success_timestamp_seconds{source}bns_blocklist_entries_by_source{source}
- Required
namefield on every blocklist source — used as the{source="..."}label on everybns_blocklist_*metric. Validation rejects missing or duplicate names at startup. - SIGHUP now does both — reload disk state (file-source edits) and trigger an immediate fetcher cycle (HTTP sources).
Breaking changes
--blocklistCLI flag removed. Use YAML (-c file.yaml) for blocklist source configuration. The flag is incompatible with the new requirednamefield; YAML is the canonical declaration form.- Container no longer bakes the hagezi list. Cold start with no cache volume serves DNS without blocking for a few seconds while the first fetch lands. Mount a named volume at
/var/cache/bnsto preserve cache across restarts:docker volume create bns-cache docker run -v bns-cache:/var/cache/bns ghcr.io/bcrisp4/bns:0.3.0
HAGEZI_TAGDockerfile build arg dropped.
Config schema
blocklists:
refresh_interval: 24h
cache_dir: /var/cache/bns/blocklists
sources:
- type: http
name: hagezi-pro
url: https://raw.githubusercontent.com/hagezi/dns-blocklists/main/domains/pro.txt
- type: file
name: custom-blocklist
path: /etc/bns/custom-blocklist.txtContainer images
Multi-arch (linux/amd64, linux/arm64) at ghcr.io/bcrisp4/bns:0.3.0, :0.3, :latest.
Spec + plan
- Design:
docs/specs/2026-05-21-bns-http-blocklist-source-design.md - Implementation plan:
docs/plans/2026-05-21-bns-http-blocklist-source-implementation.md - 16 TDD tasks plus a simplify pass and a code-review-driven fix-up.