while troubleshooting a situation where the
http://127.0.0.1:8008.tsa.kumomta queue is backing up, I noticed that
we're using the default queue configuration for this queue.
Let's make it more inline with the defaults for webhooks; give it a
1 minute base retry with a 20 minute max.
These parameters are configurable; you can pass in `tsa_queue_config` to
the setup_with_automation call to specify your preferred values for the
scheduled queue config.
We keep getting asked about
https://rustsec.org/advisories/RUSTSEC-2023-0071.html and how it impacts
kumomta.
The answer to that question is: in the default build configuration, we
use openssl's RSA signing implementation rather than that of the rsa
crate. The reason for this is that OpenSSL's RSA implementation is due
to the performance gap between the two implementations
(https://github.com/RustCrypto/RSA/issues/339). The result of this is
that the problematic code and attack vector described in the security
advisory does not apply to KumoMTA, because it is not used to compute
any signatures.
In the interest of not raising any false alarms as more and more people
perform security analyses on kumomta, this commit removes the `rsa`
crate from the build graph. In order to do so, we need to port
verification over to the openssl RSA implementation which is what this
commit does.
I look forward to a future version of the `rsa` crate being published
that has this issue resolved, and that closes the performance gap!
refs: https://github.com/RustCrypto/RSA/issues/390
Commit 12fe5e3b61 updated the
metrics related crates, but not in every one of our crates,
which meant that we were running with a mixture of 0.20
and 0.22.
The result of this was that the memory related metrics
were no long visible to the published prometheus data
because it was only looking at the other version of
the metrics crate!
This commit switches over to using a workspace dep
for metrics so that we update all related crates
together.
I think we've gone back and forth on this a couple of times.
The motivation for this commit is that we've been troubleshooting
an issue that seems to be triggered by bouncing all the mail.
The symptom is that the system becomes unresponsive after
triggering the bounce.
Here in the context of `bounce_all`, the queue lock is held
so that we can capture the messages, but then we serially
remove them from the spool, so that we can report the total
number back to the originating HTTP request.
For a large queue size that presents a big point of contention
for other tasks or requests that may need to operate on the
queue.
This commit moves that spool removal into another task so that
that task can run asynchronously and independently from the
bounce HTTP request.
The consequence of this is that the numbers reported by the
bounce request will likely be lower than the final count.
The `bounce-list` kcli command can be used to check up on
those numbers.
We've been troubleshooting a lockup on a system with a low core count.
What we found in a stack trace was that one of the threads was blocking
on the CACHE mutex in the sts logic. That mutex is intended to be
short-duration in scope, managing the direct lookup or insertion
into the cache, and no more.
However, due to the the way that rust scopes the lifetime of the
MutexGuard that is acquired from the CACHE, we were holding it
across the async DNS operation that is used to validate that
a cached policy is still current.
This can result in a deadlock on a system with a sufficiently
low core count/high enough concurrent volume of traffic to sites
with MTA-STS enabled.
This commit resolves this by introducing a lookup function that
explicitly clones the cached policy without returning a MutexGuard.
This is vaguely reminiscent of a json pointer reference that
symbolically identifies a node in a tree using a sequence of
integers to indicate the child node index by tree level.
The simplified structure method has been re-implemented in terms
of PartPointer.
It is possible to resolve a PartPointer to its associate MimePart
for both mutable and immutable access.
refs: https://github.com/KumoCorp/kumomta/issues/117
refs: https://github.com/KumoCorp/kumomta/issues/120
We skip logging the 421 we generate while shutting down because
it feels a bit redundant; you'll see the server shutting down
in the journal anyway.
refs: https://github.com/KumoCorp/kumomta/issues/88
While inbound tracing isn't intended to be used to trace 100%
of production traffic, it is useful to be able to accomodate
a bit more than very basic levels.
Increasing the capacity here will allow for that, at the cost of
a little bit of residual RAM.
The rationale was that this would be more robust, but as it turns out,
it may result in discrepenancies with the incoming site_name that
affect how we match back for suspensions.
I saw localhost getting over-resolved in the integration tests so
that it would no longer match.
Let's just KISS and trust the incoming data.
This commit connects the new websocket based suspension feed
up to shaping.lua. This allows ready-q suspensions to be
enacted in realtime, as well as sets things up to support
scheduled queue suspensions in a later commit.
refs: https://github.com/KumoCorp/kumomta/issues/113
This is very similar to the HTTP suspension API, with the
difference that the suspend method returns just the uuid rather
than the entire suspension object.
refs: https://github.com/KumoCorp/kumomta/issues/113
These files are used by me (wez!) while hacking things together locally
as a non-privileged user (myself). They should not contribute to the
overall message accounting database. Let's give each instantiation a
separate temporary path.
This function will spawn a new thread that runs a tokio
localset, which in turn will trigger the specified event
and run it.
On it's own it doesn't do a lot, but it provides a way
to perform background tasks in lua.
```lua
kumo.on('init', function()
kumo.spawn_task {
event_name = 'my.task',
args = { 'hello', 'there' },
}
end)
kumo.on('my.task', function(args)
-- Prints: `I am the task. ["hello","there"]`
print('I am the task.', kumo.json_encode(args))
end)
```