mirror of
https://github.com/KumoCorp/kumomta.git
synced 2026-09-09 16:02:44 +00:00
We weren't checking the DNSSEC status for A/AAAA when considering DANE, and were overly permissive in a couple of related cases. This diff ended up fairly large because the bulk of it is to facilitate testing. refs: https://github.com/KumoCorp/kumomta/issues/543 refs: https://github.com/KumoCorp/kumomta/pull/517
118 lines
3.3 KiB
Lua
118 lines
3.3 KiB
Lua
-- A minimal source policy for the DANE integration tests.
|
|
--
|
|
-- It routes mail for `dane.example` via the real MX resolution path (so that
|
|
-- DANE engages; mx_list would bypass it) and installs a TestResolver whose
|
|
-- zone and DNSSEC secure status are driven by env vars set by the test:
|
|
--
|
|
-- KUMOD_DANE_TLSA the TLSA rdata to publish (e.g. "3 1 1 <hex>"), or unset
|
|
-- KUMOD_DANE_SECURE "true" to mark the zone DNSSEC validated
|
|
-- KUMOD_DANE_SERVFAIL "true" to make the TLSA lookup return SERVFAIL
|
|
local kumo = require 'kumo'
|
|
|
|
local TEST_DIR = os.getenv 'KUMOD_TEST_DIR'
|
|
local SINK_PORT = tonumber(os.getenv 'KUMOD_SMTP_SINK_PORT')
|
|
|
|
local function configure_resolver()
|
|
-- The TLSA record is published at _<port>._tcp.<mxhost>, where <port> is the
|
|
-- port we actually connect on; we set the egress source remote_port to the
|
|
-- sink port, so use that here too.
|
|
local zone = string.format [[
|
|
$ORIGIN dane.example.
|
|
@ 3600 IN MX 10 mx.dane.example.
|
|
mx 3600 IN A 127.0.0.1
|
|
]]
|
|
|
|
local tlsa = os.getenv 'KUMOD_DANE_TLSA'
|
|
if tlsa then
|
|
zone = zone
|
|
.. string.format('_%d._tcp.mx 3600 IN TLSA %s\n', SINK_PORT, tlsa)
|
|
end
|
|
|
|
local config = {
|
|
zones = {
|
|
{
|
|
zone = zone,
|
|
secure = os.getenv 'KUMOD_DANE_SECURE' == 'true',
|
|
},
|
|
},
|
|
}
|
|
|
|
if os.getenv 'KUMOD_DANE_SERVFAIL' == 'true' then
|
|
config.servfail = { string.format('_%d._tcp.mx.dane.example', SINK_PORT) }
|
|
end
|
|
|
|
kumo.dns.configure_test_resolver(config)
|
|
end
|
|
|
|
kumo.on('init', function()
|
|
-- Keep accounting state isolated to this test; the defaults live in a shared,
|
|
-- possibly non-writable location.
|
|
kumo.configure_accounting_db_path ':memory:'
|
|
kumo.aaa.configure_acct_log {
|
|
log_dir = TEST_DIR .. '/acct',
|
|
max_segment_duration = '1s',
|
|
}
|
|
|
|
configure_resolver()
|
|
|
|
kumo.start_esmtp_listener {
|
|
listen = '127.0.0.1:0',
|
|
relay_hosts = { '0.0.0.0/0' },
|
|
}
|
|
|
|
kumo.start_http_listener {
|
|
listen = '127.0.0.1:0',
|
|
}
|
|
|
|
kumo.configure_local_logs {
|
|
log_dir = TEST_DIR .. '/logs',
|
|
max_segment_duration = '1s',
|
|
}
|
|
|
|
kumo.define_spool {
|
|
name = 'data',
|
|
path = TEST_DIR .. '/data-spool',
|
|
}
|
|
|
|
kumo.define_spool {
|
|
name = 'meta',
|
|
path = TEST_DIR .. '/meta-spool',
|
|
}
|
|
end)
|
|
|
|
kumo.on('get_queue_config', function(_domain, _tenant, _campaign)
|
|
-- No mx_list: use the default smtp protocol, which resolves the routing
|
|
-- domain's MX records via DNS (our TestResolver). An explicit egress pool
|
|
-- ensures our get_egress_source (and thus remote_port) is honored.
|
|
return kumo.make_queue_config {
|
|
egress_pool = 'dane',
|
|
}
|
|
end)
|
|
|
|
kumo.on('get_egress_pool', function(pool_name)
|
|
return kumo.make_egress_pool {
|
|
name = pool_name,
|
|
entries = { { name = 'dane' } },
|
|
}
|
|
end)
|
|
|
|
kumo.on('get_egress_source', function(source_name)
|
|
return kumo.make_egress_source {
|
|
name = source_name,
|
|
-- Direct the connection at the sink's ephemeral port. This is also the
|
|
-- port used to form the TLSA query name.
|
|
remote_port = SINK_PORT,
|
|
}
|
|
end)
|
|
|
|
kumo.on('get_egress_path_config', function(_domain, _source_name, _site_name)
|
|
return kumo.make_egress_path {
|
|
enable_dane = true,
|
|
-- When DANE does not apply (insecure chain), fall back to opportunistic
|
|
-- TLS that tolerates the sink's self-signed certificate.
|
|
enable_tls = 'OpportunisticInsecure',
|
|
-- Allow connecting to the loopback sink.
|
|
prohibited_hosts = {},
|
|
}
|
|
end)
|