Wez Furlong d5b13a263b Add kumo.configure_bounce_classifier
and connect it to the logger
2023-03-02 08:59:03 -07:00
2023-03-02 08:59:03 -07:00
2023-02-25 14:59:20 -07:00
2023-02-10 16:44:10 -07:00
2023-03-02 08:27:32 -07:00
2023-02-21 21:18:49 -07:00
2023-02-21 21:18:49 -07:00
2023-03-01 07:45:09 +00:00
2023-02-15 06:51:59 -07:00
2023-02-27 17:27:48 -07:00
2023-02-15 06:51:59 -07:00

kumomta

Concepts

Queuing

Messages are assigned to a queue upon reception. The system can support arbitrarily named queues but the convention is to construct the queue name from some metadata associated with the message:

  • tenant - some kind of sender or customer identifier or identity derived either from the message itself or authentication of the injection session.
  • campaign - a sender-provided label that can be used to logically group a set of related messages, perhaps generated from the same campaign.
  • destination domain - the site where the email will be routed

These three pieces of information are combined to produce the name of the queue in the form campaign:tenant@domain.

graph TD
   DQ["Queue: campaign:tenant@domain.com"]
   SMTPL["ESMTP Listener"]
   HTTPI["Injection API"]
   RQ1["Ready Queue: 10.0.0.1->MX(domain.com)"]
   RQ2["Ready Queue: 10.0.0.2->MX(domain.com)"]
   POOL["egress pool"]
   IP1["Source: 10.0.0.1"]
   IP2["Source: 10.0.0.2"]
   MAINT["Queue Maintainer"]
   DESTSITE["domain.com"]
   
   SMTPL --> DQ 
   HTTPI --> DQ
   DQ --> MAINT
   IP1 --> POOL
   IP2 --> POOL
   POOL -- per tenant:domain config --> MAINT
   MAINT -- throttle per tenant:domain config --> RQ1
   MAINT -- throttle per tenant:domain config --> RQ2
   RQ1 -- throttle per source:domain config\nconnect via 10.0.0.1 --> DESTSITE
   RQ2 -- throttle per source:domain config\nconnect via 10.0.0.2 --> DESTSITE
   

Debugging/Tracing

This will launch the server using the policy defined in simple_policy.lua:

KUMOD_LOG=kumod=trace cargo run -p kumod -- --policy simple_policy.lua

Metrics

If the http listener is enabled, the /metrics endpoint will return a set of metrics for prometheus to scrape.

You can manually review them with curl:

$ curl 'http://127.0.0.1:8000/metrics'
# HELP connection_count connection_count
# TYPE connection_count gauge
connection_count{service="esmtp_listener"} 1
connection_count{service="smtp_client:(alt1|alt2|alt3|alt4)?.gmail-smtp-in.l.google.com."} 0
# HELP delayed_count delayed_count
# TYPE delayed_count gauge
delayed_count{queue="gmail.com"} 1

Contributing

Ensure that the code is formatted before submitting a PR.

You need to install StyLua to format lua:

$ cargo install stylua --features lua54

Then you can format both the rust and the lua code:

$ make fmt

Docker build

To build a lightweight alpine-based docker image:

$ ./docker/kumod/build-docker-image.sh
...
$ docker image ls kumomta/kumod
REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
kumomta/kumod   latest    bbced15ff4d1   3 minutes ago   116MB

You can then run that image; this invocation mounts the kumo src dir at /config and then the KUMO_POLICY environment variable is used to override the default /config/policy.lua path to use the SMTP sink policy script sink.lua, which will accept and discard all mail:

$ sudo docker run --rm -p 2025:25 \
    -v .:/config \
    --name kumo-sink \
    --env KUMO_POLICY="/config/sink.lua" \
    kumomta/kumod

Fuzzing

Some components have fuzzer coverage. To run it, follow the setup from the Rust Fuzz Book

Then:

$ cd crates/rfc5321/
$ cargo +nightly fuzz run parser
S
Description
The first Open-Source high-performance MTA developed from the ground-up for high-volume email sending environments.
Readme 37 MiB
Languages
Rust 91.7%
Lua 6.3%
Python 0.9%
Shell 0.8%
JavaScript 0.1%