define_resolver
Since: Version 2025.12.02-67ee9e96
The functionality described in this section requires version 2025.12.02-67ee9e96 of KumoMTA, or a more recent version.
This function defines an alternative resolver from the default configured via configure_resolver, and gives it a name.
The alternate resolver name can then be optionally passed as a parameter to a
number of other kumo.dns functions.
The intended use case is to define an alternate resolver that points to an rbldnsd or similar specialized resolver that provides access to a DNSBL.
The NAME parameter is a string that defines the name of the alternate resolver.
The CONFIG parameter defines the parameters for the resolver. It can have
one of the following shapes:
Note
This function should be called only from inside your init event handler.
Hickory with an explicit upstream
If you have rbldnsd or similar available on 10.0.0.1:53, then you might use this:
You can then query it:
Test or static DNS
If you have fixed and locally available zone data, then you can query that explicitly:
kumo.dns.define_resolver('rbl', {
Test = {
zones = {
[[
$ORIGIN rbl.domain.
1.0.0.10 30 IN A 127.0.0.2
1.0.0.10 300 TXT "Blocked for a very good reason!"
]],
},
},
})
This mode of operation was originally intended for testing, but may prove useful in other situations.
DNSSEC secure zones and servfail
Since: Dev Builds Only
The functionality described in this section requires a dev build of KumoMTA. You can obtain a dev build by following the instructions in the Installation section.
Each entry in zones may be either a plain zone string (treated as an
insecure, non-DNSSEC zone, which is the original behavior) or a table of the
form { zone = "...", secure = true }. When secure is true, answers from
that zone are reported as DNSSEC-validated. This is required to exercise
features that only trust securely-resolved data, such as
DANE.
The Test resolver also accepts an optional servfail list of owner names;
any lookup for one of those names returns SERVFAIL. This is useful for
exercising failure-handling paths (for example, DANE downgrade resistance).
kumo.dns.define_resolver('secure-test', {
Test = {
zones = {
-- A DNSSEC-validated (secure) zone
{
zone = [[
$ORIGIN dane.example.
@ 3600 IN MX 10 mx.dane.example.
mx 3600 IN A 127.0.0.1
_25._tcp.mx 3600 IN TLSA 3 1 1 abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789
]],
secure = true,
},
-- A plain string entry is treated as an insecure zone
[[
$ORIGIN insecure.example.
@ 3600 IN A 127.0.0.2
]],
},
-- Any lookup for these names returns SERVFAIL
servfail = {
'_25._tcp.broken.example',
},
},
})
These options are primarily intended for testing.
System Default
Parses the system resolver configuration and applies that to a separate instance of the hickory DNS resolver client. This is equivalent to the default resolver settings in kumomta.
If you would like to start from the system upstreams and then layer your own resolver options on top, see kumo.dns.load_resolv_conf (Since: Dev Builds Only).
Unbound with an explicit upstream
Note
We generally recommend sticking with Hickory unless you have a very good reason.
If you have rbldnsd or similar available on 10.0.0.1:53, then you might use this:
You can then query it:
Aggregating Different Resolvers
If you have a mixture of local zone files and a remote DNS, then you can mix them together; have the local zones queried before falling back to a remote host.
In the example below, the local zone is used first before falling back to querying the upstream specified by the system.
kumo.dns.define_resolve('aggregate', {
Aggregate = {
-- The value of `Aggregate` here is an array style table
-- listing out one of the CONFIG options shown in the
-- examples above.
-- First we have a Test setup
Test = {
zones = {
[[
$ORIGIN 0.0.127.in-addr.arpa.
1 30 IN PTR localhost.
]],
},
},
-- Then we have a system default setup
'HickorySystemConfig',
},
})