Commit Graph
937 Commits
Author SHA1 Message Date
Wez Furlong d8174deb2d fix NXDOMAIN issue showing up as no non-zero-weighted sources
The suspension logic changed things so that we'd trip over a DNS
resolution earlier than normal, inside the round robin routine.

That isn't capable of reporting the domain resolution issue and
it would bubble up as NoSources and we'd miscategorize the failure.

This commit addresses that by allowing the round robin to pick a
source and then we can subsequently bubble up and handle the domain
resolution issue as normal.
2023-06-24 10:13:47 -07:00
Wez Furlong 3b681e6616 include round robin state in no-non-zero-weighted sources message 2023-06-24 10:04:20 -07:00
Wez Furlong 74b9fb2cb9 ready_queue: explain the "no answer from any hosts" transfail better 2023-06-24 08:28:26 -07:00
Wez Furlong 6514eaa6df delivery_metrics: DRY and encapsulate better
Make it more difficult to misuse and less boilerplate to use
2023-06-24 07:17:07 -07:00
Wez Furlong 7d4cc52d8d ready_queue: adjust trans and perm failure counters
In the all-connections failed and bulk ready queue operation cases,
we weren't updating the delivery metrics counters.

This commit addresses that.
2023-06-24 07:06:35 -07:00
Wez Furlong f294b6f65c ready_queue: increment attempts after exhausting connection candidates
Previously we'd just use the default error case and retry 1 minute
later, but for sites with broken tls where we can never make a
connection without changing our configuration to skip tls, we don't
want to keep retrying every minute and instead want to follow the
normal queue exponential backoff.
2023-06-24 06:58:43 -07:00
Wez Furlong f69709e34c smtp_dispatcher: improve post-starttls ehlo diagnostics
Some sites with broken tls can produce the following transient failure
log:

```
KumoMTA internal: failed to connect to any candidate hosts: EHLO: Not connected, EHLO: Not connected, EHLO: Not connected, EHLO: Not connected
```

which is very thin on actual context.

This commit adds in the useful context!

refs: https://github.com/KumoCorp/kumomta/issues/67
2023-06-24 06:54:54 -07:00
Wez Furlong 46c5f8cf98 rustfmt 2023-06-24 06:49:59 -07:00
Wez Furlong ee02c75583 really a WS only change that triggers a new build 2023-06-23 12:35:07 -07:00
Wez Furlong c8894586e8 whitespace only change to trigger a build with a new hash 2023-06-23 12:33:48 -07:00
Wez Furlong ca152156fe build-deb: include version number in filename
I suspect that using the same name on upload to openrepo
somehow collides with other versions that use the same uploaded
filename.

refs: https://github.com/openkilt/openrepo/issues/11
2023-06-23 11:52:15 -07:00
Wez Furlong b338347e34 ubuntus: add stable apt repo to sources.list 2023-06-23 11:13:08 -07:00
Wez Furlong eb6232f582 Add basic suspension of scheduled and ready queues
These are two different groups of queues, so there are two different
sets of things to manage them.

kcli now has `suspend(-list|cancel)?` and
`suspend-ready-q(-list|cancel)?` subcommands for establishing a
suspension, listing the suspensions and cancelling a suspension
in the scheduled-q and ready-q namespaces respectively.

The names of the ready queues can be derived from the metrics API:

```console
$ curl -s 'http://localhost:8000/metrics.json'  | jq .
...
  "ready_count": {
    "help": "number of messages in the ready queue",
    "type": "gauge",
    "value": {
      "service": {
        "smtp_client:source2->(in1-smtp|in2-smtp).messagingengine.com": 0.0
      }
    }
  },
...
```

From the above, `source2->(in1-smtp|in2-smtp).messagingengine.com` is
the name of the underlying ready queue.

We can and probably should add something to `kcli` to make that slightly
easier to review and manage for the operator.

refs: https://github.com/KumoCorp/kumomta/issues/51
2023-06-23 07:50:56 -07:00
Mike Hillyer c083bc44f0 Update the changelog for the new release. 2023-06-23 09:46:58 -04:00
Wez Furlong 51b72a8399 add selene linter config
This is relatively basic in that it can catch general lua lints,
but doesn't know about the set of functions available to kumo.

It doesn't appear as though selene is able to be extended to
know about those yet; that is tracked by
https://github.com/Kampfkarren/selene/issues/520

I've fixed the couple of lints in our policy and test files
as part of this commit.

You can install and run it like this:

```console
$ cargo install selene
```

Then:

```console
$ selene .
```
2023-06-22 13:50:51 -07:00
Wez Furlong 8b2584f0f3 simple_policy.lua: tweak data timeouts 2023-06-22 13:25:35 -07:00
Wez Furlong 5d39928acf add docs for new bounce APIs
and briefly show how to use `kcli` with them
2023-06-22 12:59:36 -07:00
Mike Hillyer 0ac94e3092 Automated doc formatting fix 2023-06-22 18:35:23 +00:00
Mike Hillyer 13f1617f47 Added reference to the DKIM policy helper. 2023-06-22 14:34:20 -04:00
Mike Hillyer b4fe119fdc Automated doc formatting fix 2023-06-22 18:23:39 +00:00
Mike Hillyer 02ac065ae5 Update TOC 2023-06-22 14:16:04 -04:00
Wez Furlong a2911ffd31 lifecycle: expand shutdown requested messaging
Explain a little bit more why we are waiting
2023-06-22 10:17:50 -07:00
Wez Furlong 9e83e72500 kcli: centralize request making and resolving, improve error messaging
Previously, an authentication issue could manifest as an opaque and
confusing error message like

```
Error: error decoding response body: expected value at line 1 column 1
```

now we show it like:

```
Error: request status 401: Unauthorized. Response body: Missing Authorization header
```
2023-06-22 09:55:59 -07:00
Mike Hillyer 8d843b3a51 Update shaping.toml
Little longer on the dot timeout.
2023-06-22 11:49:50 -04:00
Mike Hillyer 7166b38659 Update shaping.toml
Adding data timeout and data dot timeout to the default shaping file.
2023-06-22 11:45:44 -04:00
Wez Furlong 52e6424422 smtp_client: use data_dot timeout for the . response 2023-06-22 07:57:21 -07:00
Wez Furlong 4fe11e5f31 smtp client: ensure all reads and writes have a timeout
There were a few cases where client operations weren't wrapped
up in a timeout, which is a potential cause of hanging on shutdown:
if we're waiting an unbounded amount of time for a connection to
do something before we can shutdown, then we'll never finish.

The current timeouts struct really encodes the read timeout for
waiting for the result of a command.

What we also need is a duration to wait for sending data. We're
using the smaller of the per-command read timeout or 1 minute for
this.
2023-06-22 07:41:31 -07:00
Wez Furlong 27070388d4 fixup tokio-console
I've found the right combination to allow seeing the user-specified
log filter in the normal log output, while allowing tokio-console
to start with the appropriate filters when the `--tokio-console`
switch is used to start kumod.
2023-06-21 18:10:15 -07:00
Wez Furlong e96cd5284b bounce-list: report the bounce totals in the list
```
; ./target/debug/kcli --endpoint http://127.0.0.1:8000 bounce --everything --reason purge
{
  "id": "c8c3dc0b-084a-4dab-bf11-c44b5285554d",
  "bounced": {
    "gmail.com.mx-sink.wezfurlong.org": 1057,
    "aol.com.mx-sink.wezfurlong.org": 1079,
    "hotmail.com.mx-sink.wezfurlong.org": 1080,
    "yahoo.com.mx-sink.wezfurlong.org": 1156
  },
  "total_bounced": 4372
}
```

and follow up with the list command to see ongoing progress:

```
; ./target/debug/kcli --endpoint http://127.0.0.1:8000 bounce-list
[
  {
    "id": "c8c3dc0b-084a-4dab-bf11-c44b5285554d",
    "campaign": null,
    "tenant": null,
    "domain": null,
    "reason": "purge",
    "duration": "4m 54s 638ms 685us 58ns",
    "bounced": {
      "yahoo.com.mx-sink.wezfurlong.org": 14644,
      "hotmail.com.mx-sink.wezfurlong.org": 14515,
      "aol.com.mx-sink.wezfurlong.org": 14521,
      "gmail.com.mx-sink.wezfurlong.org": 14487
    },
    "total_bounced": 58167
  }
]
```
2023-06-21 15:36:24 -07:00
Wez Furlong d957da58b4 cargo update 2023-06-21 15:15:56 -07:00
Wez Furlong 04df1ecba9 minijinja: upgrade to 1.0.1
There's a small API change to deal with as part of moving
from 0.30 -> 1.0.

This change includes the raw block fix from the upstream.

closes: #60
2023-06-21 15:14:57 -07:00
Wez Furlong e0c47e2301 spool: allow up to 50% of cores for processing spool-in
In the future we could consider making this configurable.
For now, this does a reasonable job at getting messages
from the spool and into the queues to unblock receiving
new messages.

The degree to which this helps varies based on the number
of different scheduled and ready queues that arise from
the messages in the spool and the active configuration.
2023-06-21 13:47:42 -07:00
Wez Furlong dc071e63c0 spool: switch to flume for enumeration channel
This is mpmc which will allow parallelizing spool enumeration
in a following commit.
2023-06-21 13:47:42 -07:00
Wez Furlong 41f1216934 fix potential deadlock w/ spool manager & incorrect ready queue bounce logic
While spool enumeration is ongoing, we'd keep an exclusive lock
on the spool manager.

If we'd subsequently need to remove a message from spool, we'd
attempt to obtain a lock on the spool manager to be able to reference
the spool.

In the best case, the removal logic would be triggered from a separate
task, and would eventually succeed once enumeration completes.

However, if the calling context holds a lock on a schedule queue
then we'd have potential to deadlock, especially in the case where
we are processing an admin bounce request via the HTTP API which
needs to iterate all queues, lock them and then initial the bounces
and associated removal of the messages from the spool.  Holding a
scheduled queue lock would prevent forward progress in the spool
enumeration logic which also needs to lock that queue to insert
newly enumerated messages.

In many cases this issue would not be noticed until attempting
to shutdown the server where it would manifest as waiting forever
to shut down.

This commit removes the possibility of deadlock by adjusting
the composition of the SpoolManager.  Now, instead of needing
to lock the entire spool manager, the locks are scoped to the map
that manages the named spools; the critical section for those is
now just long enough to obtain a handle.

While examining the flow of this stuff I realized that the admin bounce
processing was overly aggressive and would bounce all the messages in
the ready queues associated with the matching scheduled queue.  That's
incorrect as the ready queues are potentially shared with other
scheduled queues can feed into those same ready queues.

I adjusted the logic for those so that we process the admin bounce
entry as part of dispatching the ready queue instead of trying to
bulk fail the ready queue.
2023-06-21 12:27:59 -07:00
Wez Furlong 5f0caebf9e lifecycle: allow labelling and enumerating pending activity
We show the total number and a truncated list during shutdown
2023-06-21 09:17:03 -07:00
Wez Furlong 5849981f3f lifecycle: more eagerly close out connections on shutdown
Check for shutdown in a couple more places, and adjust the connection
timeout logic to give up on establishing a new connection as soon as we
detect a shutdown.
2023-06-21 08:18:57 -07:00
Wez Furlong eaa5da6e9e re-ehlo when using OpportunisticInsecure and STARTTLS failed
We were previously only re-doing the EHLO in the success case, but there
are some receiving implementations that seem to roll the TLS failure
error forward, returning an error during MAIL FROM:

```
TLS connection failed: error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher (#4.3.0)
```

we want that error to show up while we're considering the connection, so
that we can fail over to the next candidate in our list, rather than
having it generate a transient failure for the message and stopping
there.

refs: https://github.com/KumoCorp/kumomta/issues/67
2023-06-21 07:03:11 -07:00
Wez Furlong 1123324400 dkim: wrap signature header
The hope is that this will encourage some verification implementations
to pass on headers where they currently fail.
2023-06-20 22:44:47 -07:00
Wez Furlong 6ef093fbc7 docs: explain more about max_ready tradeoffs 2023-06-20 14:33:40 -07:00
Wez Furlong 192c051227 docs: note the default value for max_ready 2023-06-20 14:23:17 -07:00
Tom Mairs 0ee4f12243 fix typo in shaping.toml - issue #68 2023-06-20 19:14:54 +00:00
Wez Furlong 6fff515e81 http injection: normalize newlines in generated content
Otherwise we can end up with protocol errors when trying to send
the resultant messages out via SMTP.
2023-06-20 10:19:23 -07:00
Wez Furlong a4117c6b1e OpportunisticInsecure: allow using clear text if handshake fails
Previously, we'd hold out for a different, working, host in the
set of available hosts, but when in OpportunisticInsecure mode
we're willing to send to any of the hosts that is available,
regardless of the state of their TLS.  So this commit should
allow us to proceed in clear text on the existing connection
in that case.

refs: https://github.com/KumoCorp/kumomta/issues/67
2023-06-20 08:50:09 -07:00
Wez Furlong 020626360b docs: document enable_tls = 'Disabled' 2023-06-20 08:23:36 -07:00
Wez Furlong 4cb86c7dd4 queue: centralize insert_ready logic
Commit f3be872791 was only an issue
because we had essentially two copies of the logic to insert
into the ready queue.

This commit refactors the second location to work in terms of the
first.

In doing so, I think this also fixes an issue with queues configured
for non-SMTP delivery, such as lua delivery implementations for
webhooks/AMQP in the delayed->ready case.  I think this explains
some weirdness that Tom has seen in the past when playing with
webhook logging.
2023-06-20 07:11:22 -07:00
Wez Furlong ecf3805184 bug: we'd forget about a message when all connection attempts failed
Relatively serious: if none of the resolved hosts were reachable,
the message that initiated that attempt would get logged as a transfail
but we'd then forget about it until a restart when we'd re-discover
it from the spool.

This is resolved by not taking the message from the dispatcher and
instead leaving it in place so that its centralized Drop processing
will requeue it to the scheduled queue.
2023-06-20 07:07:24 -07:00
Wez Furlong f3be872791 requeue message with attempt increment in other DNS resolve failure case
This should have been part of df4e571b51.
This case is for migrating from scheduled to ready when delayed
messages are ready, whereas the other one was newly received mail
that was ready immediately.

refs: https://github.com/KumoCorp/kumomta/issues/65
2023-06-20 06:32:32 -07:00
Wez Furlong ab80d4ca5f dns: resolve ambiguity of null mx and failed host lookups
Tom "Edge Case" Mairs found an issue where what I think happened
was that the DNS records changed since we first established our
own internal data structures.

When the new set of records doesn't resolve to any A or MX entries
we'd return the same empty list of addresses that we used to signal
a null mx and incorrectly fail the remainder of that queue.

This commit introduces a separate state for the null mx state so that
we can instead delay the queue.
2023-06-19 15:02:23 -07:00
Wez Furlong 3a74b56a52 deps: update minijinja to 0.34
The latest version is 1.0 but there are some API changes to reconcile.
Let's update to the most recent in this line that doesn't require any
changes.
2023-06-19 14:50:34 -07:00
Tom Mairs 0afd3aa8cf fix typo 2023-06-19 21:38:21 +00:00