Simple Python script as SMTP server for outgoing e-mails?

Chris Angelico rosuav at
Mon Jul 22 18:12:22 CEST 2013

On Tue, Jul 23, 2013 at 12:21 AM, Michael Torrie <torriem at> wrote:
> My mail server did a number of things:
> 1. ensure IP address of sending server has a reverse name (domain didn't
> particularly matter)
> 2. ensure the HELO address in SMTP matches IP address of sending server
> 3. check sender IP address against spam blacklists, which includes
> netblocks of home ISPs, some entire countries, flagged subnets
> 4. greylist sender IP if the recipient requested it.  First connection
> always fails with a nonfatal server error, next connection must wait at
> least 5 minutes.  If a reconnection happened too quickly, the IP was
> temporarily black listed.  After success, IP address is whitelisted for
> a time.  A commandline MTA will not be able to get through greylisting;
> only a mail server with queuing could.  Spambots tend to give up on the
> first error, even now. Cheaper targets I guess.
> 5. spamassassin checked SPF (DNS) and domainkeys (message itself) and
> weighted the spam factor accordingly
> I think there were other basic rules that sendmail applied to the
> sender, but I can't remember all of what they are.  This is well and
> truly off topic now for the python list, though.

And yet off-topic does happen... For what it's worth, here's how my
server is set up:
1. A variety of protocol-level checks. If you don't say HELO, for
instance, you get rejected. Surprisingly, these simple checks actually
keep out a lot of spam - but I've yet to see any legiit mail blocked
by them. (Not that I keep logs of these any more. I stopped watching
after it looked clean for a while.) And if legit mail is rejected,
it'll be resent or bounced by the sending MTA anyway.
2. SPF checks on the MAIL FROM:<> address. Again, if legit mail gets
rejected (which would be the fault of the sending domain owner), the
server at the previous hop will deal with it. Only hard failures get
thrown out; anything else just gets marked (which we usually ignore)
and delivered as normal, not even spam-scored.
3. Bayesian spam filter, set very conservatively so we get false
negatives but (almost) no false positives.

Any spam that gets through these three checks gets delivered, and then
the users will drop it in their junk folder. Every week I do a
train-and-wipe run across all junk folders, which logs spam counts
from our primary mailboxes. Last week's run was 228 spam across the
six logged accounts (some of those accounts collect from many
addresses), or an average of five false negatives per account per day,
and false positives are almost completely unheard-of. Considering how
much spam assaults the outside of my fortress's walls, that's a fairly
good ratio, I think. SPF for the win.


More information about the Python-list mailing list