Commit Graph
344 Commits
Author SHA1 Message Date
Wez Furlong 4c6d7ca8ea add policy-extras.mail_auth module
This aggregates the various authentication-results producing auth checks
into a more convenient function.

Part of this change improves some plumbing in the dkim checking (we no
longer raise an error for a missing From, but instead indicate a failed
dkim result), and we now support passing down a resolver name to the
various checking functions, to facilitate testing and other more
advanced use cases.

refs: https://github.com/KumoCorp/kumomta/issues/16
refs: https://github.com/KumoCorp/kumomta/issues/84
2025-11-02 11:56:57 +00:00
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
Wez Furlong db5ebb88a7 message: expose recipient list to lua api
message:recipient() may now return an array style table
holding the recipient list, if there is more than a single
recipient on the message.

Since this can be somewhat ambiguous/frustrating to work with,
there is now also a message:recipient_list() that will always
return an array style table, even if it holds just a single
element.

The included helpers have been updated to use `message:recipient_list`.

message:set_recipient() will now optionally accept an array
style table holding the recipient list to be set.
2025-10-07 07:52:58 +01:00
Wez Furlong 53a6bc3b7e log_hooks: add helper for creating a disposition hook 2025-09-09 10:39:52 +01:00
Wez Furlong f85094282f migrate run-lua-test to rust
At least one of our supported platforms doesn't have a new enough
python to run the python version, let's just use rust for this.
2025-08-13 07:09:53 +01:00
Wez Furlong c28560b4f5 run-lua-test: fixup when run as root (eg: in CI)
Need to pass `--user` in that case
2025-08-11 14:21:02 +01:00
Wez Furlong 9f316ed689 ci: improve run-lua-test
This commit:

* Adds auto-discovery of both module style and crate style tests
* Runs each test via its own instance of `kumod`, so that one test
  cannot pollute the state of another
* Runs all lua tests concurrently
2025-08-11 13:24:41 +01:00
Wez Furlong 7e6ca34e2d new: kumo.fs lua module
The read_dir and glob functions have been logically moved into that new
namespace, leaving deprecated versions of them in the `kumo` module.

A new `kumo.fs.open` function that works similarly to `io.open` is
provided.  This function cooperates with the kumo async io scheduler
and won't block it if the filesystem is under pressure.

It returns file handles that are simlar to the builtin lua file handle
objects, but do not support formatting or parsing of writes or reads
respectively: the calling code is responsible for that.  The rationale
for this difference is that is that lua's semantics for those functions
are frankly a bit weird and are hard to replicate precisely.
2025-07-23 16:51:06 +01:00
Wez Furlong 7d617bb270 add kumo.mpsc.define
This function allows defining a non-durable, non-persistent, in-memory
queue that is intended to be used as glue when building up more advanced
processing flows within kumomta.

The intent is that the queue is processed from within a task spawned via
`spawn_task`.
2025-07-23 12:44:10 +01:00
kayozakiandWez Furlong a7315633de add kumo.dns.lookup_ptr (#390)
* add lookup_ptr

Co-authored-by: Wez Furlong <wez@wezfurlong.org>
2025-07-22 08:45:27 +01:00
Mike Hillyer 58e9770206 We miss you Mister Rogers. 2025-07-18 12:11:14 -04:00
Mike Hillyer 41d251f20d Update links to Comcast docs 2025-07-14 12:19:40 -04:00
smsvip 76f2e833c2 Update shaping.toml
"gmail.com".automation --> regex = "Our system has detected an unusual rate"   

This item is repeated, although it will be override .
2025-07-01 13:11:09 +01:00
Mike Hillyer c7daa01ef2 Whoops, already required. 2025-06-11 18:34:05 -04:00
Mike Hillyer 748c700c7b Adding TLS required for Comcast as per @AlexB in the Discord. 2025-06-11 18:29:38 -04:00
Mike Hillyer 9dba9c5b5f Update traffic shaping defaults to require TLS for Google as per conversation with Gmail admins. 2025-06-10 09:26:07 -04:00
Wez Furlong fedd2959b6 enhance log_arf, log_oob to support LogThenDrop
It is common to want to express that incoming reports should
be logged, but not relayed.

This commit facilitates that by expanding `log_arf` and `log_oob`
to allow more than just a simple boolean value.

We now support both LogThenRelay and LogThenDrop as dispositions
for an incoming report, as well as Ignore to not care about the
report content.

For the LogThenDrop case we'll log only the incoming OOB or Feedback
record to the logs and then discard the incoming message.

For LogThenRelay we'll log the incoming OOB/Feedback report as well
as enqueue the message and log a Reception and, subsequently, records
for its delivery attempts.

The previously supported boolean values are mapped to `Ignore` (false)
and `LogThenRelay` (true), respectively: their behavior is the same as
in prior releases.

The integration test and smtp server tracing infra has been enhanced a
bit to support extracting these new disposition states from the tracer
during the integration test.
2025-05-05 08:25:40 -07:00
Wez Furlong 16fad7b260 promote docker_utils to policy-extras
It is useful enough and avoids some reptitions between
the single node and docker swarm examples.

closes: https://github.com/KumoCorp/kumomta/issues/359
2025-05-02 10:09:57 -07:00
Wez Furlong f92df0fca0 lruttl: introduce allow_stale_reads option
This is paired with a corresponding field in the memoize options
struct, which is in turn exposed to the shaping helper shaping_data
cache via the `allow_stale_shaping_data` field.

The effect of setting this to true is:

* Undoes the effect of invalidate_with_epoch, as stale reads cannot
  be epoch based
* If a semaphore wait times out, and a stale value was present in
  the cache, that stale value will be returned to the caller

To facilitate this behavior, the lruttl cache introduces a new
state for a cached value: `Refreshing`, which is a combination
of both `Present` and `Pending`.

When stale reads are allowed, we take care to avoid unilaterally
replacing `Present` with `Pending` when an item has expired.

Whenever we satisfy a lookup with a stale value, we will bump a new
lruttl_stale_count counter for that cache.  Previously, we would
classify those as errors.

Something else that changed as part of this commit, is that we now set
an overall deadline for the semaphore wait operation; previously, each
wait would allow for up to the specified semaphore timeout, but now the
total wait time for that lookup will be bounded to the specified
timeout.
2025-04-30 14:01:26 -07:00
Kyle Renfrow 38e52c0bbf Adding shaping rules for Yahoo deferral codes TSS05, IPTS04 and IPTS05 in addition to existing TSS04 rule
Yahoo confirmed these four should all be treated similarly.
2025-04-17 14:27:51 -04:00
Wez Furlong c22e98bcd5 add log-filter.py helper script
This is to help humans grok a diagnostic log file a bit better.
This isn't a supported product surface and isn't deployed with
kumomta.  It is intended primarily as a log debugging aid.
2025-04-16 14:53:25 -07:00
Mike Hillyer b034b1b9df Update bounces.toml
Adding a couple of missed codes.
2025-04-07 22:21:22 -04:00
Wez Furlong 95654c61fd shaping.lua: increase shaping_data cache capacity
I've observed a system where we had more than 4 outstanding
shaping_data lookups from different ConfigEpochs; that system
had slow dns resolution and we ended up looping for these because
the capacity was not high enough and the population of the result
always took too long.

Let's just give ourselves a bit more headroom; this coupled
with the earlier commits that adjust retry behavior should
help to smooth things out in this situation.
2025-04-06 09:55:02 -07:00
Wez Furlong 5eb57e63d5 shaping.toml: disable dane for office365-dane
We cannot default it to enabled because a fully working
dane setup requires additional configuration in the resolver
and we cannot guarantee that that has happened here.
2025-04-06 07:47:00 -07:00
Wez Furlong f8bbacba54 systemd: read optional environment files
It is sometimes necessary to set environment variables
to adjust some early-startup options that need to be
applied before enough of the system is ready to read
lua policy files.

While it is possible to use `systemctl edit SERVICE`
and enter systemd-specific directives to configure that,
it is not the most convenient thing.

What this commit does is introduce 3 new optional files:

* /opt/kumomta/etc/kumo-common.env: sourced by kumod and tsa
* /opt/kumomta/etc/tsa-daemon.env: sourced by tsa
* /opt/kumomta/etc/kumod.env: sourced by kumod

The format of these files is `NAME=VALUE` on each line, as
per the `EnvironmentFile` docs in systemd.

One practical application for this is on an over-committed system
where the number of reported cores is larger than the number of
available cores.

For such a system you will need to configure the
`KUMO_AVAILABLE_PARALLELISM` environment variable for each kumo
service running on your system. With these environment files you
can do that simply by creating `/opt/kumomta/etc/kumo-common.env`
with a line like this inside:

```
KUMO_AVAILABLE_PARALLELISM=48
```
2025-04-03 07:26:15 -07:00
Wez Furlong 3b14587192 fix delayed shutdown for non-smtp delivery handlers
Occasionally we'll have someone report that systemd timed out
and sigkill'd their kumo on shutdown.

One possible scenario for this is a lua delivery handler that
is taking too long, presumably because the other end of it
(eg: webhook or other custom endpoint) is not responding in
a timely fashion.

The way that we handle shutdown is that we compute a maximum
theoretical timeout value by summing up all of the smtp client
timeout values.  Some of those can be several minutes in
duration because the are using default values derived from
a very conservative set of values suggested by the SMTP
RFCs from the '70s.

Those obviously should not apply to a custom delivery handler,
but also, in the context of an established SMTP session, we
should not add in the connection-establishment-specific values
when we're just waiting for a per-message send.

This commit addresses this situation on two fronts:

* Introduce a new system_shutdown_timeout value that allows the
  user to conveniently express their desired timeout value
  in a single option.  This is *not* set by default!
* The default value for system_shutdown_timeout is computed by
  summing the per-message-delivery smtp timeout options, which
  is a much more reasonable, and more importantly, shorter than
  our 300s TimeoutStopSec value in kumomta.service
2025-04-02 14:21:31 -07:00
Wez Furlong 1e55d47b93 Add default TSA shaping config to shaping.toml
We've seen folks trip over this a couple of times, and it's
because we don't document this and include it in the defaults,
so here we go.
2025-03-31 12:02:54 -07:00
Wez Furlong c9ab140ac1 shaping.lua: expose memoize populate retry/timeout params
undocumented for the moment
2025-03-21 16:59:13 -07:00
Wez Furlong 9b065fb133 shaping.lua: revise update strategy for tsa pushed data
Previously, we'd build a little map of existing rules and check
things off against it, but that doesn't have the best scaling
properties, because we need to copy the full set of bounces/suspensions
into lua and check against that.

Since the underlying bounce/suspension tracking stuff already
guarantees that inserting a record with the same criteria will
replace another, this checking in lua-space was redundant and
wasteful, so we can just remove it.

This commit also adds some debug logging to show how many
records are being processed.
2025-03-18 14:05:53 -07:00
Wez Furlong 98e99594d9 shaping: process tsa websocket pushes in batches
We'll wait up to 3s at a time for however many mesages are available
to extract from the tsa daemon websocket, then process the results
in batches.

This avoids the potential for geometric complexity if there is a run of
subscription updates happening around the same time.
2025-03-18 14:05:30 -07:00
Wez Furlong 9e6321ecb6 shaping: add timeout for tsa shaping data fetches 2025-03-18 14:05:30 -07:00
Wez Furlong 5b3d94ef98 lruttl: potentially squash sema/eviction errors from logs
A couple of users have reported seeing:

  sema was closed but state is still pending

and/or

  lruttl: shaping_data did not find anything to evict, target was 1

messages in the diagnostic logs.

These arise due to the capacity of 1 that was configured
for the shaping data cache in the shaping helper and a race
condition where lookups are interleaved around a config epoch
bump triggered either by the initial epoch bump on startup,
or a bump produced by the TSA daemon.

This commit adjust the strategy for handling those errors if/when
they arise by attempting to restart the cache lookup process.

In addition, this commit raises the capacity of the shaping data
cache to avoid this point of contention.
2025-03-15 09:58:53 -07:00
Wez Furlong cc58befdc6 install.sh: fix typo 2025-03-15 07:34:00 -07:00
Wez Furlong bb2e671f4e add explain-throttle script 2025-03-12 11:07:52 -07:00
Wez Furlong f1f5d27591 sources.lua: surface socks5_proxy_source_address issues better
This field only accepts IP addresses; it is an error to use
a DNS name with it.

The sources helper was swallowing the helpful part of the context
about the issue with that field.

This commit ensures that we do surface it.
2025-03-11 06:55:44 -07:00
Wez Furlong f23875b1a1 shaping.lua: mostly switch prints to kumo.log_XXX
Keeping the validation stuff as prints for the time being,
as I think that looks nicer in the context of a standalone
validation mode.
2025-03-07 08:06:35 -07:00
Wez Furlong 5c154417c7 shaping.lua: fix missing string.format calls
closes: https://github.com/KumoCorp/kumomta/issues/351
2025-03-04 16:24:58 -07:00
Wez Furlong 0666374f58 tsa: expose underlying log hook back_pressure to configuration 2025-02-24 08:59:58 -07:00
Wez Furlong a805184a8f remove deprecated unused fields from tsa shaping object 2025-02-24 08:59:24 -07:00
Wez Furlong 161e7b6d3b shaping.lua: ignore Rebind and Delayed log record types
Cut out rebind and delayed log records from the feed to the TSA
daemons.  These don't make sense to have TSA rules applied to
them, and in some configurations (such as deferred injection)
these records can 2x the volume of records being processed.

With pre-filtering enabled those records won't make it to the TSA
daemon, but we would still need to run those records through the
rules to realize that.

With this commit we can cut these out in O(1) and minimize the
local CPU cost of that.
2025-02-24 08:31:46 -07:00
Wez Furlong 3071fe9701 add shrink_policy queue config option
This allows reducing how much of a message is freed when it is
delayed.
2025-02-21 17:15:52 -07:00
Wez Furlong f210a95e37 dkim helper: fixup vault usage
Appending `.key` to the implicit vault path doesn't make a lot
of sense.

Removing extraneous slash from example in the docs.
2025-02-13 14:42:16 -07:00
Wez Furlong 8637a2adfe memoize: add len metamethod to MemoizedTable
refs: https://github.com/KumoCorp/kumomta/pull/343
2025-02-12 12:02:26 -07:00
Wez Furlong 0ab606cfee memoize: make epoch-based invalidation optional
It is not always desirable to invalidate with the epoch,
so allow opting in instead of always invalidating that way.
2025-02-06 11:06:25 -07:00
ncai 38484d0bf3 add unmask to enable installing kumomta over kumomta-dev and the other way around 2025-02-05 11:19:27 -07:00
Wez Furlong 80b7e6520e resolve-shaping-domain: allow specifying the source name 2025-01-17 10:07:02 -07:00
Wez Furlong 9cbef3b202 fix deserialize error: unknown field relay_from_authz issue
The changes in e4b743cb8f to improve
memoize performance could cause the error message above because
the __newindex method wasn't actually writing the new value to
the unshared table, it was returning the existing value!

Most of this commit is really plumbing to support calling through the
cache layers in the same way that the listener would use, but in the
context of the unit tests in the lua file.

A nice side effect of this plumbing is that it is now possible
to iterate (via pairs) and index fields of the main config
objects that are returned by the most common `kumo.make_xxx`
functions.
2025-01-13 16:51:38 -07:00
Wez Furlong 1aa1188f6c policy_utils.equals now uses pairs on userdata
In an upcoming change, I want to allow comparing userdata
and tables that serialize the same way, rather than just
using the current logic which decides that a table and
a userdata can never be equal.

This commit removes that check and instead continues through
to iterate the keys/values of both operands regardless of
whether the container is a table or userdata.
2025-01-11 06:18:21 -07:00
Wez Furlong 48e89105a7 fix provider rule matching with MXSuffix
Given a provider with the following config:

```json
      "match": [
        {
          "MXSuffix": "mta5.am0.yahoodns.net"
        },
        {
          "MXSuffix": "mta6.am0.yahoodns.net"
        },
        {
          "MXSuffix": "mta7.am0.yahoodns.net"
        }
      ]
```

(Note that this configuration is not ideal because someone with
`notreallymta5.am0.yahoodns.net` in their MX records will match
this.  If you were using SMTP auth for such a site, then you risk
leaking your credentials to it! We should consider adding an exact
match option for this case)

we could never match this because the logic had the inner and outer
loops swapped.

For a provider to match, all of the resolved host names must match
at least one of the MXSuffixes defined in the rule.

The flipped logic prevented that from matching.

Most of this commit is adding stuff to help trace this down
and debug it.

In particular, `resolve-queue-config` will tell you what the
effective value of the get-queue-config event is for a given
queue name, and `resolve-shaping-domain` will show you the shaping
configuration for a (bogus) source.
2024-12-16 12:46:31 -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