Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Unbound

ASecurity

Expert coverage of Unbound recursive resolver: unbound.conf tuning, DNSSEC validation, DoT/DoH encrypted DNS, module architecture (validator, iterator, cachedb, python), local zones, pfSense/OPNsense integration, Pi-hole upstream configuration, and qname minimisation. Use for \"Unbound\", \"unbound.conf\", \"recursive resolver\", \"pfSense DNS\", \"OPNsense DNS\", \"Pi-hole upstream\", \"qname minimisation\", \"Unbound DNSSEC\". Do NOT use for cross-vendor comparison, platform selection, or c...

4 stars
0 votes
0 copies
0 views
Added 9/24/2026
devopspythonrustgodatabasesecurityperformance

Works with

cli

Security Analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned 9/24/2026

$npx -y skills add chrishuffman5/domain-expert --skill unbound --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Unbound?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Unbound
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/chrishuffman5-unbound/badge)](https://www.skillsdirectory.com/skills/chrishuffman5-unbound)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: unbound
description: "Expert coverage of Unbound recursive resolver: unbound.conf tuning, DNSSEC validation, DoT/DoH encrypted DNS, module architecture (validator, iterator, cachedb, python), local zones, pfSense/OPNsense integration, Pi-hole upstream configuration, and qname minimisation. Use for \"Unbound\", \"unbound.conf\", \"recursive resolver\", \"pfSense DNS\", \"OPNsense DNS\", \"Pi-hole upstream\", \"qname minimisation\", \"Unbound DNSSEC\". Do NOT use for cross-vendor comparison, platform selection, or category-wide architecture -- use the `dns` skill."
license: MIT
---

# Unbound

This skill covers Unbound (NLnet Labs), a high-performance recursive DNS resolver. Areas of expertise include:

- Multi-threaded architecture with shared cache and per-thread iterators
- `unbound.conf` configuration and performance tuning
- DNSSEC validation with automatic trust anchor management (RFC 5011)
- DNS over TLS (DoT) upstream forwarding and incoming DoH server (1.17+)
- Module pipeline architecture: validator, iterator, respip, cachedb, python, dynlib
- Local zones and local-data for split-horizon, internal resolution, and ad-blocking
- pfSense and OPNsense integration (default resolver since OPNsense 17.7)
- Pi-hole upstream configuration for DNSSEC + ad-blocking combination
- Serve-expired for DNS resilience during upstream outages
- Qname minimisation (RFC 7816) for privacy

## How to Approach Tasks

1. **Classify** the request:
   - **Configuration** -- `unbound.conf` settings, forwarding, local zones, access control
   - **Performance tuning** -- Thread count, cache sizing, prefetch, TCP fast open
   - **Security** -- DNSSEC validation, DoT/DoH, access control, hardening
   - **Integration** -- pfSense/OPNsense GUI config, Pi-hole upstream, systemd-resolved
   - **Architecture** -- Load `references/architecture.md` for module pipeline and deployment patterns

2. **Identify deployment** -- Standalone recursive, forwarder to upstream, pfSense/OPNsense appliance, Pi-hole upstream, or stub/authority hybrid.

3. **Identify scale** -- Home/small office (1-100 clients), campus (1000+), or ISP-scale (100k+). Scale determines thread count, cache sizes, and architecture.

4. **Recommend** -- Provide specific `unbound.conf` configuration blocks with explanations.

## Core Architecture

### Multi-Threaded Design

- `num-threads`: worker threads handling queries in parallel (match CPU core count)
- Shared cache across threads (or per-thread with optional sync via `msg-cache-slabs`)
- Each thread runs independent iterator state machine for recursive lookups
- Infra cache: tracks per-server performance (RTT, lame detection)
- Key cache: DNSSEC key material for validated zones

### Module Pipeline

Each query traverses a chain of modules:

1. **validator**: DNSSEC validation (signature verification, chain of trust)
2. **iterator**: recursive resolution logic (root -> TLD -> authoritative)
3. **respip**: response IP policy (EDNS client subnet, policy filtering)
4. **cachedb**: external cache database (Redis) for shared cache across instances
5. **python**: Python module for custom query/response manipulation
6. **dynlib**: C dynamic library for high-performance custom logic

Module order configured via `module-config: "validator iterator"` (default).

## Core Configuration

### Essential Settings

```ini
server:
    num-threads: 4                         # match CPU cores
    interface: 0.0.0.0                     # listen address
    port: 53
    access-control: 10.0.0.0/8 allow       # allow internal clients
    access-control: 192.168.0.0/16 allow
    access-control: 127.0.0.0/8 allow

    # DNSSEC
    auto-trust-anchor-file: "/var/lib/unbound/root.key"
    root-hints: "/etc/unbound/root.hints"

    # Privacy
    hide-identity: yes
    hide-version: yes
    qname-minimisation: yes                # RFC 7816

    # Performance
    prefetch: yes                          # refresh popular entries before TTL expiry
    prefetch-key: yes                      # prefetch DNSKEY for DNSSEC
    msg-cache-size: 128m
    rrset-cache-size: 256m                 # should be 2x msg-cache-size
    cache-min-ttl: 60                      # floor for cached TTLs
    cache-max-ttl: 86400

    # Resilience
    serve-expired: yes                     # return stale on upstream failure
    serve-expired-ttl: 86400              # max stale age (24 hours)

    # Hardening
    harden-glue: yes
    harden-dnssec-stripped: yes
    harden-below-nxdomain: yes
    use-caps-for-id: yes                   # 0x20 encoding for cache poisoning defense
```

### DoT Upstream Forwarding

```ini
forward-zone:
    name: "."
    forward-tls-upstream: yes
    forward-addr: 1.1.1.1@853#cloudflare-dns.com
    forward-addr: 1.0.0.1@853#cloudflare-dns.com
    forward-addr: 8.8.8.8@853#dns.google
    forward-addr: 8.8.4.4@853#dns.google
```

### DoH Server (Incoming, 1.17+)

```ini
server:
    interface: 0.0.0.0@443
    https-port: 443
    tls-service-key: "/etc/unbound/server.key"
    tls-service-pem: "/etc/unbound/server.pem"
    http-endpoint: "/dns-query"
```

Full encrypted path: clients connect via DoH -> Unbound resolves via DoT upstream.

### Local Zones and Overrides

```ini
# Internal hostname resolution
local-zone: "home.lab." static
local-data: "server1.home.lab. IN A 10.0.0.10"
local-data: "server2.home.lab. IN A 10.0.0.11"

# Block a domain
local-zone: "ads.example.com." refuse

# Redirect domain
local-zone: "override.example.com." redirect
local-data: "override.example.com. IN A 10.0.0.1"
```

### Conditional Forwarding

```ini
# Forward internal domain to corporate DNS
forward-zone:
    name: "corp.internal."
    forward-addr: 10.0.0.53
    forward-addr: 10.0.0.54

# Forward reverse lookups to internal DNS
forward-zone:
    name: "10.in-addr.arpa."
    forward-addr: 10.0.0.53
```

## pfSense and OPNsense Integration

### OPNsense (Default Resolver)

- Unbound is default DNS resolver since OPNsense 17.7
- GUI: Services > Unbound DNS > General (enable, interfaces, access networks)
- Advanced settings via "Custom options" text box in GUI
- DNSBL integration: OPNsense supports DNS block lists via Unbound plugin
- DoT upstream: configurable in GUI (Services > Unbound DNS > DNS over TLS)
- DHCP registration: auto-registers DHCP leases as DNS entries

### pfSense

- Unbound is default resolver (Services > DNS Resolver)
- GUI for common settings; advanced via custom options
- DHCP integration: static mappings and leases registered automatically
- Host overrides: GUI-managed local-data entries

### Pi-hole + Unbound Stack

Recommended architecture for ad-blocking with full DNSSEC:

```
Client ──► Pi-hole (ad filter) ──► Unbound (recursive + DNSSEC)
                                       │
                                   Root/TLD/Auth
                                   (full recursion)
```

Pi-hole handles ad/tracker filtering. Unbound performs full recursive resolution with DNSSEC validation. No upstream forwarder needed -- Unbound queries root servers directly.

Configuration for Pi-hole upstream:
```ini
server:
    interface: 127.0.0.1
    port: 5335                             # non-standard port for Pi-hole
    do-not-query-localhost: no
    access-control: 127.0.0.0/8 allow

    # Full recursion (no forwarding)
    # Do NOT add forward-zone for "."
```

Pi-hole Custom DNS: set upstream to `127.0.0.1#5335`.

## Performance Tuning

### Thread and Cache Sizing

| Deployment | Threads | msg-cache | rrset-cache |
|---|---|---|---|
| Home (1-10 clients) | 1-2 | 8m | 16m |
| Small office (10-100) | 2-4 | 32m | 64m |
| Campus (100-1000) | 4-8 | 128m | 256m |
| ISP (1000+) | 8-16 | 512m | 1g |

### Slab Configuration

Slabs should be a power of 2 close to `num-threads`:
```ini
msg-cache-slabs: 4
rrset-cache-slabs: 4
infra-cache-slabs: 4
key-cache-slabs: 4
```

### TCP Optimization

```ini
outgoing-range: 8192                       # concurrent queries (per thread)
num-queries-per-thread: 4096
so-reuseport: yes                          # distribute sockets across threads
```

## Common Pitfalls

1. **rrset-cache-size < 2x msg-cache-size** -- RRset cache should be approximately 2x message cache. Incorrect ratio causes premature cache evictions and query amplification.
2. **Forwarding to upstream with DNSSEC validation** -- When forwarding (not recursing), Unbound cannot fully validate DNSSEC unless the upstream also signs responses. Use `forward-tls-upstream` for trusted forwarding or full recursion for strict DNSSEC.
3. **serve-expired without TTL limit** -- `serve-expired: yes` without `serve-expired-ttl` can return very stale records. Always set a max stale age.
4. **Pi-hole + Unbound port conflict** -- Both default to port 53. Run Unbound on a non-standard port (5335) when co-located with Pi-hole.
5. **qname-minimisation breaking legacy authoritative servers** -- Some old authoritative servers do not handle minimized queries correctly. Use `qname-minimisation-strict: no` (default) to fall back gracefully.
6. **OPNsense custom options overwritten on upgrade** -- Custom unbound.conf edits outside the GUI may be overwritten during OPNsense upgrades. Use the GUI "Custom options" field instead.

## Reference Files

- `references/architecture.md` -- Recursive resolver architecture, DNSSEC, DoT/DoH, modules, pfSense/OPNsense/Pi-hole

Attribution

chrishuffman5chrishuffman5
View sourceSee grades on GitHubMore from chrishuffman5 →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Terraform Module Library

Build reusable Terraform modules for AWS, Azure, and GCP infrastructure following infrastructure-as-code best practices. Use when creating infrastructure modules, standardizing cloud provisioning, or implementing reusable IaC components.

401991 votes

sematext-otel

Wire a service's OpenTelemetry output to Sematext Cloud. Walks through region, App-type, instrumentation flow (managed OTLP endpoint vs Sematext Agent), and signal selection (traces/metrics/logs), then produces the exact env-var block and points at a runnable reference example in this repo. Invoke when instrumenting a new app for Sematext.

01 votes

Deployment Patterns

Deployment workflows, CI/CD pipeline patterns, Docker containerization, health checks, rollback strategies, and production readiness checklists for web applications. Use when setting up deployment infrastructure or planning releases.

2699140 votes

Babysit

Watch a pull request or review cycle until it is ready to merge. Use when asked to babysit, monitor, or keep checking PR comments, reviews, and CI until all actionable issues are resolved.

971540 votes

V7 Roster

Interact with the Paperclip control plane API for task coordination and governance. Use when checking assignments, updating issue status, posting comments, delegating work, managing routines, or calling Paperclip API endpoints.

953190 votes
View all in devops →