Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DANE Support #8

Closed
MHillyer opened this issue Mar 28, 2023 · 3 comments
Closed

DANE Support #8

MHillyer opened this issue Mar 28, 2023 · 3 comments
Assignees
Labels
enhancement New feature or request sending Relates to outbound/delivery processing
Milestone

Comments

@MHillyer
Copy link
Collaborator

MHillyer commented Mar 28, 2023

DANE for SMTP: https://datatracker.ietf.org/doc/html/rfc7672
DANE in General: https://datatracker.ietf.org/doc/html/rfc6698

TLSA resolution psuedocode: https://datatracker.ietf.org/doc/html/rfc6698#appendix-B.2

Implementing this requires solid DNSSEC support, and I'm not sure whether it currently exists.
Relevant issues in the upstream resolver library:

In addition, rustls doesn't have first-class support for DANE in general:

and it isn't clear how/if we can adapt the data and feed it into it verifier implementation

@MHillyer MHillyer added the enhancement New feature or request label Mar 28, 2023
@MHillyer MHillyer changed the title Add support for DANE DANE Mar 28, 2023
@MHillyer MHillyer changed the title DANE DANE Support Mar 28, 2023
wez pushed a commit that referenced this issue Jun 15, 2023
don't apply SMTP transparency decoding
@wez
Copy link
Collaborator

wez commented Aug 31, 2023

I believe that the current status of the dns resolver is that in order to get DNSSEC validation we:

  • Need to enable a crate level feature to compile in support for it
  • We need to enable validation in the resolver configuration via https://docs.kumomta.com/reference/kumo.dns/configure_resolver/
  • The consequence then is that all domains that are not signed (which is the vast majority) will effectively fail to resolve

That's an obviously untenable situation for us.

An alternative might be to explicitly configure a separate DNSSEC-only resolver instance and use that for DANE. If we can do that without exposing the bifurcation to the user that might work.

@wez
Copy link
Collaborator

wez commented Sep 1, 2023

The current status of my analysis is:

  • Without a high-fidelity DNSSEC enabled resolver, it is pointless to try to implement DANE; it provides no advantage over our existing OpportunisticInsecure TLS mode of operation, and in fact it could be harmful to attempt to use DANE information without correctly validating it. We cannot try to fill in the gaps by eg: making two queries with verification enabled and disabled, because there isn't enough information present in the responses to determine whether a domain is unsigned or failed to verify.
  • Assuming that we're able to extend trust-dns-resolver or source an alternative resolver, the next hurdle is correctly verifying the certificates presented during the TLS handshake. We need to propagate the set of TLSA records through to the connector and feed it into the certificate verifier, which requires the ability to parse and match.

The best way forward for us and the ecosystem is for trust-dns-resolver and rustls to be extended to support those things.

An alternative way forward is to source an alternative resolver (perhaps by embedding one via FFI) and switching to openssl for the transport security. It is unclear whether that would be faster to implement, but would have the advantage that the verification logic could then be borrowed from eg: postfix's implementation approach.

wez added a commit that referenced this issue Sep 8, 2023
This is set to true when the MX was resolved with DNSSEC validated.

refs: #8
wez added a commit that referenced this issue Sep 8, 2023
@wez wez added the sending Relates to outbound/delivery processing label Sep 13, 2023
@wez
Copy link
Collaborator

wez commented Oct 14, 2023

Will try getting this into the rust openssl wrapper and tackling it that way.
Here's my PR for the first part of this:

wez added a commit that referenced this issue Oct 27, 2023
This code isn't currently reachable (defaults to false), but allows
for a runtime selection between rustls and openssl-based tls.

refs: #8
wez added a commit that referenced this issue Oct 27, 2023
Adds the ability to enable DANE verification for SMTP.

It is disabled by default because correct operation also
requires working DNSSEC which in turns requires the use
of the unbound resolver.

When enabled, the SMTP client will use the OpenSSL DANE
implementation to verify the peer certificate.

refs: #8

```lua
local kumo = require 'kumo'

-- Called on startup to initialize the system
kumo.on('init', function()
  kumo.configure_accounting_db_path '/tmp/acct.db'

  kumo.dns.configure_unbound_resolver {
    options = {
      validate = true, -- enable DNSSEC validation
    },
    -- name_servers = { '1.1.1.1:53' },
  }

  kumo.set_diagnostic_log_filter 'rfc5321=trace,kumod::ready_queue=trace,kumod::smtp_dispatcher=trace,info'
  kumo.start_esmtp_listener {
    listen = '0.0.0.0:2025',
    relay_hosts = { '127.0.0.1', '192.168.1.0/24' },
  }

  kumo.configure_local_logs {
    log_dir = '/var/tmp/kumo-logs',
    max_segment_duration = '1s',
  }

  kumo.start_http_listener {
    listen = '0.0.0.0:8000',
    trusted_hosts = { '127.0.0.1', '::1' },
  }

  kumo.define_spool {
    name = 'data',
    path = '/var/tmp/kumo-spool/data',
    kind = 'RocksDB',
  }

  kumo.define_spool {
    name = 'meta',
    path = '/var/tmp/kumo-spool/meta',
    kind = 'RocksDB',
  }
end)

kumo.on('get_egress_pool', function(pool_name)
  if pool_name == 'pool0' then
    return kumo.make_egress_pool {
      name = 'pool0',
      entries = {
        { name = 'source0' },
      },
    }
  end

  error("I don't know how to configure pool " .. pool_name)
end)

kumo.on('get_egress_source', function(source_name)
  return kumo.make_egress_source {
    name = source_name,
    socks5_proxy_server = '127.0.0.1:5000',
    socks5_proxy_source_address = '0.0.0.0',
  }
end)

kumo.on(
  'get_egress_path_config',
  function(routing_domain, egress_source, site_name)
    print('get_egress_path_config', routing_domain, egress_source, site_name)
    return kumo.make_egress_path {
      enable_tls = 'Disabled',
      enable_dane = true,
      idle_timeout = '5s',
      data_timeout = '10s',
      data_dot_timeout = '15s',
      prohibited_hosts = {},
    }
  end
)

kumo.on('get_queue_config', function(domain, tenant, campaign)
  return kumo.make_queue_config {
    egress_pool = 'pool0',
  }
end)
```
wez added a commit that referenced this issue Oct 27, 2023
@wez wez closed this as completed Nov 29, 2023
@MHillyer MHillyer added this to the Fall Release milestone Nov 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request sending Relates to outbound/delivery processing
Projects
Status: Done
Development

No branches or pull requests

2 participants