#pMtaFilters
Milters (Sendmail milter protocol) and MTA hooks (HTTP per SMTP stage)
Existing filters plug straight into the SMTP dialogue: milters speak the Sendmail milter protocol version 6 (Rspamd through its milter proxy, ClamAV-milter, OpenDKIM, DLP products); MTA hooks are plain HTTP services that receive a JSON document per stage (CONNECT, EHLO, MAIL FROM, RCPT TO, DATA) and return a decision. Both run for inbound mail (port 25) and optionally for submission (465/587). Configure them under Milters & MTA hooks (#pMtaFilters), each entry with a test button.
Choose the default action deliberately: "accept" (fail open) keeps mail flowing when a filter is down, "tempfail" (like Postfix milter_default_action = tempfail) makes senders retry later until the filter is back. For virus scanners tempfail is safer, for scoring services accept. Quarantine puts inbound mail into the Junk folder; on submission the message is rejected with 550.
MTA hook response (Stalwart compatible)
Request: context (stage, client, sasl, tls, server, queue, protocol), envelope (from, to) and at DATA message (headers, contents, size). Signature in the X-Nextxch-Signature header: sha256=HMAC over the body.
POST https://dlp.internal/hook (X-Nextxch-Hook-Stage: data)
{
"action": "accept",
"modifications": [
{ "type": "addHeader", "name": "X-DLP-Status", "value": "clean" },
{ "type": "changeHeader", "index": 1, "name": "Subject", "value": "[external] Offer" },
{ "type": "deleteHeader", "index": 1, "name": "X-Internal-Route" }
]
}
{ "action": "reject", "response": { "status": 550, "enhancedStatus": "5.7.1", "message": "Confidential data detected" } }
{ "action": "tempfail", "response": { "status": 451, "message": "Please try again later" } }
{ "action": "quarantine" } { "action": "discard" }
Settings, Default Values & Best Practices
| Setting / Location | Description | Default Value | Production Best Practice |
|---|---|---|---|
Milter-Adresse |
TCP or Unix socket of the milter: inet:host:port, inet:port@host (Sendmail notation), host:port or unix:/path. | - |
Rspamd: inet:127.0.0.1:11332 (proxy worker with milter = yes). ClamAV-milter: unix:/run/clamav/clamav-milter.ctl or inet:127.0.0.1:7357. |
Phasen und Aktionen (Milter) |
Option negotiation v6, macros (j, {client_addr}, i, {auth_authen}, {mail_addr}, {rcpt_addr}), connect, helo, mail, rcpt, data, header, eoh, body, eom. Replies: accept, continue, reject, tempfail, discard, reply code, quarantine. Modifications: add, insert and change headers, replace body, add/delete recipients, change sender. | alle angeboten |
Stages the milter switches off (SMFIP_NO*) are not sent; stages without reply (SMFIP_NR_*) are not waited for. |
Zeitlimits |
Connect, per command and for content/end of message, set separately; progress replies extend the content timeout. | 5 s / 10 s / 60 s |
Raise the content timeout to 120 to 300 s for virus scanners with large attachments. |
MTA-Hook Phasen und Sicherheit |
Per hook: connect, ehlo, mail, rcpt, data. Optional auth header (e.g. Authorization: Bearer ...) and HMAC-SHA256 signature; both are stored encrypted and never shown. | data |
Enable only the stages you need: each call adds the hook's response time to the SMTP dialogue. The hook should answer in under a second. |
Reihenfolge |
Milters and hooks run by their order field; the first rejection ends the chain. At DATA each filter sees the message with the changes of the ones before. | Milter 100, Hooks 200 |
Put fast, cheap checks (e.g. reputation) before expensive ones (virus scan). |