MAS-WP-0004: Postfix integration profile, corpus probe in pytest, Exim notes
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
This commit is contained in:
parent
082d4c39eb
commit
d766d61e7f
12 changed files with 1029 additions and 98 deletions
51
integrations/exim/NOTES.md
Normal file
51
integrations/exim/NOTES.md
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# 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`).
|
||||
Loading…
Add table
Add a link
Reference in a new issue