Commit Graph

341 Commits

Author SHA1 Message Date
Wez Furlong 4ed60d30a1 docs: update for release 2025-01-29 17:05:37 -07:00
Wez Furlong ea8f2be678 docs: add weird period example to throttle docs 2025-01-29 09:45:04 -07:00
Wez Furlong 87e0939f43 throttle: expose max_burst throttle spec
This was always present, it just wasn't something we provided a syntax
to specify.

max_burst allows you to control how quickly your throttle budget will
be consumed over the throttle time period.

The default max_burst is equal to the limit you specify, allowing
the full budget to be instantaneously consumed.

refs: https://github.com/KumoCorp/kumomta/issues/326
2025-01-29 09:22:57 -07:00
Wez Furlong f9d8ceee9d inspect-sched-q: add now time to the response
This is useful when sanity checking the due times vs. the current time
2025-01-24 15:28:37 -07:00
Wez Furlong e474516b01 add reconnect_strategy option
This controls what we do in an smtp session when we experience a
disconnect during message sending; do we give up on the session,
continue with the connection plan, or try to connect to the same
host again and continue sending any additional messages there?
2025-01-24 13:43:49 -07:00
Wez Furlong 6841841283 first run at an inspect-sched-q command
This can return a sample (or all) of the messages as well as
some additional queue metadata for a named scheduled queue.

refs: #231
2025-01-23 17:10:41 -07:00
Wez Furlong 01c52eef03 docs: update for 2025.01.23-7273d2bc release 2025-01-23 13:49:35 -07:00
Wez Furlong bb66d06169 docs: add opportunistic_tls_reconnect_on_failed_handshake to changelog 2025-01-23 07:32:08 -07:00
Wez Furlong c215ed9c2f rfc5321: add enable_rset and enable_pipelining options
These control whether we'll use RSET and/or PIPELINING when
sending via SMTP.
2025-01-23 07:20:00 -07:00
Wez Furlong cf6f3540e7 Add new Delay log record type
The purpose of this record is to log additional context about why
a message might end up in the scheduled queue when it hasn't
logged a TransientFailure.

There are a few situations around handling throttles and limits
where we might put a message back into the scheduled queue, without also
logging a TransientFailure record. It's possible that we should
reconsider some of those, but for the moment, there is an observability
hole that needs to be filled.

What this commit does is introduce an `InsertContext` which can hold one
or more `InsertReason`s about why a message is being inserted into the
scheduled queue.

There are 3 primary reasons for insertion:

* Received - the message was just received/injected
* Enumerated - the message was discovered in spool enumeration
* DueTimeWasReached - the message is now due for delivery and is being
  popped off the scheduled queue

The additional reasons can be added to the context to provide more
color about what happened.

When a message is added to the scheduled queue, the accumulation
in the InsertContext is examined, and if the context doesn't
indicate that the message was Enumerated and it wasn't also
already logged as a TransientFailure, a `Delay` record is
logged.

The `Delay` record includes in its `response.content` the ordered set of
InsertReasons as well as the delay duration and due time.

Logging Delay records might place undesirable pressure on the
logging storage, so you may wish to disable it via:

```lua
kumo.configure_local_logs {
  per_record = {
    Delay = {
      -- Suppress Delay records
      enable = false
    }
  }
}
```

or similar.
2025-01-17 13:21:47 -07:00
Wez Furlong c1575bba6d docs: mention that timer:done() returns seconds
I didn't include this in the recent code change that added the
return value.
2025-01-11 06:52:10 -07:00
Wez Furlong 9e823dc352 add kumo.time lua module, with new timer object
The timer object can track latencies in lua code and is helpful for
ad-hoc, explicit "profiling" in your policy script: the latencies are
exported via a prometheus histogram.
2025-01-09 15:36:30 -07:00
Wez Furlong 49eb0a634c smtp_server_ehlo: pass in and allow returning a list of extensions
This is helpful in situations where you need to do things that
are not strictly supported but might just happen to squeak by
if support is claimed for them.
2025-01-09 11:03:11 -07:00
Wez Furlong 4375958da2 docs: tag available_parallelism with threadpool 2025-01-08 16:00:17 -07:00
Wez Furlong cd2fea5d99 docs: fix typo on configure_unbound_resolver page 2025-01-08 15:55:04 -07:00
Wez Furlong 1b82b54bc8 docs: tag set_logging_threads too 2025-01-08 15:54:05 -07:00
Wez Furlong 2dc9b2b319 docs: setup tags to find threadpool related options 2025-01-08 15:52:06 -07:00
Wez Furlong d436c08858 docs: add kumo.dkim.set_signing_threads
This was added in the last release, but the docs were overlooked.
2025-01-08 15:32:08 -07:00
Wez Furlong 58a4b9921a docs: format recent kafka changes 2025-01-08 15:31:38 -07:00
Wez Furlong 44c0c029e4 throttle: introduce LimitSpec and force_local mode
This brings parity with ThrottleSpec in allowing for explicitly
local limits, even when redis sharing is enabled.
2025-01-06 06:53:12 -07:00
Nathalie Cai a3c7fe7d00 add send_batch method to kafka mod (#324)
* add send_batch method to kafka mod

* add error messages to returned value and don't log it as error

* add kafka send_batch doc

---------

Co-authored-by: ncai <ncai@chapsvision.com>
2025-01-03 09:57:40 -07:00
Wez Furlong ff8c0ccff2 Expose ready queue states via api, and in kcli queue-summary
This adds connection limit/throttle states to the readyq rows
in `kcli queue-summary`, alongside where we would show the
suspension state.

This makes it easier to understand when a given egress path
might be hitting connection limits.
2024-12-21 07:44:29 -07:00
Wez Furlong 39bbc0953e switch to DeferredInjectionRebind for deferred->fully realized
It's confusing to have 2 Delivery records, even if there are other
fields that distinguish between the events.
2024-12-19 10:14:26 -07:00
Wez Furlong cc90c278fa docs: fixup mermaidjs issue
This used to work fine, but recently started to bleed through
some control characters

closes: https://github.com/KumoCorp/kumomta/issues/323
2024-12-18 06:41:45 -07:00
Wez Furlong 8be4ad82a1 add basic outbound LMTP support
This enables LMTP over TCP by setting `use_lmtp = true` in the
egress path configuration.

refs: https://github.com/KumoCorp/kumomta/issues/267
2024-12-17 06:48:52 -07:00
Wez Furlong 05295e415a add opportunistic_tls_reconnect_on_failed_handshake option
When used together with an Opportunistic TLS mode, if the handshake
or subsequent EHLO fails, we will re-connect to the current host
and disable TLS.

This is implemented as a recursive solution, which I'm not totally
keen on, but the recursion is limited to a single level so it's
not so bad.
2024-12-16 15:20:13 -07:00
Wez Furlong 5f19f7ce04 add deferred_queue option to the smtp listener
This option should be used with caution, and ideally only
for trusted networks.

The purpose is to absorb the latency of post-DATA processing
and hide it from the trust injector.

It defers processing that would normally happen in smtp_server_message_received
and instead will, at some (ideally) near-future time trigger an
smtp_server_message_deferred_inject event instead.

This will marginally increase your average injection latency but should
clamp your worst case injection latency much lower because the outliers
will not happen inline with the injecting client.
2024-12-16 11:27:40 -07:00
Wez Furlong 8689d4daf0 docs: document new TSA Bounce actions
closes: https://github.com/KumoCorp/kumomta/issues/272
2024-12-09 07:27:14 -07:00
Wez Furlong 6da455d42b kumod: process TSA Bounce rules and apply as bounces
Accepts scheduled queue bounce events from the event subscription,
and translates them into local admin bounce records.

refs: https://github.com/KumoCorp/kumomta/issues/272
2024-12-09 07:15:45 -07:00
Wez Furlong c92cff2a60 maildir: support template expansion of maildir_path
closes: https://github.com/KumoCorp/kumomta/issues/109
2024-12-08 10:15:53 -07:00
Wez Furlong 1a83f72b6d maildir: expose dir_mode and file_mode to protocol config
You can now specify the dir and file modes in your maildir
protocol configuration.

refs: https://github.com/KumoCorp/kumomta/issues/109
2024-12-08 09:41:55 -07:00
Wez Furlong 38fd692e94 docs: show how to skip IPv6
I was halfway through adding special purpose options for this,
but I realized that skip_hosts already exists for this function
and is much more flexible.

Add an example to the docs to show how it can be done.
The same technique can be used to skip using IPv4 if that is
desired (despite being impractical with the current state
of SMTP on ipv6), but using `0.0.0.0/0` as an entry in the
skip_hosts list.

closes: https://github.com/KumoCorp/kumomta/issues/317
2024-12-04 07:33:50 -07:00
Wez Furlong a2f8a1007b remove stale comment 2024-11-22 09:42:10 -07:00
Wez Furlong 70583302ee add session_id to LogRecord and thread through
refs: https://github.com/KumoCorp/kumomta/issues/316
2024-11-19 08:12:13 -07:00
Wez Furlong 971612a7d2 docs: add section about memory management 2024-11-12 13:30:10 -07:00
Wez Furlong e06a4a9049 docs: rotate changelog for 2024.11.08-d383b033 2024-11-12 12:28:40 -07:00
Wez Furlong cf911c4067 docs: update dev -> 2024.11.08-d383b033 2024-11-12 12:25:53 -07:00
Wez Furlong d383b033cf docs: add a refman section for template syntax 2024-11-08 10:37:08 -07:00
Mike Hillyer 00ccd5d69c Update the add_authentication_results page to show SPF as well as DKIM. 2024-11-08 11:11:28 -05:00
Wez Furlong d3e399cfda docs: describe the configuration monitoring and epoch system 2024-11-08 07:14:03 -07:00
Wez Furlong d33aa15c40 docs: add note about the null queue not actually being a queue 2024-11-08 05:32:37 -07:00
Wez Furlong f74f0a7556 add ehlo_domain to the set of predefined connection metadata values 2024-11-08 05:27:02 -07:00
Dirkjan Ochtman 55dcf3e6f9 kumod: add basic SPF Lua API 2024-11-07 07:52:37 -07:00
Mike Hillyer 8bdfa734e9 Should not have made a page in the refman. 2024-11-05 17:39:16 -05:00
Mike Hillyer 1c8e3e413e Add a page for overall_max_message_rate to the reference manual. 2024-11-05 17:26:48 -05:00
Wez Furlong fbed08567f add remember_broken_tls option
This provides a simpler and easier to use option for dealing with broken
TLS.

The back story here is that sites with broken TLS ideally should result
in a TLS failure and return us to a clear text SMTP session that we
could use for the remainder if we are in opportunistic mode.

In practice, it's not that simple:

* The rustls implementation provides into_fallible() to enable this mode
  of operation, but certain handshake errors result in the session being
  unusable once the failed handshake has been communicated
* Openssl is perfectly capable of operating this way, but the Rust
  ecosystem bindings do not expose the handshake failure in a way that
  allows the clear text session to continue

If we wanted to allow the session to communicate with the failed host in
clear text we will need to make a new separate connection for this case.

There is a concern that this will bump a connection counter in a
reputation system implemented on the destination host, but it is
reasonable to wonder if a site that has broken TLS would be sufficiently
sophisticated to employ such a system.

If we did want to allow making a new connection to the same host, it is
a bit awkward to fit into our current mx host connection plan system.

So, with all that in mind, this commit tries a slightly different
approach:

* A new `remember_broken_tls = "3 days"` field in the egress path config
  will enable an in-process cache to keep track of the site_names that
  advertise STARTTLS and for which we failed to handshake, or failed to
  re-EHLO after a handshake.

* That will cause the connection plan to move on to subsequent hosts, if
  any.  It won't cause us to re-attempt the current host.

* Subsequent connection attempts (which may be immediate if there are
  additional hosts in the current session plan) will consult the
  broken tls cache for the site, and use that to decide on the
  availability of TLS

* If we previously encountered broken TLS, we will effectively treat
  the site as not advertising TLS in EHLO, but will generate an
  appropriate error message if TLS is Required.

Since we track the breakage in a cache with per-item TTLs, you
can set the duration as appropriate to your situation.

The cache will be cleared when the process is restarted.

There is no sharing of the cache between nodes.

This is a much lower complexity solution than the existing workaround
using TSA automation rules to override the site with Disabled TLS, and
will help to minimize the number of rules for that purpose in the TSA
daemon.

Note that this commit doesn't change any behavior; we can do a followup
commit to replace those TSA rules with this mechanism.
2024-10-31 13:11:49 -07:00
Wez Furlong 73d811b8ef tsa: add SetDomainConfig action
The back story here is that we were investigating a report of
get_egress_path_config sometimes taking a long time (30-60 seconds!) to
complete.

The issue correlates with a large number of TSA entries that
disable the use of TLS for broken sites (>30,000 entries),
and some kind of DNS resolution.

Running the sample of the TSA output through validate-shaping on my
local system can take 30+ seconds to resolve, with a handful of the
entries timing out after 15 seconds (which is 5 seconds timeout on a
query, plus 2 retries of 5 seconds each).  In this sort of situation
with a persistently slow resolve on specific domains, the best case
result is therefore 15 seconds, but it could be longer depending on the
ordering of the results and prevailing winds on the upstream dns server.

What's tricky in this situation is that we have to resolve the site
name for each of the entries that have mx_rollup=true enabled in
order to correctly match any given domain when satisfying the
get_egress_path_config event callout.  Being lazy with resolution
doesn't help at load time because we're only loaded immediately
prior to invoking this event.

The next logical question to ask is: why do we need to have 30,000+
entries to disable TLS for these broken sites--can't we just retry in
clear text? Well, it's a bit tricky: we're not guaranteed to be able
to continue in clear text after STARTLS fails. If we were to disconnect
and reconnect to the same host immediately after, that's technically
2 connections being made in quick succession to the remote site, and
that might have reputation influencing consequences. I'd like to avoid
adding that sort of reconnection logic without providing a way to
control that behavior, and that is something for a separate change
from this one.

So, looking at the nature of the problematic rule, it doesn't
actually need to be keyed by the site name because there are
not shared limits or constraints that it might make sense to
apply, and in the context of this issue, it's not necessary
to use rollup.

This commit introduces a `SetDomainConfig` action that will
emit a config entry that explicitly sets `mx_rollup=false`
regardless of the value of `mx_rollup` for the defining rule
condition.

When mx_rollup=false, we do not need to resolve the MX
record for the entry when we load the shaping rules,
which eliminates the DNS latency for the aggregate
set of domains with broken TLS.

It would be great if we could automagically fixup the
TSA config database when updating to this version, but
since the rule is an optional part of the suggested
shaping configuration, which may not even be loaded
by a given overall configuration, it's not appropriate
to assume that we should do any fixup.

There's likely a one liner that can be run in sqlite to remove or force
the expiration of the old rules.
2024-10-31 09:28:38 -07:00
Wez Furlong 207bf44f18 docs: format enable_dane.md 2024-10-28 20:46:03 -07:00
Wez Furlong 18cbdeae1a fixup enable_dane page
it was still formatted as if it were part of its former home
in the big page for make_egress_path.

Tidy it up.
2024-10-25 09:09:11 -07:00
Laurent Marchaud 6142808730 fix a few typos in the docs
Signed-off-by: Laurent Marchaud <laurent@marchaud.com>
2024-10-24 12:10:53 -04:00