Profile in integrations/postfix (install.sh + README), now used by the live deployment. Probe runs every conformance-corpus local-part and the relay negatives against it; tests/test_postfix_profile.py runs it where Docker is available. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 5787@bnt-lap001 Assistant-Session: 5db26b82-138b-40cc-9856-4d5eb0f752fd
51 lines
2 KiB
Markdown
51 lines
2 KiB
Markdown
# Exim notes (MAS-WP-0004 T03)
|
|
|
|
No Exim profile is shipped, because there is no demand yet. These notes say
|
|
what one would need. The ACL finding was checked against the stock config
|
|
of Debian bookworm `exim4-daemon-light` (Exim 4.96, 2026-10-19). The router
|
|
and transport points come from the Exim documentation and are untested.
|
|
|
|
## Pitfalls
|
|
|
|
- **Stock ACL rejects every P2 address.** `acl_check_rcpt` denies local
|
|
domains' local-parts that match `CHECK_RCPT_LOCAL_LOCALPARTS`, which
|
|
defaults to `^[.] : ^.*[@%!/|`#&?]`. So `ticket!callback@D` and
|
|
`ticket=PR%2B42@D` get `550 restricted characters in address`. This is the
|
|
same failure class as Postfix's `reject_unauth_destination`. Upstream
|
|
Exim's example `configure` has the same rule (`^[.] : ^.*[@%!/|]`).
|
|
- **Percent hack** is off by default (`percent_hack_domains` unset), so `%`
|
|
is not rewritten once the ACL lets it through. Exim has no bang-path
|
|
rewriting.
|
|
- **Case.** Routers lower-case `$local_part` unless `caseful_local_part =
|
|
true`, which would hide `Ticket=PR42` (invalid in MAS) as `ticket=PR42`.
|
|
- **Suffixes.** A router with `local_part_suffix = +*` strips facets before
|
|
the transport sees them. Do not set it on the MAS router.
|
|
|
|
## Settings a profile would need
|
|
|
|
```
|
|
# main section: drop % and ! from the local-domain restriction
|
|
CHECK_RCPT_LOCAL_LOCALPARTS = ^[.] : ^.*[@/|`#&?]
|
|
|
|
# router, first for the MAS domain
|
|
mas:
|
|
driver = accept
|
|
domains = D
|
|
caseful_local_part = true
|
|
transport = mas_pipe
|
|
|
|
# transport: one recipient per call, envelope recipient as received
|
|
mas_pipe:
|
|
driver = pipe
|
|
batch_max = 1
|
|
user = mas
|
|
command = /usr/local/bin/mas-gateway --statute <statute> \
|
|
--trusted-authserv-id D pipe --app-url <url> \
|
|
--recipient ${quote:$local_part}@$domain
|
|
```
|
|
|
|
Keep `CHECK_RCPT_REMOTE_LOCALPARTS` as it is: relaying stays closed, and only
|
|
D is a local domain. Sender authentication would use Exim's built-in
|
|
`dkim`/`spf`/`dmarc` ACL conditions with `add_header =
|
|
Authentication-Results: D; ...`. Incoming A-R headers for D must be removed
|
|
first (`headers_remove`).
|