OPNsense Unbound DNSBL

This role configures DNS Blocklists (DNSBL) in OPNsense Unbound resolver via the REST API. DNSBL blocks malicious domains, ads, trackers, and other unwanted content at the DNS level.

Ansible DNS HTTPS JSON OPNsense REST API SSL TLS

OPNsense Unbound DNSBL Role

Overview

This role configures DNS Blocklists (DNSBL) in OPNsense Unbound resolver via the REST API. DNSBL blocks malicious domains, ads, trackers, and other unwanted content at the DNS level.

Purpose

  • Ad Blocking: Block advertisements at DNS level
  • Malware Protection: Block known malicious domains
  • Privacy: Block tracking and telemetry domains
  • Code as Configuration: Define DNSBL settings in YAML
  • API-Based: Reliable automation via OPNsense REST API
  • Idempotent: Safe to run multiple times

Requirements

  • Ansible 2.9 or higher
  • OPNsense firewall with API access enabled
  • os-unbound-plus plugin installed (provides DNSBL functionality)
  • API key and secret stored in Ansible Vault
  • Network connectivity to OPNsense (VLAN10)
  • OPNsense user with Unbound permissions

Role Variables

Required Variables

VariableRequiredDescription
vault_opnsense_bjoffrey_user_api_keyYesOPNsense API key (in vault)
vault_opnsense_bjoffrey_user_api_secretYesOPNsense API secret (in vault)
opnsense_unbound_dnsbl_configYesDNSBL configuration object

Optional Variables

VariableDefaultDescription
opnsense_unbound_dnsbl_validate_certstrueValidate SSL certificates

Configuration Structure

opnsense_unbound_dnsbl_config:
  enabled: "1"              # Enable (1) or disable (0) DNSBL
  type:                     # List of blocklist type codes
    - ag                    # AdGuard List
    - sb                    # Steven Black List
  lists:                    # Custom blocklist URLs
    - https://example.com/blocklist.txt
  allowlists:               # Domains to whitelist
    - trusted-domain.com
    - another-trusted.com
  blocklists:               # Domains to explicitly block
    - block-this.com
  wildcards:                # Wildcard domain blocks
    - "*.ads.example.com"
  source_nets: ""           # Source networks (empty = all)
  address: ""               # Redirect address (empty = default)
  nxdomain: "0"             # Return NXDOMAIN instead of redirect
  cache_ttl: "72000"        # Cache TTL in seconds (20 hours)
  description: "default"    # Description

Available Blocklist Types

Core Lists

CodeDescription
atfAbuse.ch - ThreatFox IOC database
agAdGuard List
elEasyList
epEasyPrivacy
sbSteven Black List
yyYoYo List

Hagezi Lists

CodeDescription
hgz001Multi LIGHT - Basic protection
hgz002Multi NORMAL - All-round protection
hgz003Multi PRO - Extended protection
hgz004Multi PRO mini
hgz005Multi PRO++ - Maximum protection
hgz006Multi PRO++ mini
hgz007Multi ULTIMATE - Aggressive protection
hgz008Multi ULTIMATE mini
hgz009Fake - scams / fakes
hgz010Pop-Up Ads
hgz011Threat Intelligence Feeds
hgz012Threat Intelligence Feeds - Medium
hgz013Threat Intelligence Feeds - Mini
hgz014DoH/VPN/TOR/Proxy Bypass
hgz015Safesearch not supported
hgz016Dynamic DNS blocking
hgz017Badware Hoster blocking
hgz018Anti Piracy
hgz019Gambling
hgz020Gambling - Medium
hgz021Gambling - Mini

OISD Lists

CodeDescription
oisd0Domain Blocklist Ads
oisd1Domain Blocklist Big
oisd2Domain Blocklist NSFW

Dependencies

This role has no dependencies on other Ansible roles, but requires:

  • OPNsense firewall with API enabled
  • os-unbound-plus plugin installed
  • Unbound DNS service enabled
  • API key with Unbound management permissions
  • Ansible Vault for storing API credentials

Example Playbook

Basic Usage

---
- name: Configure OPNsense Unbound DNSBL
  hosts: mint-vm
  gather_facts: false

  vars_files:
    - ../../roles/opnsense_unbound_dnsbl/vars/dnsbl.yml

  tasks:
    - name: Configure DNSBL
      ansible.builtin.include_role:
        name: opnsense_unbound_dnsbl

Inline Variables

---
- name: Configure Unbound DNSBL
  hosts: mint-vm
  gather_facts: false

  vars:
    opnsense_unbound_dnsbl_config:
      enabled: "1"
      type:
        - ag    # AdGuard
        - sb    # Steven Black
        - atf   # ThreatFox
      lists: []
      allowlists:
        - trusted-domain.com
      blocklists: []
      wildcards: []
      nxdomain: "0"
      cache_ttl: "72000"
      description: "Basic ad and malware blocking"

  roles:
    - opnsense_unbound_dnsbl

What This Role Does

  1. Fetches existing DNSBL config via /api/unbound/settings/search_dnsbl
  2. Compares with desired config (enabled, type, lists, allowlists, etc.)
  3. Updates if different via /api/unbound/settings/set_dnsbl/{uuid}
  4. Applies DNSBL changes via /api/unbound/service/dnsbl
  5. Displays summary of DNSBL status

OPNsense API Endpoints

Search DNSBL Configuration

GET /api/unbound/settings/search_dnsbl
Authorization: Basic (API key:secret)

Returns current DNSBL configuration.

Update DNSBL Configuration

POST /api/unbound/settings/set_dnsbl/{uuid}
Authorization: Basic (API key:secret)
Content-Type: application/json

Request body:

{
  "blocklist": {
    "enabled": "1",
    "type": "ag,sb,atf",
    "lists": "",
    "allowlists": "trusted.com",
    "blocklists": "",
    "wildcards": "",
    "source_nets": "",
    "address": "",
    "nxdomain": "0",
    "cache_ttl": "72000",
    "description": "default"
  }
}

Apply DNSBL Changes

POST /api/unbound/service/dnsbl
Authorization: Basic (API key:secret)

Applies DNSBL blocklist configuration changes.

Configuration Examples

opnsense_unbound_dnsbl_config:
  enabled: "1"
  type:
    - ag       # AdGuard
    - sb       # Steven Black
    - atf      # ThreatFox malware
    - hgz003   # Hagezi PRO
    - oisd1    # OISD Big
  lists: []
  allowlists: []
  blocklists: []
  wildcards: []
  nxdomain: "0"
  cache_ttl: "72000"
  description: "Balanced ad/malware blocking"

Maximum Protection

opnsense_unbound_dnsbl_config:
  enabled: "1"
  type:
    - ag
    - sb
    - atf
    - hgz007   # Hagezi ULTIMATE
    - hgz009   # Fake/scams
    - hgz011   # Threat Intelligence
    - oisd1
  lists: []
  allowlists: []
  blocklists: []
  wildcards: []
  nxdomain: "0"
  cache_ttl: "72000"
  description: "Maximum protection"

Privacy Focused

opnsense_unbound_dnsbl_config:
  enabled: "1"
  type:
    - ep       # EasyPrivacy
    - hgz014   # DoH/VPN/TOR/Proxy Bypass
    - hgz018   # Anti Piracy
  lists: []
  allowlists: []
  blocklists: []
  wildcards: []
  nxdomain: "0"
  cache_ttl: "72000"
  description: "Privacy focused blocking"

Custom Lists

opnsense_unbound_dnsbl_config:
  enabled: "1"
  type:
    - ag
    - sb
  lists:
    - https://example.com/my-blocklist.txt
    - https://another.com/blocklist.txt
  allowlists:
    - trusted-site.com
    - another-trusted.com
  blocklists:
    - block-this.com
    - and-this.com
  wildcards:
    - "*.ads.example.com"
  nxdomain: "0"
  cache_ttl: "72000"
  description: "With custom lists"

Security Considerations

  • API Credentials: Stored in Ansible Vault
  • HTTPS: Uses SSL/TLS for API calls
  • Basic Auth: API key/secret authentication
  • Certificate Validation: Enabled by default
  • DNS-Level Blocking: Blocks threats before they reach devices

Troubleshooting

DNSBL not blocking domains

Cause: Unbound not reconfigured or DNSBL disabled

Solution: Check that enabled: "1" and verify reconfigure task ran

”Plugin not found” errors

Cause: os-unbound-plus plugin not installed

Solution: Install the plugin via OPNsense UI: System → Firmware → Plugins → os-unbound-plus

Legitimate sites blocked

Cause: Overly aggressive blocklists

Solution: Add domains to allowlists or use less aggressive lists

DNS resolution slow

Cause: Too many blocklists or low cache TTL

Solution: Reduce number of lists or increase cache_ttl

Best Practices

  1. Start conservative: Begin with basic lists (ag, sb) and add more as needed
  2. Monitor logs: Check Unbound logs for false positives
  3. Whitelist carefully: Add legitimate blocked domains to allowlists
  4. Use cache: Keep cache_ttl high (72000s = 20 hours) for performance
  5. Test changes: Verify DNS resolution after applying changes
  6. Document choices: Use description field to explain configuration

This role works well with:

  • opnsense_unbound_host_overrides: Manage DNS host overrides
  • opnsense_unbound_settings: Configure general Unbound settings
  • opnsense_firewall: Configure firewall rules for DNS traffic

License

MIT

Author

Created for homelab infrastructure management.