Tags and Views

The tags and views functionality make it possible to send specific DNS answers based on the IP address of the client.


The tags functionality makes it possible to divide incoming client queries in categories (tags), and use local-zone: and local-data: information for these specific tags.

Before these tags can be used, you need to define them in the Unbound configuration using define-tag:. In this example, a tag for domains containing malware is set, along with one for domains of gambling sites:

define-tag: "malware gambling"

Now that Unbound is aware of the existing tags, it is possible to start using them.

The access-control-tag: element is used to specify the tag to use for client source address. Alternatively, the interface-tag: element is used to specify the tag to use for clients on a specific listening interface. You can add multiple tags to these elements:

# Per client IP ...
access-control-tag: "malware"
access-control-tag: "malware"
access-control-tag: "gambling"
access-control-tag: "malware gambling"

# ... and/or per listening interface
interface-tag: eth0 "malware"
interface-tag: "malware gambling"


Any access-control*: setting overrides all interface-*: settings for targeted clients.

Unbound will create a *-tag element with the “allow” type if the IP address block / listening interface in the *-tag element does not match an existing access control rule.

When a query comes in that is marked with a tag, Unbound starts searching its local-zone tree for the best match. The best match is the most specific local-zone with a matching tag, or without any tag. That means that local-zones without any tag will be used for all queries and tagged local-zones only for queries with matching tags.

Adding tags to local-zones can be done using the local-zone-tag: element:

local-zone: malwarehere.example refuse
local-zone: somegamblingsite.example static
local-zone: matchestwotags.example transparent
local-zone: notags.example inform

local-zone-tag: malwarehere.example malware
local-zone-tag: somegamblingsite.example malware
local-zone-tag: matchestwotags.example "malware gambling"

A local-zone can have multiple tags, as illustrated in the example above. The tagged local-zones will be used if one or more tags match the query. So, the matchestwotags.example local-zone will be used for all queries with at least the malware or gambling tag. The used local-zone type will be the type specified in the matching local-zone. It is possible to depend the local-zone type on the client and tag combination. Setting tag specific local-zone types can be done using access-control-tag-action: and/or interface-tag-action::

# Per client IP ...
access-control-tag-action: "malware" refuse
access-control-tag-action: "malware" deny

# ... and/or per listening interface
interface-tag-action: eth0 "malware" refuse
interface-tag-action: "malware" deny

In addition to configuring a local-zone type for specific clients/tag match, it is also possible to set the used local-data RRs. This can be done using the access-control-tag-data: and/or interface-tag-data: elements:

# Per client IP ...
access-control-tag-data: "gambling" "A"

# ... and/or per listening interface
interface-tag-data: "gambling" "A"

Sometimes you might want to override a local-zone type for a specific IP prefix or interface, regardless the type configured for tagged and untagged local zones, and regardless the type configured using access-control-tag-action: and/or interface-tag-action:. This override can be done using local-zone-override:.


Tags make is possible to divide a large number of local-zones in categories, and assign these categories to a large number of IP address blocks. As tags on the clients and local-zones are stored in bitmaps, it is advised to keep the number of tags low. Specifically for client prefixes (i.e., access-control-tag*:), if a lot of clients have their own local-zones, without sharing these to other IP prefixes, it can result in a large amount tags. In this situation it is more convenient to give the clients’ IP prefix its own tree containing local-zones. Another benefit of having a separate local zone tree is that it makes it possible to apply a local-zone action to a part of the domain space, without having other local-zone elements of subdomains overriding this. Configuring a client specific local-zone tree can be done using views.

A view is a named list of configuration options. The supported view configuration options are local-zone: and local-data:.

A view is configured using a view: clause. There may be multiple view clauses, each with a unique name. For example:

    name: "firstview"
    local-zone: example.com inform
    local-data: 'example.com TXT "this is an example"'
    local-zone: refused.example.nl refuse

Mapping a view to a client can be done using the access-control-view: element:

access-control-view: firstview

Alternatively, mapping a view to clients in a specific interface can be done using the interface-view: element:

interface-view: eth0 firstview

By default, view configuration options override the global configuration outside the view. When a client matches a view it will only use the view’s local-zone tree. This behaviour can be changed by setting view-first: to yes. If view-first is enabled, Unbound will try to use the view’s local-zone tree, and if there is no match it will search the global tree.

See also

View Options in the unbound.conf(5) manpage.