Commit Graph

1295 Commits

Author SHA1 Message Date
Jagoda Estera Ślązak a9dd9fe3e0 docs: Update overview diagrams (#995)
Adds a detailed diagram describing
all paths a message can take,
that takes into account postfix services.

Additionally, adds OpenDKIM to dependency
diagram.

Fixes: #771
Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
Co-authored-by: missytake <missytake@systemli.org>
2026-06-03 12:24:32 +02:00
missytake aa846c3478 fix: expire empty directories (#994)
* fix: respect --dry when expiring empty directories

Co-authored-by: j4n <j4n@systemli.org>
2026-06-03 10:42:28 +02:00
feld 921080125f Aggressive LMTP header cleanup (#816)
This will remove all headers possible during LMTP delivery, except:

- From: required or core does not process the message correctly.
  Also required for cleartext compatibility.
- Message-Id: required for clients to know which messages have been
  downloaded
- Chat-Is-Post-Message: is required for our attachment previews
- Content-Type: required
- For Cleartext compability: To, CC, In-Reply-To, References, Subject,
  and Date
- For Chatmail future expansion, allow Chat-*
- Permit the entire Secure-Join* namespace

Co-authored-by: holger krekel  <holger@merlinux.eu>
2026-06-03 08:43:36 +02:00
Jagoda Estera Ślązak d898f41064 fix: Always deploy unbound.conf.d/chatmail.conf (#993)
This fixes issue with negative cache
only disabled in ipv4-only mode.

Follow up to #992

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-06-02 12:02:07 +02:00
Jagoda Estera Ślązak e9e012234b feat: Disable negative cache in unbound (#992)
Related:
- https://github.com/chatmail/relay/issues/543
- https://github.com/chatmail/filtermail/pull/170

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-06-02 10:48:28 +02:00
Jagoda Estera Ślązak bb40c5bb21 fix: Check if all required ports are available for filtermail (#983)
Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-06-01 11:10:25 +02:00
Jagoda Estera Ślązak a229f1bc45 chore(deps): Upgrade filtermail to v0.7 (#982)
## 0.7.0 - 2026-05-26

### Bug Fixes

- Do not crash if accepting new connection fails

### Documentation

- *(readme)* Remove docs for options removed in da9a116

### Features

- [**breaking**] Remove passthrough options that allowed unencrypted mail to pass

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-06-01 09:55:50 +02:00
link2xt 4ba19b0031 test: set socket security for IMAP and SMTP to "TLS" in "dclogin"
With "default" (like it was for SMTP) or not set (like it was for IMAP),
both TLS and STARTTLS are tried.
Trying STARTTLS against TLS port is going to timeout
because in STARTTLS server talks first,
but when connected to TLS port the server
waits for TLS client hello and does not send anything.

Should not actually matter in tests which connect successfully
on the first try because implicit TLS is tried first.
2026-05-28 22:29:08 +00:00
holger krekel 5eab3a5a25 try using cmlxc main branch fix for delete-server issue 2026-05-28 21:40:05 +02:00
holger krekel 30729d9be0 fix: core 2.50.0 does not have delete_server_after config anymore. 2026-05-28 21:40:05 +02:00
link2xt 4b04aae83b feat: reduce maximal_queue_lifetime from 5d to 2d
If the message is not delivered within 2 days,
it is unlikely to be delivered in 5 days either.
2026-05-20 19:27:58 +00:00
link2xt 0eed92171c fix: reduce maxproc for filtermail-transport LMTP client to 500
This further reduces it from 1000.
For small servers this may be needed if they have low memory.
For large servers may be increased manually for now.
2026-05-20 15:39:11 +00:00
link2xt a5b9a98baa fix: limit the number of LMTP clients for filtermail-transport to 1000
Postfix does not have jitter for deferred mails
and scans the queue periodically every
queue_run_delay (<https://www.postfix.org/postconf.5.html#queue_run_delay>).
As a result it is likely
to try delivering many deferred messages
at the same time.

Normally the number of outgoing connections
should be low even with unreachable destinations,
but after the server downtime
or if admin flushes the queue manually
it is possible that a lot of messages
to the same unreachable destination
expire at once and are moved
from "deferred" into the "active" queue.

Trying to deliver them all at once
may make the server run out of memory
by starting many LMTP clients.
Limiting the number of LMTP processes
turns OOM problem into head of line blocking problem.
Messages sent to reachable destinations
will be delayed as well,
but at least deferred messages will
get distributed over time.

In this case "active" queue may grow
(up to qmgr_message_active_limit defaulting to 20000),
but then admin may notice the problem
and solve it e.g. by making the destinations reachable
or setting up a transport map to route
messages for known dead servers into discard transport.

Eventually the problem should be solved
by filtermail-transport quickly returning temporary errors
for destinations which already have many messages queued,
then we can reduce "maxproc" further.
2026-05-19 22:17:04 +00:00
link2xt ab2d807084 fix: set relay restrictions per smtpd service with default reject
We never want to defer email with a tepporary error when it has destination
that we cannot deliver locally and don't want to relay.
To avoid doing this accidentally, set default action to "reject"
and then override it with the minimal restrictions per smtpd.

Submission ports already had smtpd_relay_restrictions=permit_sasl_authenticated,reject override.

Each smtpd port must have at least one of
reject, reject_unauth_destination, defer, defer_if_permit, defer_unauth_destination
according to <https://www.postfix.org/postconf.5.html#smtpd_relay_restrictions>.

I have set smtpd_relay_restrictions=reject_unauth_destination for port 25 and incoming reinject port,
and smtpd_relay_restrictions=permit_mynetworks,reject for outgoing reinject port.
2026-05-19 15:54:15 +00:00
j4n ce05b26c77 ci: auto-trigger docker build on release tag push
docker-dispatch.yaml previously only fired on push to main and manual
workflow_dispatch, so tagging 1.11.0 did not build the release image.
This change adds matching of X.Y.Z tag.
2026-05-19 14:58:05 +02:00
missytake 77ed93fb7a docs: add scripts/initenv.sh to upgrade instructions 2026-05-18 10:35:25 +02:00
missytake 39d1ecaa03 chore(release): prepare for 1.11.0 2026-05-15 17:13:58 +02:00
holger krekel a266ffd060 fix: fix #972 by increasing file descriptors for filtermail 2026-05-14 22:40:25 +02:00
holger krekel a47bb94143 feat: warn about any unused chatmail.ini parameter at the end of "cmdeploy run" 2026-05-14 20:58:47 +02:00
holger krekel 43ae9fee5c feat!: ignore passthrough_sender and passthrough_recipients to eliminate one more source of unencrypted messages
When running "cmdeploy run" operators will see a warning if their chatmail.ini contains these unused options.
2026-05-14 20:58:47 +02:00
holger krekel 42dc781d7d feat: make turn_socket_path configurable, and cleanup tests and turnserver code.
this is originally motivated by https://github.com/chatmail/relay/pull/840
2026-05-13 21:02:28 +02:00
missytake ed664cd9cd feat(config): load default values from Config(), not chatmail.ini.f (#853)
* config: comment out values in chatmail.ini.f, so defaults take precedence
* config: remove testrun-specific overrides
* config: remove filtermail ports from default ini
2026-05-12 22:44:06 +02:00
holger krekel 26a13fbc26 feat: DKIM-sign bounce messages (mainly "user does not exist")
This was originally based on Jagoda's https://github.com/chatmail/relay/pull/874
but then the postfix config was simplified, and it comes with a simpler and more robust test.
2026-05-12 14:19:11 +02:00
missytake d054fbb5aa docs: document how to upgrade to new version (#965)
Co-authored-by: Jagoda Estera Ślązak <128227338+j-g00da@users.noreply.github.com>
2026-05-12 14:13:28 +02:00
j4n def08c52f4 feat(doc/docker): Introduce docker images in documentation 2026-05-12 13:45:21 +02:00
Jagoda Estera Ślązak 32cfa9c76c chore(deps): Upgrade filtermail to v0.6.6 (#967)
## 0.6.6 - 2026-05-12

### Bug Fixes

- Return HTTP 200 because madmail expects it, and make sure https is immediately retried when SMTP fails

### Features

- Improved SMTP error responses

### Miscellaneous Tasks

- Remove mac and windows from matrix tests
- Run cmlxc tests in all classic/classic-ipv4/madmail combinations

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-05-12 13:24:23 +02:00
Jagoda Estera Ślązak c0b207c320 chore(deps): Upgrade filtermail to v0.6.5 (#966) 2026-05-12 10:37:28 +02:00
holger krekel 4ebde2825d feat: support setup without domain, with only an IPv4 address (#963)
* dovecot: enable login names with square brackets

* config: make IPv4-only relays use self-signed TLS certs

* postfix: make delivery for IP-only relays work

* cmdeploy: skip DNS checks for IPv4 only relays

* www: generate dclogin codes for IPv4-only relays

* opendkim: disable DKIM signing on ipv4-only relays

* get delivery working

* get tests working on IPv4 only machine

* doc: document IPv4-only relays

* dns: warn if mail_domain is an IP, instead of checking DNS

* config: validate domains when formatting them

* ci: add cmlxc testing for no-DNS relays

* ci: run no-dns and normal CI in parallel

* retain "config.mail_domain" as the domain part of @ email addresses, so for ipv4 relays  "[1.2.3.4]" and introduce config.ipv4_relay and config.mail_domain_bare helpers.

* ci: migrate from --no-dns to --type ipv4 for cmlxc compatibility

* cleanup dead code, fix docs, fixate cmlxc version

---------

Co-authored-by: missytake <missytake@systemli.org>
2026-05-11 21:52:33 +02:00
holger krekel 6a7e6ce9e7 feat: expose metadata "maxsmtprecipients" value
also add metadata tests and make metadata lookup method more readable by using structural match/case syntax
2026-05-11 20:08:38 +02:00
holger krekel 8db668c037 fix(logging): log all http requests to syslog 2026-05-10 23:32:42 +02:00
holger krekel 45fafa10a9 fix: legacy token metadata storage used list type, but if no new setmetadata happened, the user would not be notified at all. 2026-05-08 21:39:40 +02:00
missytake ee435a7ef7 fix(dns): query correct NS if MNAME server is hidden (#954)
replaces #870
fix #851

* fix(dns): address possible IndexError
* fix(dns): remove redundant docstring
* fix(dns): don't make NS explicit if None
* bump cmlxc to 0.13.5 which fixes a powerdns config issue
* remove the unneccessary SOA mocks, simplify mock tests, and run ruff format

Co-authored-by: holger krekel <holger@merlinux.eu>
2026-05-08 19:34:42 +02:00
missytake 8fafd4e79f fix(nginx): properly redirect www to mail_domain 2026-05-07 23:00:02 +02:00
punkero-org 129b8a20bc fix(cmdeploy): stop and disable unbound-resolvconf
Commit 825831e purges resolvconf, however the unbound service
activates a 'wants' unit for async resolvconf updates. This
results in errors in systemd startup as the unit will now always fail.

Stop and disable the unbound-resolvconf unit activation
2026-05-07 13:40:19 +02:00
holger krekel a1f64ebd96 refactor: introduce automated change-tracking across deployers 2026-05-06 20:02:13 +02:00
j4n fb64be97b5 fix(mtail): correct boot ordering and deploy restart logic
Correct the systemd unit modifications in 98bc1503 that lead to startup
failures in some instances. Switch to After+Wants = network-online.target
and add RestartSec=2s to give late-binding more interfaces time to appear.

In the deployer, capture the files.template() return value and
appropriately set need_restart and daemon_reload.
2026-05-06 14:04:32 +02:00
Jagoda Estera Ślązak b05e26819f fix: Increase concurrency limit and re-enable filtermail-transport (#949) 2026-05-05 18:30:20 +02:00
Jagoda Estera Ślązak 1db586b3eb fix(filtermail): Disable filtermail-transport for now (#948)
Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-05-05 09:07:06 +02:00
Jagoda Ślązak 44fe2dc08f fix: Use path with no leading slash for mxdeliv
For compatibility with madmail,
we want to use path with no leading
slash. This change saves us from
having to follow redirects.

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-05-01 17:37:35 +02:00
Jagoda Ślązak 8721600d13 build(deps): Upgrade to filtermail v0.6.4
Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-05-01 17:37:31 +02:00
Jagoda Ślązak dfed2b4681 feat: Use filtermail for delivery to remote MTAs
Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-05-01 17:37:28 +02:00
holger krekel f5fd286663 fix: make www tests work with editable instead of just plain installs 2026-05-01 16:52:09 +02:00
missytake 16b00da373 chore: prepare 1.10.0 release (#943)
Co-authored-by: j4n <j4n@systemli.org>
1.10.0
2026-04-30 15:51:17 +02:00
j4n 75606f5eb8 fix(mtail): start after networking is fully up 2026-04-30 14:23:32 +02:00
holger krekel d256538f81 testing: support custom filtermail binary through CHATMAIL_FILTERMAIL_BINARY env var 2026-04-29 20:27:12 +02:00
link2xt fdf8e5e345 ci: setup zizmor
Zizmor is a linter for GitHub Actions
2026-04-29 16:58:19 +00:00
j4n 81a161d433 feat(ci): add repository_dispatch trigger to chatmail/docker
On push to main send a repository_dispatch event to chatmail/docker with
relay_ref, relay_sha, and relay_sha_short.

This triggers docker-ci.yaml to build a new Docker image from
the updated relay code, push to GHCR, and eventually run integration
tests via cmlxc's reusable lxc-test workflow.

Requires DOCKER_DISPATCH_TOKEN secret with repo scope on
chatmail/docker.

Also set workflow_dispatch to allow manual triggering of Docker builds
from any relay branch via the GitHub UI.
2026-04-29 15:43:19 +02:00
link2xt 454ac6248a docs: add documentation on reverse DNS (PTR) records 2026-04-27 16:43:29 +00:00
link2xt 85915652b3 feat: do not bind SMTP client sockets to public addresses
This change reverts 06560dd071

Main reason for using the same address for sending
as the one used in DNS is to pass FCrDNS
(forward-confirmed reverse DNS) checks:
IP address used by SMTP client should resolve
to the domain which in turn resolves to the same IP.
chatmail relays don't do check reverse DNS
for incoming connections,
but other email servers may do and reject email
if the check does not pass.

Most chatmail relays only have one IP address per address family,
so this configuration does not change anything.

For chatmail relays that have multiple addresses
and only publishing one IP to DNS,
source address used for outgoing SMTP connections
should be the public IP.

This can be ensured by configuring the source
address in the routing table,
e.g. with the `src` argument
to `ip route add/change/replace` command.

Solving this by binding SMTP client address
on the application level prevents chatmail relays
from configuring alternative routes.

Besides, some chatmail relays are NATed
and NAT is responsible for translating the address to the public one,
in which case using `smtp_bind_address_enforce`
will result in unnecessarily deferring all mails.
2026-04-27 16:43:29 +00:00
link2xt 1e8c56e08a docs(doc/README.md): scripts/initenv.sh should be used for building the docs
doc/README.md was outdated, it did not include sphinxcontrib-mermaid.
Better use scripts/initenv.sh which already installs all dependencies
and is used in CI.
2026-04-24 21:18:58 +00:00