Files
kumomta/docs/reference/kumo.dns/define_resolver.md
T
Wez Furlong b73d81b0fc dns: utilities and plumbing for querying DNSBLs
This commit does some plumbing work to allow defining alternative
resolvers with different names that can be used to query different
upstream DNS servers.

This is most useful when implement DNSBLs where you might have a custom
DNS server configured with one or more RBL zones that is reserved purely
for RBL lookups.

The plumbing introduces a more regular syntax for defining one of the
various implementations of the Resolver trait, as well as a new
Aggregate resolver impl that can query across multiple Resolvers until a
query is satisfied.

This allows some interesting and powerful configurations, such as
loading a static zone file into memory to query it directly, and/or
blending that together with querying either the system or some other
upstream DNS server as a fallback.

The various lookup functions (except for MX!) have been updated to
accept an optional alternate resolver name, so that they work together
with the above.

A new rbl_lookup function is also provided as a convenience for querying
the most common form of RBLS.

ptr_host and reverse_ip are two string utility functions that are likely
not going to be widely used, but are very convenient to have when you
do have a usecase that requires it!

closes: https://github.com/KumoCorp/kumomta/issues/269
2025-10-10 18:45:52 +01:00

3.2 KiB

define_resolver

kumo.dns.define_resolver(NAME, CONFIG)

{{since('dev')}}

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:

kumo.dns.define_resolver('rbl', {
  Hickory = {
    name_servers = {
      '10.0.0.1:53',
    },
  },
})

You can then query it:

local answer, reason = kumo.dns.rbl_lookup(IP, 'rbl.domain', 'rbl')

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!"
  ]],
    },
  },
})

You can then query it:

local answer, reason = kumo.dns.rbl_lookup('10.0.0.1', 'rbl.domain', 'rbl')

This mode of operation was originally intended for testing, but may prove useful in other situations.

System Default

kumo.dns.define_resolver('myresolver', 'HickorySystemConfig')

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.

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:

kumo.dns.define_resolver('rbl', {
  Unbound = {
    name_servers = {
      '10.0.0.1:53',
    },
  },
})

You can then query it:

local answer, reason = kumo.dns.rbl_lookup(IP, 'rbl.domain', 'rbl')

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',
  },
})