Commit Graph
110 Commits
Author SHA1 Message Date
Wez Furlong a73912e7e1 rollup.lua: remove stray debug print 2023-08-12 07:24:29 -07:00
Wez Furlong 7aa80bc34a rollup.lua: add ip-based rollup
How it works:

* When the lowest preference MX host names match a pattern like
  `.mail.protection.outlook.com`, the message has its routing_domain
  set to a placeholder domain whose name ends with `.ip_rollup`.
* That results in a scheduled queue name like
  `foo.com!outlook.ip_rollup`, which makes it possible to know both the
  original domain and the fact that rollup is in use.
* `get_queue_config` can check to see if the routing_domain is set to
  something that ends with `.ip_rollup` to override the `mx_list`
  in the queue configuration with just the lowest preference IP
  addresses from the original domain.
* Now, instead of computing a site_name base around
  `foo-com.mail.protection.outlook.com`, which includes the individual
  original recipient domain, and would cause there to be a separate
  ready queue for each domain, the overridden mx_list causes
  the site_name to be eg: `mx_list:[104.47.24.36],[104.47.25.36]`.
  That same site_name will be used for every domain that shares those
  same IP addresses
* When `get_egress_path_config` is called to get shaping parameters,
  it is passed the routing domain `outlook.ip_rollup`. You can use that
  name with mx_rollup=false as the key in your shaping.toml, of if you
  are directly implementing `get_egress_path_config`, you can use that
  name to determine the appropriate configuration.

```lua
kumo.on('get_queue_config', function(domain, tenant, campaign, routing_domain)
  local params = {}
  rollup.apply_ip_rollup_to_queue_config(domain, routing_domain, params
  return kumo.make_queue_config(params)
end)

kumo.on('smtp_server_message_received', function(msg)
  rollup.reroute_using_ip_rollup(msg, {
    ['.mail.protection.outlook.com.'] = 'outlook.ip_rollup',
  })
end)
```

In your shaping.toml:

```toml
["outlook.ip_rollup"]
mx_rollup = false
 # shaping parameters here
```

Caveats:

* With this technique, we'll never try to use any of the lower
  priority/higher preference value MX records for any of the matching
  domains.
* The IP addresses to which the MX host names resolve can vary over time.
  We'll still queue the mail to the same scheduled queue (eg:
  `foo.com!outlook.ip_rollup`), but it's possible for there to be
  multiple ready queues with different names based on those changed
  IPs.  This is actually a feature: if the destination domain has
  an outage and are now publishing different IPs, we'll pick those up
  and use them.
* Since the ready queue names look like `mx_list:[104.47.24.36],[104.47.25.36]`
  it can be hard to intuit just from glancing at that name where those queues go.
2023-08-12 06:52:39 -07:00
Wez Furlong a08b780ab3 listener_domains.lua: add relay_from_authz option
This allows listing out authorization identities.
If the incoming client is authorized to act as one of the listed
`relay_from_authz` authorization identities, then the incoming
session will be added to the relay_from CIDR for the scope of
that connected session, and the result is that they will be allowed
to relay from the associated domain.

This is useful if you want to give a tenant SMTP auth credentials
but only want to allow them to send from the domain(s) that
they are permitted to send as/from.
2023-08-11 08:31:15 -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 c5409a7145 tsa: add systemd service that starts by default 2023-08-03 11:53:34 -07:00
Wez Furlong c8a040dfc4 tsa: teach shaping.lua to pull from the tsa-daemon
Refine the egress path update logic as part of that, so that we wake
sleeping Dispatchers to have them notice when it changes.
2023-08-03 11:36:02 -07:00
Wez Furlong a327e3db0c ready_queue: periodically refresh path_config
To facilitate more dynamically updating the configuration, this commit:

* Introduces a ConfigHandle type to aid in building shared configuration
  objects that don't require full mutex interlock
* Switches ReadyQueue and Dispatcher to hold egress path config in a ConfigHandle
* ReadyQueue maintainer will now refresh, by calling
  get_egress_path_config, the value in the config handle
* shaping.lua now uses a ttl of 1 minute (which is the same as the
  ReadyQueue maintainer interval), so that the ready queues should
  reflect egress path configuration changes approximately every minute.
2023-08-03 08:20:40 -07:00
Wez Furlong 22b5f43f84 shaping.lua: fix typo 2023-08-02 09:10:01 -07:00
Wez Furlong 16ea223ae8 tsa: basic rule matching
This is plumbing to perform rule matching.
It doesn't do anything useful with matches yet.
2023-08-01 13:58:50 -07:00
Wez Furlong 0565daf790 tsa: load shaping data on startup 2023-08-01 10:12:43 -07:00
Wez Furlong b8721831c2 packaging: add new binaries to rpm 2023-08-01 08:13:14 -07:00
Wez Furlong 907d724f01 listener_domains: cache compiled domain_maps
Make use of our new ability to memoize the compiled domain map
so that we can avoid rebuilding it on each lua hook invocation.

This should improve performance for sites with large numbers of
listener domains.
2023-07-31 16:57:16 -07:00
Wez Furlong 0e39fe35ff domain-map: allow use with memoize
This allows us to avoid rebuilding the map on each message reception
when using the dkim helpers, which should improve the performance
for sites with large numbers of signing domains.
2023-07-31 16:57:16 -07:00
Wez Furlong 45e1564459 shaping: use the rust parser in shaping.lua 2023-07-31 16:57:15 -07:00
Wez Furlong e4ca23f01e shaping: add rust merge/eval for get_egress_path_config
The intent is to allow this to be used from shaping.lua,
but a little more plumbing is needed before we can call it
from there.

Added some tests to sanity check that the data looks right.
2023-07-31 16:57:15 -07:00
Wez Furlong 53fd3c5f3c add rust parser for shaping.toml
This moves things around a bit so that we can parse the shaping.toml
data from rust, and expands it to add automation entries per-domain.

A new tool `validate-shaping` can now be used to validate the
shaping configuration independently of starting the server and
injecting mail.
2023-07-31 16:57:15 -07:00
Wez Furlong 270c72cd83 tsa-daemon can now ingest log records
Using the init_with_tsa.lua policy for kumod, together with
tsa_init.lua as the policy for tsa-daemon, logs from kumod
are now sent to tsa-daemon.

It doesn't do anything with them yet.
2023-07-31 16:57:15 -07:00
Wez Furlong b00d8a44db shaping: more prep for automation 2023-07-31 16:57:15 -07:00
Wez Furlong d2d6965d11 shaping: refactor in preparation for automation
Introduce a setup_with_automation entrypoint that will accept
a richer parameter struct to specify the shaping automation
daemon(s) to which to push logs and from which we will pull
configuration.

This is just a refactor: none of that stuff is done yet.
2023-07-31 16:57:15 -07:00
Wez Furlong f3ab16c2bf ci: add Mariner, attempt 1 2023-07-22 12:51:30 -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 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
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
Tom Mairs 0ee4f12243 fix typo in shaping.toml - issue #68 2023-06-20 19:14:54 +00:00
Wez Furlong a4e014b387 dkim_sign: fix http injection event name 2023-06-19 12:54:37 -07:00
Wez Furlong 1d5180a221 sources.lua: tolerate empty pool or source sections in a file
We can compose multiple files, so it is OK for there to not
be any sources or pools in any given file.
2023-06-16 08:46:35 -07:00
Wez Furlong fb1df13447 shaping.lua: make DNS resolution errors non-blocking
We'll just ignore the associated rules instead.

refs: #57
2023-06-16 07:49:15 -07:00
Wez Furlong 261f68078f sources.lua make_egress_poll typo -> make_egress_pool 2023-06-15 08:19:16 -07:00
Wez Furlong 4f56314f48 kumomta.service: increase shutdown timeout
The default of 90 seconds is too short for a busy server.
Increase to 5 minutes.
2023-06-15 07:36:52 -07:00
Wez Furlong 420dade8fb sources.lua: fixup initialization of name
refs: https://github.com/KumoCorp/kumomta/issues/56
2023-06-14 19:56:16 -07:00
Wez Furlong 628cda23ce shaping.lua: table_keys lives in utils 2023-06-12 16:07:47 -07:00
Wez Furlong c31b7e8191 dkim_sign: wrap an around the additional_signatures bit over here too 2023-06-12 14:56:02 -07:00
Wez Furlong fe2f674180 listener_domains: defer building domain_map
Ideally we'd memoize the compiled map, but right now it isn't
compatible with being serialized, so we have to do it after
we call memoize
2023-06-12 14:26:11 -07:00
Wez Furlong 79f45005d5 dkim: defer building domain map
Ideally we'd memoize the compiled map, but right now it isn't
compatible with being serialized, so we have to do it after
we call memoize
2023-06-12 14:19:19 -07:00
Wez Furlong 22404630aa dkim_sign.lua: fix another data.base vs. base 2023-06-09 14:15:19 -07:00
Wez Furlong 87cffb945e dkim_sign.lua: avoid nil reference for additional_signatures 2023-06-09 13:06:27 -07:00
Wez Furlong 30bcf40497 dkim_sign.lua: fix array syntax for headers 2023-06-09 11:55:36 -07:00
Wez Furlong 643eecc9cc dkim_sign.lua: fixup base 2023-06-09 11:48:19 -07:00
Wez Furlong fd4aeb00a2 dkim_sign.lua: fixup missing vault_path_prefix usage 2023-06-09 11:47:27 -07:00
Wez Furlong 5001095044 dkim: sketch out an entirely untested dkim signing helper 2023-06-09 11:43:05 -07:00
Wez Furlong b930ee5ec1 shaping.toml: remove unresolvable protection.outlook.com domain
entries in this file must be resolvable domains, and this one
has neither A nor MX records
2023-06-08 14:39:27 -07:00
Wez Furlong 8625d9d182 ship proxy-server in the kumo rpms and docker image
In the future I want to add separate packages for just the proxy
server, but for now this is the most expedient way to deliver
the binary.

refs: https://github.com/KumoCorp/kumomta/issues/45
2023-06-07 15:24:06 -07:00
Wez Furlong 22451330f4 CLI: add kcli command for interacting with admin http endpoints
```console
$ kcli --help
KumoMTA CLI.

Full docs available at: <https://docs.kumomta.com>

Usage: kcli --endpoint <ENDPOINT> <COMMAND>

Commands:
  bounce
          Administratively bounce messages in matching queues
  set-log-filter
          Changes the diagnostic log filter
  help
          Print this message or the help of the given subcommand(s)

Options:
      --endpoint <ENDPOINT>
          URL to reach the KumoMTA HTTP API

  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version
```

```console
$ kcli bounce --help
Administratively bounce messages in matching queues.

Each individual message that is bounced will generate a log record capturing the event and then be removed from the spool.

Make sure that you mean it, as there is no going back!

The bounce will be applied immediately to queued messages, and the directive will remain in effect for the duration specified, causing newly received messages or messages that were in a transient state at the time the directive was received, to also be bounced as they are placed back into the matching queue(s).

Usage: kcli --endpoint <ENDPOINT> bounce [OPTIONS] --reason <REASON>

Options:
      --domain <DOMAIN>
          The domain name to match. If omitted, any domains will match!

      --campaign <CAMPAIGN>
          The campaign name to match. If omitted, any campaigns will match!

      --tenant <TENANT>
          The tenant name to match. If omitted, any tenant will match!

      --reason <REASON>
          The reason to log in the delivery logs

      --everything
          Purge all queues

      --duration <DURATION>
          The duration over which matching messages will continue to bounce. The default is '5m'

  -h, --help
          Print help (see a summary with '-h')
```

```console
$ kcli set-log-filter --help
Changes the diagnostic log filter

See <https://docs.kumomta.com/reference/kumo/set_diagnostic_log_filter/> for more information about the log filter syntax.

Usage: kcli --endpoint <ENDPOINT> set-log-filter <FILTER>

Arguments:
  <FILTER>

Options:
  -h, --help  Print help
```

refs: https://github.com/KumoCorp/kumomta/issues/55
2023-06-07 12:09:07 -07:00
Wez Furlong 7db243025e add policy helper for sources and pools 2023-06-01 13:08:05 -07:00
Wez Furlong e8a049cc83 document listener parameter to get_listener_domain update helpers
Allow per-listener listener-domain configuration
2023-05-31 15:46:12 -07:00
Wez Furlong 9708bbb1de fix more typos 2023-05-31 12:44:46 -07:00
Wez Furlong 97f5abfcf0 fix typo 2023-05-31 12:34:02 -07:00
Wez Furlong ce7dece927 move domains out of listener, replace with get_listener_domain event
This commit also includes a policy helper
`policy_extras.listener_domains` to make it convenient to define
listener domains in toml and/or json files.

To facilitate this, the DomainMap rust structure has been exposed
to lua code via the new `kumo.domain_map.new` function.
2023-05-31 12:29:44 -07:00