MTA integration
xListman integrates with an existing mail server rather than replacing it. Your MTA accepts mail for the list domain and hands it to xListman over LMTP (or the pipe-mode Unix socket); xListman delivers outbound mail back through your relay.
This is the step most first-time setups underestimate. Set aside time for it, and test each leg before moving on.
The flow
- Inbound. A message to
dev@example.comarrives at your MTA. It is routed to xListman’s LMTP server, which parses the address —dev@example.comis a post,dev-subscribe@…is a subscription request,dev-request@…is an email command, and so on. - Outbound. Posts, digests, and notices go through a persistent queue and out
via SMTP to your relay (
smtp.host:smtp.port). - The bounce reverse leg. Outbound envelope senders are VERP-encoded — a
message to
alice@work.comondev@example.comleaves with envelope senderdev-bounces+alice=work.com@example.com. If delivery fails, your MTA bounces a DSN back to that address, which routes in through the same LMTP transport and is attributed to Alice’s subscription. The reverse leg is part of the loop, not a separate channel.
Which path to use
- LMTP — the primary path, validated end to end against Postfix and exim, including the VERP bounce reverse leg. Use this unless you have a reason not to.
- Pipe mode — a Unix socket that a mail filter program hands messages to
(
xlistman deliver <address>). For setups where you’d rather pipe mail than run an LMTP listener.
The LMTP server
The LMTP server listens on lmtp.listen (:8024 by default) and is unauthenticated. In production, bind it to a private interface
(127.0.0.1:8024) so only your MTA can reach it — don’t leave it exposed on a
public address.
Guides
- Postfix — the
virtual_transportwiring. - exim — the
manualrouterouter to an LMTP transport. - Pipe mode — using
xlistman deliverwith a pipe-based MTA config.
Testing without an MTA
To exercise xListman’s inbound half before wiring a real MTA, set smtp.mode: sink. Outbound mail is written as files to smtp.sink_dir instead of being
relayed, so you can confirm the full pipeline with nothing but the binary:
smtp:
mode: "sink"
sink_dir: "./mail"
Each outbound message becomes one <nanoseconds>-<recipient>.eml file with X-Envelope-From: and X-Envelope-To: headers prepended.