Commit Graph

68 Commits

Author SHA1 Message Date
Wez Furlong 9a9443be71 logs: add source_address field to SMTP client logs
Previously we would log the pool and source name, but it is
desirable to also log the underlying socket address information,
so here we go!

refs: #40
2024-07-12 08:39:15 -07:00
Wez Furlong b003e49c9c rfc5321: split out banner_timeout from connect_timeout
The motivation for this is:

My test environment is not permitted to reach outbound port 25.
If I run an ad-hoc test without setting up an explicit sink,
I end up with messages that try to reach the public internet.
Since they are blocked at a firewall, each of the MX hosts in
the connection plan is subject to a 60s wait before trying the next
thing.

In addition, this can cause the shutdown to take longer while
we wait for the in-flight delivery attempts to complete.

Making a separate configuration option allows the local administrator
to decide how to split the time waiting for a connection from
the time waiting for the banner.

refs: https://github.com/KumoCorp/kumomta/issues/196
2024-07-12 07:54:43 -07:00
Wez Furlong a00e8d0f0a NEW: add tracing to smtp client, kcli trace-smtp-client
It is now possible to trace outbound SMTP sessions, filtering
by a variety of properties.

Details are in `kcli trace-smtp-client --help` and also in
the docs at /reference/kcli/trace-smtp-client.md

refs: #87
2024-07-11 08:56:25 -07:00
Wez Furlong 11bbd07f3f listener_domains: add typing and validation
refs: #211
2024-06-28 09:43:38 -07:00
Wez Furlong b9dccf1cc3 add policy-extras.typing lua module
The primary purpose here is to allow defining typed records
for use in our helpers.

The dkim_sign module has been updated to make use of this
to ensure that the correct shape of data has been loaded.
2024-06-26 16:38:22 -07:00
Wez Furlong 39818c1e36 Add validation for dkim_sign helper
refs: https://github.com/KumoCorp/kumomta/issues/211
2024-06-25 12:08:37 -07:00
Wez Furlong 3139be2cfd Add new kumod --validate flag
The purpose is to provide a deeper, offline validation pass
of the policy configuration, prior to deploying and making it
live.

The system behavior changes when in `--validate` mode:

* Listeners, spool and spawned tasks will be silently skipped;
  the parameters will be validated but the primary functions
  of those things will be skipped silently.
* After triggering the `init` event, an additional new `validate_config`
  event (which can be registered multiple times) will be triggered
  to allow lua modules to perform extended validation.
* A module can either raise an error via `error` to immediately report
  a problem, or instead call a new, preferred, `kumo.validation_failed()`
  function to flag validation as failed but allow additional validation
  to be performed and summarized all together.
* Once the `validate_config` event returns, the process will terminate
  with either exit code 0 for a successful validation, or non-zero
  to indicate that something failed.

Validation errors are reported in a human readable form.

This commit adds validate_config event handlers for the following
helper modules:

* `shaping` - any warnings reported by the underlying rust code
  will be reported here and cause validation to fail. This is
  functionally equivalent to using the `validate-shaping` binary,
  except that it will automatically be passed the set of shaping
  files defined by your `init.lua`

  If the `sources` helper is also configured, the list of sources
  referenced by the shaping config will be cross-checked against
  the sources data to confirm that all possible sources are defined.

* `sources` - each listed source and pool will be validated by
  calling `kumo.make_egress_source` or `kumo.make_egress_pool`
  respectively.

  Pool membership will be validated to confirm that every
  listed pool is defined in the sources data.

* `queues` - each domain and tenant that references an egress_pool
  will be cross-checked with the `sources` helper, if the sources
  helper has been configured.

It is now an error to attempt to setup any of the above helpers
more than once.

refs: https://github.com/KumoCorp/kumomta/issues/211
2024-06-25 11:05:04 -07:00
Wez Furlong 403f80ac26 simple_policy/sink: use temporary file for acct db
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.
2024-03-28 07:14:35 -07:00
Wez Furlong 15b1fab110 checkpoint some local testing/hacking in my test configs 2024-03-27 16:33:17 -07:00
Wez Furlong 7ff5c4115e dkim helper: give a clearer error message when From: header is missing
Previously, we'd just generate an attempt to index `nil` error
message, and the result would be a 421 technical difficulties.

Promote this to a 522 with an explanation about the missing
From header.
2023-12-13 10:21:37 -07:00
Wez Furlong a03fcb2bf1 docs: fix sqlite auth example 2023-11-10 07:01:58 -07:00
Wez Furlong 929d51deba events: plumbing for registering multiple handlers
Previously, we'd restrict `kumo.on` to allowing just a single
instance of an event to be registered. The purpose of this was
to help surface logical errors where copypasta would result in
a bogus configuration.

With multiple helper lua modules now wanting to take responsibility
for some portion of the event handling, it is becoming more complex
to stitch things together.

It is desirable to allow multiple handlers for certain events,
so that a module can handle just its area of responsibility
without worry other modules about it.

This commit introduces a CallbackSignature type that allows
defining the function signature for event callbacks.

The signature can be pre-created and registered ahead of setting
up any lua contexts, which allows declaring whether an event
can have multiple callbacks registered.

The `get_queue_config` event handler has been set to allow multiple
callbacks.
2023-11-02 18:11:17 -07:00
Wez Furlong 4c36489681 First pass at accounting db
This keeps track of the volume of receptions and deliveries over time.
2023-10-12 20:43:58 -04:00
Wez Furlong 3b10d637f9 docs: show how to use dkim verification
refs: https://github.com/KumoCorp/kumomta/issues/82
2023-09-14 13:03:41 -07:00
Wez Furlong 06bb8d0492 add msg:add_authentication_results
This method will prepend an Authentication-Results header
to the message with the specified set of results and
local server name.

We need a more convenient way to default the server name;
ideally we'd pick this up from the listener, but that is currently
awkward in the policy.

refs: https://github.com/KumoCorp/kumomta/issues/82
2023-09-14 13:03:41 -07:00
Wez Furlong e4bb5d674d add msg:dkim_verify()
This method returns an array of AuthenticationResult reflecting
the verification status.

refs: https://github.com/KumoCorp/kumomta/issues/82
2023-09-14 13:03:41 -07:00
Wez Furlong 0b21193b8a add msg:check_fix_conformance()
This is for check and/or fixing message conformance issues.
2023-08-29 16:18:59 -07:00
Wez Furlong a6a711e72f simple_policy: remove rollup from testing policy 2023-08-11 12:36:54 -07:00
Wez Furlong 67b71a8b83 policy-extras: add rollup.lua
This is a prototype of a means for dealing with rolling up microsoft's
domains so that shaping can be applied holistically over both eg:
hotmail.com and outlook.com.

Those domains don't work with our default automatic MX based rollup
because they don't return the same MX hostnames.

Checking this in to make it easier for others to test/evaluate.
In the future, we may find a way to integrate this with our main
shaping helpers.
2023-08-10 11:48:07 -07:00
Wez Furlong 3fd76dd45a introduce routing_domain concept
Augments our queue name format to be
`campaign:tenant@domain!routing_domain`.

The routing_domain is optional.  If the routing_domain is not set, its
effective value is that of the recipient domain.

You can `msg:set_meta('routing_domain', 'bar.com')` to set the
routing_domain for a message, so if the original recipient was
`user@foo.com`, that would cause the computed queue name for it to be
`foo.com!bar.com`.

The routing_domain is used when deciding on the ready_queue name
and destination MXs, so continuing our example, instead of resolving
`foo.com` MX records we'd resolve `bar.com` and deliver to that site.

The `get_egress_path_config` event `domain` parameter is redefined to be
the effective `routing_domain`.

The `get_queue_config` event `domain` parameter is the regular recipient
domain. The `routing_domain` is not currently made available to
`get_queue_config`. If/when we expose it, it will likely be via a
queue name object instead of adding an additional parameter. That would
be a breaking change.

The consequence of not exposing this parameter is that per-message
routing scenarios for the same domain (but different routing domains)
cannot vary the scheduled queue parmeters (eg: retry intervals). Even
though they would have separate scheduled queue instances, those
instances would have the same scheduled queue parameters.  If you need
to be able to do that, then explicitly setting the domain portion of the
queue name would be a way to do that: `msg:set_meta('queue',
'foo.com-via-bar.com!bar.com')`.  `get_queue_config` would then be
called with `domain='foo.com-via-bar.com'` and your policy could then
respond accordingly.
2023-08-10 08:43:20 -07:00
Wez Furlong 8b2584f0f3 simple_policy.lua: tweak data timeouts 2023-06-22 13:25:35 -07:00
Wez Furlong 45c5d011d1 simple_policy.lua: s/max_connections/connection_limit/
use the correct name for this field
2023-06-16 08:47:33 -07:00
Wez Furlong b7c557c31a define_egress_(pool|source) -> make_egress_(pool|source)
Switch the configuration plumbing for pools and sources to be pull-based
rather than push based.

In other words, rather than defining them in the `init` event,
you now need to supply them to the new `get_egress_pool` and
`get_egress_source` events.

Data is cached by default for 1 minute. This allows for new sources
to come into being on-demand, and for data to age out and change
over time, without requiring that the server be restarted.

This commit updates the reference section, but there is some content
in the user guide that refers to the old style of configuration that
will need to be updated.

refs: https://github.com/KumoCorp/kumomta/issues/13
2023-05-30 14:08:07 -07:00
Wez Furlong 278bc81aa0 move shaping -> policy-extras/shaping, and deploy with package
The assets/policy-extras dir is now deployed to
`/opt/kumomta/share/policy-extras` and added to the require path,
so you can do:

```lua
local shaping = require 'policy-extras.shaping'
```

to pull it into your policy.
2023-04-26 14:51:52 -07:00
Wez Furlong b3f3f877df add functions for working with address headers 2023-03-14 18:53:47 -07:00
Wez Furlong 269e0702b4 add SMTP AUTH PLAIN support
Verified via:

```
swaks ... --auth plain --tls --auth-user scott --auth-password tiger
```
2023-03-11 16:23:49 -07:00
Wez Furlong 92a5509af5 update simple_policy for changes to the dkim vault parameters 2023-03-07 14:52:36 -07:00
Wez Furlong 7054fb31c9 switch to using human time for the queue related time intervals 2023-03-06 19:33:05 -07:00
Wez Furlong 00c253a9dd add maildir support
This is to facilitate end-to-end testing to validate that the
right bits come out at the end.
2023-03-06 19:05:49 -07:00
Wez Furlong 30e64c577f tweak simple policy to show sqlite usage for auth 2023-03-06 12:35:25 -07:00
Wez Furlong 0ca585bd5a Optionally use redis for throttles 2023-03-05 10:39:56 -07:00
Wez Furlong 52f7ab6150 add prohibited_hosts and skip_hosts for outbound resolving
While in that part of the code, handle null MX destination domains
(such as `example.com) more nicely.
2023-03-04 10:09:17 -07:00
Wez Furlong 7d76b3d9d7 add support for retrieving signing keys from hashicorp vault 2023-03-03 10:32:16 -07:00
Wez Furlong 35d90a72ab undo changes to simple_policy.lua
I'm not sure if these were intended to be committed, but
back them out so that they don't collide with my testing!
2023-03-01 16:23:45 -07:00
Wez Furlong c7a8405ddf fix code formatting 2023-03-01 09:45:22 -07:00
Wez Furlong 2b0ba702cb add scheduling constraints
This is implemented by allowing the Message:set_due method to
load the message metadata to consult the scheduling constraints,
which should mean that all scheduling updates have the constraints
applied to them.
2023-03-01 09:43:48 -07:00
Tom Mairs 2699111362 fixed page order in guide 2023-03-01 07:45:09 +00:00
Wez Furlong 557fff650d implement max_deliveries_per_connection 2023-02-28 15:12:15 -07:00
Wez Furlong c275c696ff implement message and connection rate throttles
These use the local/in-process throttles.
Seems to work in my very light testing so far.
2023-02-28 13:56:58 -07:00
Wez Furlong 9ab1727792 rename: dest_site -> egress path 2023-02-28 09:56:20 -07:00
Wez Furlong 327aef76d3 implement binding to a source address
The source address is defined by the egress source
2023-02-28 09:44:08 -07:00
Wez Furlong 93ff9e1991 adjust dest_site to queue based on source->site
There needs to be another pass over this for naming,
but this brings us closer to the state shown in the
diagram in the readme.
2023-02-28 06:29:26 -07:00
Wez Furlong 9338de3d06 delay ready queue when target site is persistently unavailable
Tidy up the logging around this; move some error logs to debug level,
especially since we log message events to the log file for that purpose;
there is no need to log errors to the console for this.
2023-02-26 22:26:03 -07:00
Wez Furlong 51d9928ead docs: add more reference content 2023-02-25 20:41:50 -07:00
Wez Furlong 79ff6354c7 format 2023-02-24 10:53:17 -07:00
Wez Furlong 12f1637087 http: add https and some plumbing for auth
* Reuse the tls acceptor stuff from the smtp_server.
  We'll automatically generate self-signed certs when
  none are provided.
* Add trusted_hosts setting for the http server
* Add an auth middleware that will accept connections from
  trusted hosts as pre-authenticated. Other hosts must provide
  http authorization.
* Add lua hooks for the policy script to validate either http
  basic auth (user+pass), or bearer auth (token).

There's not currently an authentication storage subsystem, but
the lua hook allows for very basic stuff to be configured, and
could also be used to employ eg: looking things up from a database
once we add some lua utility functions for that purpose.

The `/metrics` endpoint will only respond to trusted IPs.

Other endpoints all require some kind of successful authentication.
2023-02-24 10:47:06 -07:00
Wez Furlong 5438824ef3 smtp_server: add reception limits
allow limiting the number of messages and the number of recipients
that come in on a single connection
2023-02-22 23:12:39 -07:00
Wez Furlong bcd4a6fc6d take a crack at logging receptions and deliveries 2023-02-22 11:57:26 -07:00
Wez Furlong 5cfb086fed spool: remove sled
It's beta and rocksdb performs better; there's not a compelling
reason to retain it until it stabilizes.
2023-02-21 21:28:36 -07:00
Wez Furlong b25ff76118 add dkim signing
A fairly sprawling commit:

* Move config to its own crate to facilitate making things more modular
* Crates/modules can now provide a registration function that can be
  used to setup functions in the lua environment
* Message crate now has a dkim module with a signer type that can
  be loaded from lua; signers are cached (with ttl) and shareable
* Message now has a dkim_sign method that does the signing, as well
  as methods for appending and prepending headers that are necessary
  to support signing.
2023-02-21 21:18:49 -07:00