Mac OS X Snow Leopard Server: Configuring outgoing SMTP authentication for postfix

More and more ISPs require customers to use the ISP’s own SMTP server for sending mail (to effectively block spam coming from hijacked customer workstations). Or you simply might want to send outgoing mail using your own SMTP mail server somewhere in the Internet, which  should only accept encrypted, authenticated connection requests.

If you’re lucky, you can configure postfix on your Snow Leopard Server (and later) using the supplied ‘Server Admin’ GUI tool and enter your authentication credentials and the name of your (or your ISP’s) SMTP server there. This is explained in the following Youtube video: Using Your ISPs Mail Server in Snow Leopard Server.

In my case, this wasn’t sufficient, i.e. didn’t work and hence I had to use the CLI tool instead (which appears to be buggy, see later). The configuration of outgoing SMTP authentication for postfix on Mac OS X Snow Leopard Server is analogous to my quite old post about configuring SMTP auth for postfix on Linux, only the commands slightly differ.

Here are the commands I had to use:

# serveradmin settings mail:postfix:smtp_sasl_mechanism_filter = "plain"

mail:postfix:smtp_sasl_mechanism_filter = “plain”

# serveradmin settings mail:postfix:smtp_sasl_security_options = "noanonymous"

mail:postfix:smtp_sasl_security_options = “noanonymous”

# serveradmin settings mail:postfix:smtp_use_tls = "yes"

mail:postfix:smtp_use_tls = “1”

 

The last command reveals a bug in the ‘serveradmin’ tool which will prevent postfix from working correctly as the value is set to “1” instead of “yes”! As a workaround, you need to manually set the value to “yes” in /etc/postfix/main.cf:

 

# vi /etc/postfix/main.cf

smtp_use_tls = yes

 

# vi /etc/postfix/sasl/passwd

# cat /etc/postfix/sasl/passwd

smtp.mydomain.com login:password

# postmap hash:/etc/postfix/sasl/passwd

# serveradmin stop mail

mail:state = “STOPPED”

# serveradmin start mail

mail:state = “RUNNING”

Done that, you can test the new settings by composing and sending a message using the ‘mail’ command:

# mail -s "a test message" myaddress@mydomain.com

(enter the body text and finish editing the message by entering a dot on an empty line)

Check the mail queue with

# mailq

Requeue messages that couldn’t be delivered using

# postqueue -f

[Edit 20130401: Fixed some typos, clarified the phrasing, anonymized data]

Gentoo: Mailman 2.1.11 incompatibility with Python 2.6

Mailman 2.1.11 (or earlier) isn’t compatible to Python 2.6. So if you upgrade your box to Python 2.6 without upgrading to Mailman 2.1.12 at the same time, you’ll run into troubles. And if you’re unlucky (e.g. when running some low-volume mailing lists), you might not even notice it.

One sign of such troubles is that messages sent to your Mailman mailing lists aren’t processed anymore. They simply seem to get “swallowed” by your Mailman server: Messages don’t reach the list, don’t get forwarded to subscribers and there’s no bounce or failure notice. For low-traffic lists, this might go unnoticed for several days or even weeks.

Another sign (that can easily slip through under certain, quite common circumstances) is that as long as you’re running Mailman 2.1.11 with Python 2.6, cron will, every 5 minutes,  send an error message to mailman@myhost.com with a subject similar to

Cron <mailman@myhost> /usr/bin/python -S /usr/lib64/mailman/cron/gate_news

and a content like

/usr/lib64/mailman/Mailman/Utils.py:32: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
import sha
Traceback (most recent call last):
File “/usr/lib64/mailman/cron/gate_news”, line 44, in <module>
from Mailman import MailList
File “/usr/lib64/mailman/Mailman/MailList.py”, line 51, in <module>
from Mailman.Archiver import Archiver
File “/usr/lib64/mailman/Mailman/Archiver/__init__.py”, line 17, in <module>
from Archiver import *
File “/usr/lib64/mailman/Mailman/Archiver/Archiver.py”, line 32, in <module>
from Mailman import Mailbox
File “/usr/lib64/mailman/Mailman/Mailbox.py”, line 21, in <module>
import mailbox
File “/usr/lib64/python2.6/mailbox.py”, line 19, in <module>
import email.message
ImportError: No module named message

That by itself wouldn’t be a big problem and probably get noticed quickly if you forwarded mailman@yourhost.com to your admin’s e-mail address. The problem arises if you happen to host a mailing list named “mailman” (which is often set up as a mailing list for testing and debugging). In that (not uncommon) case, all these cron error messages are forwarded to the “mailman” mailing list.  This makes about 288 messages per day that are queued in /var/lib/mailman/qfiles/in and won’t be delivered (due to the compatibility problem with Python 2.6).

Once you upgrade to Mailman 2.1.12 (and restart /etc/init.d/mailman), all these messages in /var/lib/mailman/qfiles/in will be queued by your MTA (e.g. postfix). This may seem like a strange loop problem in Mailman (or your MTA configuration), which is quite irritating at first.

Here’s how to solve the problem (you may need to adjust these steps to your settings/system paths):

1) Temporarily stop the Mailman service

/etc/init.d/mailman stop

2) Delete all the queued messages to/for mailman-owner@myhost.mydomain.com in your MTA’s mail queue. For postfix as MTA, the following script may be helpful: mailq by Dan Mick.

3) Delete all the cron-generated error messages in /var/lib/mailman/qfiles/in.

In order to determine these error messages, use Mailman’s show_qfiles command to view the message content, e.g.

/usr/lib64/mailman/bin/show_qfiles /var/lib/mailman/qfiles/in/longnumber.longnumber.pck

The best way to identify these messages is by filtering them according to their file size. Usually they have sizes around 1600 bytes. E.g. for a file size of 1635 bytes, try sth similar to:

cd /var/lib/mailman/qfiles/in

find ./ -size 1635c -exec rm {} \;

4) Once you’ve deleted all these cron error messages in Mailman’s in-queue, you can restart Mailman (/etc/init.d/mailman start). Mailman will then start delivering the remaining valid files in its in-queue. Your MTA/postfix queue looks normal again (i.e. there’s no more overflowing)!

5) Finally, you need to manually “discard all messages marked Defer” for the ‘mailman’ mailing list using the web admin interface (usually on https://myhost.mydomain.com/mailman/admindb/mailman or similar). Before discarding these messages, make sure you don’t discard any valid messages.

That’s it!

Thanks to Mark Sapiro AKA msapiro from #mailman @ irc.freenode.net for very useful hints and help!

P.S. Some other helpful resources in case of Mailman problems:

How to find running Mailman instances (qrunners)

How to integrate postfix and Mailman

Gentoo: Greylisting for Postfix using Postgrey

Finally, I’ve had to enable greylisting for this domain due to ever increasing levels of spam. Fortunately, setting it up is very easy. For Gentoo and Postfix, here’s a nice walkthrough:

postfix greylisting on gentoo (postgrey) | andreas d.’s.

Let’s hope that this, in conjunction with other anti-spam measures, will do it for a while.

Non-spammers shouldn’t experience any problems due to this change, but if you do, please contact me using Skype (mettlerd), phone or SMS.

Setting up Procmail and Postfix with maildir for mobile usage

When I’m on the road, I can check my private and business e-mail using my very handy Nokia e61i smartphone (which I like a lot, apart from its rather unstable web browser). However, as I’ve never been far away from a computer for a long time so far, I’ve only used to check mail that was delivered to my inbox, and not to any of its about 200 subfolders (I once tried to subscribe to all folders – the mail client of the e61i simply crashed ;). Now, I figured I’d need to do something about this in order to not miss any of the mails that are automatically moved to a subfolder by the server-side procmail mail filter.

The solution: Simply create a new procmail rule that copies (that’s what the c stands for) any incoming message to a special folder (I named it “mobile”; note that my postfix uses the maildir format to store messages):

:0 c
.mobile/

Preferably, this rule should be placed after the spam filtering rules (you don’t want to pay for spam on your mobile, do you? ;) and before the normal procmail mail filter rules (which move every incoming mail to the appropriate subfolder). You can also use a dedicated rules file for every group of similar rules. For example, I include the files spam.rc, mobile.rc, lists.rc (with their according rules) in the main .procmailrc config file.

Now every mail that wasn’t filtered by the spam filter gets copied to the “mobile” subfolder of your inbox prior to getting moved to the appropriate subfolder (by the rules in lists.rc).

On my e61i, I hence only need to subscribe to the “mobile” subfolder in order to catch all incoming messages. As you can’t unsubscribe from the inbox subfolder itself, you should set the maximum number of caught new inbox mails to 1 (which is the minimum) in order to avoid fetching things twice. You can further configure that only headers are fetched to minimize the amount of data[1] that is automatically downloaded with every mail check (also: switch off polling if you don’t need it).

Note that another advantage of this solution is that you won’t tamper with any of the original messages (that are either in your inbox or in any of its subfolders). Some might call this a disadvantage though.

That’s it, have fun! :)

[1] I pay 0.10 CHF per 20 KB, i.e. 5 CHF (5 USD) per MB (which is incredibly expensive as I currently don’t have any flat rate data plan -> please don’t send me a mail bomb just for fun, else I’ll have to write a more sophisticated procmail rule that only copies messages < 100 KB to the mobile folder)

Setting up postfix for virtual mail hosts

After setting up name-based virtual web hosting for Apache, I’ve just set up virtual mail hosting for my new company, Printscreen GmbH, using postfix – and it was amazingly simple! :) For some basic virtual mail hosting using normal UNIX/Linux user accounts, all you need is a plain-text file (‘/etc/postfix/virtual’) that maps virtual mail addresses to the actual user accounts and two additional lines in main.cf:

/etc/postfix/virtual:
postmaster@example.com postmaster
# Uncomment entry below to implement a catch-all address
# @example.com jim

/etc/postfix/main.cf:
virtual_alias_domains = example.com
virtual_alias_maps = hash:/etc/postfix/virtual

Then just execute

# postmap /etc/postfix/virtual && /etc/init.d/postfix reload

Voilà!

The nice postfix readme file for this and some more complicated virtual mail hosting configurations:

http://www.postfix.org/VIRTUAL_README.html

Another, possibly helpful howto (search):

http://www.freebsddiary.org/postfix.php

For setups using a MySQL database as a backend for storing the mappings, see Google. I currently don’t need this and hence don’t like to introduce any unnecessary MySQL dependency to my postfix server – remember the KISS principle ;)