MSA (by alaric)
I've just written an MSA daemon.
The role of an MSA (Mail Submission Agent) is defined in RFC2476.
An MSA is like an MTA. It accepts SMTP, but on a different port. The idea is that initial submission of email to a mail relay is a different thing from inter-MTA transfer, so a different port is justified. That means that the incoming connections on port 587 can require authentication (either by source IP or by SMTP AUTH) and then have mail relay access, while incoming connections on port 25 are from the general Internet, and are only accepted for destinations we are MX for.
Many people do everything on port 25, but it complicates things - you need to set up complicated rules about which destination domains to accept mail for in different situations. Also, you often need to recompile your MTA to support SMTP AUTH, and run SASL authentication daemons, and lots of complex configuration - I gave up because I couldn't make it work.
Also, MTAs should not normally alter message headers, but an initially submitted email may have to have a message ID and/or Date etc. added to it. Making a separate MSA allows that separate program to deal with header tidying, meaning MTAs don't have to worry about doing that in the appropriate situations.
What I've done is to leave my Postfix setup alone, but have written a separate daemon to listen on port 587. This daemon has an inbuilt SASL implementation for SMTP AUTH. It implements the required subset of SMTP. It authenticates the user against a password database, then consults a list of From: addresses that user is allowed to send email with. It accepts an email, checks it is from an allowed From: address for that user, adds any missing headers, adds a Received: header (like the one on this email...), then passes the completed email to the local MTA for relaying onwards (by talking to port 25 locally, although it could just invoke "sendmail").
This now means that wherever my laptop sends email from, the email will always be routed across the Internet from one of my two mail servers, meaning I can set my SPF record to only accept email from my domains from those two machines 🙂
The MSA daemon might also be extended to support PGP-signing all outgoing email, with a per-user private key, and/or adding Hashcash headers and the like...
I'm going to open-source it, but I need to test it in real life for a while, and tidy it up. Right now, it's configured by editing the source, rather than using a proper external user database... and it could be more efficient; right now it spools the incoming email to disk (apart from the headers, which it strips out for tidying), but then slurps it all up again into a big string to use the Python smtplib library to send the email onwards. I'll probably make it invoke sendmail locally to send the email, piped in from the file.
But if anyone wants to be an early adopter, drop me a message...