OpenBSD Handbook

    Theme
    • Part I. Install & Configure
      • Introduction to OpenBSD
      • Installing OpenBSD
      • The X Window System
      • Networking on OpenBSD
      • System Configuration
      • OpenBSD Basics
      • Managing Software: Packages and Ports
    • Part II. Daily Operations
      • OpenBSD Desktop Environments
      • Multimedia
      • Printing
      • Linux Compatibility
      • Windows Compatibility
      • Games
    • Part III. System Administration
      • Virtualization
      • Storage and File Systems
      • Updating and Upgrading
      • Localization
      • The OpenBSD Boot Process
      • Security
    • Part IV. Networking & Daemons
      • Services
        • Database
          • MariaDB
          • PostgreSQL
          • Redis
          • memcached
        • Directory
          • YP (NIS)
          • LDAP
        • File
          • NFS
          • Samba
        • FTP Services
          • ftpd
          • ProFTPD
          • vsftpd
          • Pure-FTPd
          • TFTP
        • Mail
          • OpenSMTPD Mail Server
          • Dovecot IMAP and POP3 Server
          • Postfix
          • Exim
          • Rspamd
        • Name
          • Unbound DNS Resolver
          • NSD Authoritative DNS Server
          • BIND DNS Server
        • Networking
          • OpenBGPD
          • rad
          • DHCP on OpenBSD
          • slaacd
        • Web
          • Apache HTTP Server
          • nginx Web Server
          • OpenBSD httpd Web Server
          • relayd Reverse Proxy
        • Logging
          • syslogd
        • Monitoring
          • SNMP
        • Remote Access
          • Audit OpenSSH
          • OpenSSH Server
        • File Synchronization
          • rsync
        • Messaging
          • RabbitMQ Message Broker
        • Time
          • NTP Time Synchronization
        • Load Balancing
          • Build Redundant Load-Balanced Gateways
          • Load Balance Services with NAT or DSR
          • Build an HA HTTPS Load Balancer
      • PF
        • pfctl cheat sheet
        • PF Anchors
        • PF Filter Rules
        • PF Forwarding
        • PF Lists and Macros
        • PF Load Balancing
        • PF Logging
        • PF NAT
        • PF Options
        • PF Policies
        • PF Shortcuts
        • PF Tables
      • Advanced Networking
        • High Availability and State Replication
        • Multi-WAN and Policy-Based Routing
        • VPN and Cryptographic Tunneling
        • Classic and Lightweight Tunnels
        • IPv6 at Scale
        • QoS and Traffic Shaping
        • MPLS and Label Distribution
        • Network Services at Scale
        • Virtualization and Host Networking
        • Large-Scale L2 and L3 Design
        • Telemetry, Logging, and Flow Export
        • Hardening and Operational Safety
        • Reference Architectures
        • Troubleshooting Playbooks
      • Serial Communication
    • Part V. Miscellaneous
      • Virtualization Cheat Sheet
      • OpenBSD Cheatsheet
      • How-to Guides
        • Installation and First Boot
          • Complete the First 30 Minutes After Installation
          • Check Hardware Compatibility Before Installing
          • Bootstrap Wi-Fi Firmware Without Ethernet
          • Run OpenBSD as a Virtual Machine Guest
          • Install OpenBSD on a VPS or Cloud Server
          • Install OpenBSD with Full-Disk Encryption
          • Dual-Boot OpenBSD on a UEFI System
          • Automate OpenBSD Installation with Autoinstall and PXE
        • Desktops and Laptops
          • Set Up OpenBSD as a Laptop or Workstation
          • Configure Laptop Power Management
          • Troubleshoot Web Browsers on OpenBSD
          • Use Plan 9 Tools on OpenBSD
          • Build a Minimal Desktop with suckless Tools
          • Install Z shell (zsh)
        • Networking and Remote Access
          • Create an Administrator Account with doas and SSH Keys
          • Configure Secure Remote Access with OpenSSH
          • Use FIDO Security Keys with OpenSSH
          • Configure Wi-Fi Roaming and Wired Failover
          • Troubleshoot PF, NAT, and Routing
          • Route Multiple VLANs with PF
          • Configure a Road-Warrior WireGuard VPN
          • Route IPv6 Networks without NAT
          • Test OpenBGPD with Two Providers
          • Unlock an Internal Service with an SSH Key
          • Build a Simple Router and Firewall
        • Servers and Services
          • Set Up WordPress on OpenBSD
          • Build a Mail Server with OpenSMTPD, Dovecot, and Rspamd
        • Security, Maintenance and Recovery
          • Establish a Conservative Security Baseline
          • Recover Access and Reset the Root Password
          • Collect OpenBSD Diagnostic Evidence
          • Troubleshoot Package Installation and Update Failures
          • Schedule Recurring Maintenance
          • Monitor an OpenBSD System
          • Back Up and Restore an OpenBSD System
          • Configure softraid RAID1
          • Recover an OpenBSD System That Does Not Boot
        • Building, Automation and Virtual Machines
          • Manage OpenBSD with Ansible
          • Build Third-Party Software from Ports
          • Build OpenBSD from Source
          • Plan a Docker Workload Migration to OpenBSD
      • OpenBSD for Linux Users
      • OpenBSD for FreeBSD Users
      • OpenBSD for macOS Users
    • OpenBSD FAQ
    • OpenBSD Architectures
      • OpenBSD Package Search
        • Synopsis
        • Choose the Resolver Role
        • Create the Configuration
        • Add Local Names
        • Add PF Rules
        • Enable and Test Unbound
        • Direct Clients to the Resolver
        • Make the Router Use Unbound
        • Optional Remote Control
        • Troubleshooting

        Unbound DNS Resolver

        Synopsis #

        unbound(8) is a validating, recursive, caching DNS resolver included in the OpenBSD base system. It is distinct from unwind(8) , which integrates local resolution with changing network proposals, and nsd(8) , which serves authoritative zones.

        This chapter configures Unbound as a LAN resolver on 10.10.10.1. It leaves the router’s own /etc/resolv.conf under resolvd(8) control. This separation allows the router to keep using its normal local resolver path while Unbound listens only on the LAN address.

        Unbound is included in base but is not the automatically integrated default resolver. Enabling the daemon does not by itself make either the local host or LAN clients use it.

        Choose the Resolver Role #

        Use Unbound to provide recursive DNS service to a defined set of clients, such as a LAN. Use unwind for an automatically integrated resolver on a workstation or mobile host. Use nsd for authoritative DNS data.

        Do not expose recursive service to the Internet. An open resolver can be abused for reflection attacks and consumes resources on behalf of untrusted clients.

        A LAN client queries Unbound, which answers locally or performs recursionA client on 10.10.10.0/24 sends DNS queries to the Unbound resolver at 10.10.10.1 using UDP or TCP port 53. Unbound can use configured local data or a valid cached answer. When needed it queries authoritative servers, following the DNS hierarchy from root through TLD to the relevant zone, reusing cached information when available. Answers return through Unbound to the client. resolvd manages resolver configuration; it does not answer DNS queries.Who answers a DNS query?Clients on 10.10.10.0/24Configured DNS server: 10.10.10.1DNS query and answerUDP or TCP port 53Unbound: 10.10.10.1Uses local data or a valid cached answerPerforms recursion when neededValidates DNSSEC-signed answersQueries and replies as neededCached referrals can skip stepsAuthoritative DNS serversRoot, TLD, and the relevant zoneUnbound follows their referralsresolvd manages /etc/resolv.conf.It configures DNS; it does not answer queries.
        LAN clients query Unbound. It uses local data or its cache when possible and queries authoritative DNS servers when needed.

        Create the Configuration #

        The default configuration path is /var/unbound/etc/unbound.conf. Preserve any existing local policy and create a protected backup before replacing it.

        For a resolver at 10.10.10.1 serving 10.10.10.0/24, use:

        server:
            interface: 10.10.10.1
        
            access-control: 0.0.0.0/0 refuse
            access-control: 10.10.10.0/24 allow
        
            hide-identity: yes
            hide-version: yes
            harden-glue: yes
            harden-dnssec-stripped: yes
        
            auto-trust-anchor-file: "/var/unbound/db/root.key"
        

        The refusal rule denies queries from clients outside the allowed network. Add IPv6 interfaces and access-control entries only for prefixes that are actually routed and protected.

        Initialize or update the DNSSEC root trust anchor with unbound-anchor(8) :

        doas unbound-anchor -a /var/unbound/db/root.key
        doas chown _unbound:_unbound /var/unbound/db /var/unbound/db/root.key
        

        The command can use built-in trust material when the network is unavailable. The Unbound account must be able to update the anchor and its directory when RFC 5011 tracking is enabled.

        Validate the configuration with unbound-checkconf(8) :

        doas unbound-checkconf /var/unbound/etc/unbound.conf
        

        Add Local Names #

        Small static overrides can use local-zone and local-data in the server section:

            local-zone: "internal.example." static
            local-data: "router.internal.example. IN A 10.10.10.1"
            local-data: "files.internal.example. IN A 10.10.10.20"
        

        Use a trailing dot for complete DNS names. A static local zone answers only data configured for that zone and returns negative answers for other names below it. Larger or dynamically maintained authoritative zones belong on an authoritative server.

        Add PF Rules #

        Permit DNS from the controlled LAN to the resolver address over both UDP and TCP:

        lan = "vlan10"
        lan_net = "10.10.10.0/24"
        
        pass in on $lan proto { udp, tcp } from $lan_net to 10.10.10.1 port domain
        

        TCP is required for responses that do not fit in UDP, zone-related operations where allowed, and normal fallback behavior. Do not add a general Internet-facing port 53 rule.

        Parse the complete policy before loading it:

        doas pfctl -nf /etc/pf.conf
          # Check syntax without changing the active ruleset
        doas pfctl -f /etc/pf.conf
          # Load the verified policy
        

        Enable and Test Unbound #

        Enable and start the daemon with rcctl(8) :

        doas rcctl enable unbound
          # Start Unbound during boot
        doas rcctl start unbound
          # Start recursive service now
        doas rcctl check unbound
          # Confirm the daemon remains running
        

        Confirm that only the intended address and port are listening:

        netstat -na -f inet | grep '\.53 '
        

        From a LAN client, query the resolver directly with host(1) :

        host openbsd.org 10.10.10.1
          # Test public recursive resolution
        host router.internal.example 10.10.10.1
          # Test the local override
        

        Repeat a public query and inspect service logs when resolution is slow or fails. Use tcpdump(8) to separate client reachability from upstream recursion:

        doas tcpdump -ni vlan10 port 53
          # Observe client queries and replies
        doas tcpdump -ni egress port 53
          # Observe recursive queries to authoritative servers
        

        Direct Clients to the Resolver #

        Static clients can place nameserver 10.10.10.1 in their resolver configuration. DHCP service should advertise 10.10.10.1 as the domain-name server for the corresponding subnet.

        Do not make /etc/resolv.conf immutable. On OpenBSD clients, resolvd merges proposals from DHCP, SLAAC, VPNs, and supported network devices. Check which resolver is selected when a client moves between networks.

        Make the Router Use Unbound #

        The LAN-only design does not change the router’s local resolver. If the router must also query Unbound, add a loopback listener to unbound.conf, permit loopback clients, and configure local DNS resolution to use it.

        One possible stable-server design is:

        server:
            interface: 127.0.0.1
            interface: 10.10.10.1
            access-control: 127.0.0.0/8 allow
            access-control: 10.10.10.0/24 allow
        

        Before changing the router’s resolver, check how resolvd, unwind, and DHCP or SLAAC proposals update /etc/resolv.conf. Leave resolvd enabled if Unbound serves only LAN clients.

        Optional Remote Control #

        unbound-control(8) requires a configured control channel. Do not assume that it works merely because the resolver daemon is running.

        To use unbound-control, configure a local Unix control socket or use unbound-control-setup as described in the manual. Keep the control endpoint local and restrict filesystem access. Then validate commands such as status, statistics, reload, and cache flush in a maintenance window.

        Troubleshooting #

        • A startup failure should be investigated with unbound-checkconf, service logs, address ownership, and existing port 53 listeners.
        • Client timeouts with no packets on the LAN interface indicate client configuration, routing, VLAN, or PF problems.
        • Client packets with no upstream queries indicate Unbound access control, configuration, or DNSSEC state.
        • Upstream queries with no replies indicate routing, provider filtering, or upstream reachability.
        • SERVFAIL can be a correct DNSSEC-validation result. Check time synchronization and validation logs before weakening DNSSEC.
        • Local names that return NXDOMAIN should be checked for trailing dots, zone type, and exact owner names.

        See Configure Name Services for authoritative and recursive DNS roles and Build a Simple Router and Firewall for a LAN service example.

        Report a bug
        • Synopsis
        • Choose the Resolver Role
        • Create the Configuration
        • Add Local Names
        • Add PF Rules
        • Enable and Test Unbound
        • Direct Clients to the Resolver
        • Make the Router Use Unbound
        • Optional Remote Control
        • Troubleshooting