From 82a9850a4b60dfa4fab3d38b7fab4471fc1e66d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jagoda=20Estera=20=C5=9Al=C4=85zak?= <128227338+j-g00da@users.noreply.github.com> Date: Thu, 12 Mar 2026 18:15:08 +0100 Subject: [PATCH] docs(readme): Improve README.md (#88) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #85 Signed-off-by: Jagoda Ślązak --- filtermail/README.md | 114 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/filtermail/README.md b/filtermail/README.md index 5a30e70f..00e4392b 100644 --- a/filtermail/README.md +++ b/filtermail/README.md @@ -1,12 +1,124 @@ # filtermail -Rust drop-in reimplementation of chatmaild's filtermail. +A postfix smtpd proxy filter used by [chatmail relay](https://github.com/chatmail/relay). + +Filtermail is a fast, minimal and secure Rust-based SMTP before-queue filter. +By acting as a protocol-aware proxy for incoming and outgoing messages, +it enforces mandatory end-to-end encryption, +performs DKIM verification, +and handles per-sender rate limiting. ## Usage ```plain filtermail (incoming|outgoing) ``` +where `` is a path to `chatmail.ini` configuration file. + +Filtermail can be used in `incoming` or `outgoing` mode that apply different settings +to filter either incoming or outgoing emails. + +### Incoming mode + +Filtermail in incoming mode performs following steps: + +1. Rejects messages if `DATA` exceeds configured message size limit. +2. Rejects messages that do not meet at least one of the following criteria: + - PGP encrypted, + - securejoin message, + - mailer-daemon message, + - all recipients allow cleartext + (`enforceE2EEincoming` is not present in their mailbox directory). +3. If `MAIL FROM` doesn't match `From` header, +the address is removed from `MAIL FROM` on reinjection +(prevents bounces to possibly spoofed `MAIL FROM`). +4. Checks message origin, +depending on address type: + - **domain** - performs a strict DKIM verification and domain alignment check + (domain of address from `From` header must exactly match the DKIM signature domain), + rejecting messages that fail. + - **domain-literal (IP address)** - rejects message if the IP in domain-literal of `From` header address + does not match the origin IP received by `XFORWARD` command. +5. In case of a DKIM failure, +the message is saved to `/tmp/filtermail-rejected/dkim-verify` directory for later inspection. + +### Outgoing mode + +Filtermail in outgoing mode performs following steps: + +1. Rejects messages at `MAIL FROM` stage if the address exceeded rate limit. +2. Rejects messages if `DATA` exceeds configured message size limit. +3. Rejects messages which `From` header address does not match one in `MAIL FROM`. +4. Rejects messages that do not meet at least one of the following criteria: + - PGP encrypted, + - securejoin message, + - sender is in `passthrough_senders`, + - self-sent Autocrypt Setup Message, + - all recipients match `passthrough_recipients`. + +## Configuration + +### chatmail.ini + +Filtermail shares the same configuration file as chatmail relay, +but implements a custom parser that only requires a small subset of configuration options: + +- `filtermail_smtp_port` - port to listen on in outgoing mode, +defaults to `10080`. +- `filtermail_smtp_port_incoming` - port to listen on in incoming mode, +defaults to `10081`. +- `postfix_reinject_port` - port to reinject messages to postfix in outgoing mode, +defaults to `10025`. +- `postfix_reinject_port_incoming` - port to reinject messages to postfix in incoming mode, +defaults to `10026`. +- `max_message_size` - maximum allowed message size in bytes, +defaults to `31457280` (30 MiB). +- `max_user_send_per_minute` - email sending rate per user and minute, +defaults to `60`. +- `max_user_send_burst_size` - per-user max burst size for sending rate limiting (GCRA bucket capacity), +defaults to `10`. +- `passthrough_senders` - space separated list of email addresses +which can send outbound un-encrypted mail. +- `passthrough_recipients` - space separated list of email addresses +which can receive inbound un-encrypted mail, +item may start with `@` to whitelist whole recipient domains. +- `mail_domain` - domain name used in email addresses. +- `mailboxes_dir` - path to mailboxes directory, +defaults to `/home/vmail/mail/`. + +### Environment variables + +Additional options that can be set using environment variables: + +- `RUST_LOG` - set log level, +defaults to `info`. +- `FILTERMAIL_SKIP_DKIM` - completely skip DKIM verification; +only for testing purposes and not recommended for production use, +defaults to `0`. + +## Usage outside of chatmail relay + +**Filtermail development is focused on supporting it as a systemd service used by chatmail relay.** +Althrough unsupported, it may still work outside of this context or even without postfix, +with few considerations: + +- Filtermail expects to receive messages from a trusted server, +and thus should not be exposed directly to the internet. +- In incoming mode it expects to receive `XFORWARD` commands with the origin IP, +if the other server doesn't support this, +it will lead to rejection of every email using domain-literals in it's `From` header address. +- Issues outside of chatmail relay context are not necessarily considered bugs; +PRs fixing them are not guaranteed to be accepted. +(Trivial changes may still be considered, +please open an issue to discuss any such changes before working on them). + + +## Releases + +Filtermail is distributed as a statically linked linux binary, +available for `x86_64` and `aarch64` architectures. + +Binaries are available on the [releases page](https://github.com/chatmail/filtermail/releases). ## License