Postfix

The Postfix configuration is two lines. The substance is knowing which knobs not to turn.

The wiring

Add to /etc/postfix/main.cf:

virtual_mailbox_domains = lists.example.com
virtual_transport = lmtp:[127.0.0.1]:8024
  • virtual_mailbox_domains — the list domain Postfix should accept mail for and route onward.
  • virtual_transport = lmtp:[127.0.0.1]:8024 — hand those messages to xListman’s LMTP server. The [127.0.0.1] bracket syntax pins the LMTP client to that host so no MX lookup happens.

Then reload Postfix:

sudo postfix reload

What not to do

  • Don’t put the list domain in mydestination. That makes Postfix treat it as a local domain and apply local_recipient_maps, which rejects addresses like dev-subscribe@… as unknown local users before xListman ever sees them.
  • Don’t put it in relay_domains. Relay semantics are wrong for a final-delivery agent; this is your final delivery.
  • Don’t rely on recipient_delimiter. Postfix’s LMTP client does not apply it — it passes the full dev+role@domain envelope recipient through, and xListman parses the role suffix itself. That’s exactly what you want.

The bounce reverse leg

The VERP bounce path works only when your MTA accepts a bad recipient at SMTP time and then fails at final delivery, so a DSN (with the null envelope sender MAIL FROM:<>, per RFC 3464) bounces back to the VERP address. A handy trigger for testing: an aliases entry mapping a subscribed address to a user that doesn’t exist.

# /etc/aliases
deadbeat: no_such_local_user_xyz

The address is accepted at RCPT (250), then local(8) fails at delivery — the DSN routes through LMTP back to xListman’s bounce handler, and the subscription’s bounce count increments. Bounce it past the list’s bounce_threshold and the subscription disables, which is the full loop working end to end.

Binding the LMTP server

The LMTP server is unauthenticated, so in production make sure lmtp.listen in your xListman config binds a private interface:

lmtp:
  listen: "127.0.0.1:8024"

so only Postfix on the same host can reach it.

Next: exim.