Postfix, SASL, SMTHAUTH, TLS and Relay

Posted by Joshua Schmidlkofer 01/10/2011 at 17h09

Relaying with Postfix, SASL, Authentication and TLS

Create All The Files!

/etc/postfix/sasl/saslpass

mail.myserver.com relayuser:my password with spaces

/etc/postfix/tls_policy

[mail.myserver.com]:587 encrypt protocols=TLSv1 ciphers=high
[mail.myserver.com]:msa encrypt protocols=TLSv1 ciphers=high
[mail.myserver.com]:submission encrypt protocols=TLSv1 ciphers=high

Set File Permissions on SASL password file

chown root:root /etc/postfix/sasl/saslpass
chmod 600 /etc/postfix/sasl/saslpass

Hash All The Files!

postmap /etc/postfix/sasl/saslpass
postmap /etc/postfix/tls_policy

Configure All The Postfix!

## Since I am using TLS, I will allow plain text and LOGIN (which are disabled by default
postconf -e "smtp_sasl_security_options = "

## Enable SASL for outgoing SMTP traffic.
postconf -e  "smtp_sasl_auth_enable = yes"

### Add the SASL password map
postconf -e " smtp_sasl_password_maps = hash:/etc/postfix/sasl/saslpass"

### Set the TLS Policy map so that my mail server uses TLS w/ the appropriate policies.
postconf -e " smtp_tls_policy_maps = hash:/etc/postfix/tls_policy"

### Add the relayhost as my upstream mail server, note the format, it's important.
postconf -e "relayhost = [mail.myserver.com]:587"

Brief Explanation

I needed to relay from my in-house Linux box, which runs Postfix (on Ubuntu, incidentally), through my colo-hosted mail server. This recipe will work for Comcast, Verizon, Frontier, and Gmail. Those are the only places I have tested it. All of those mailservers have a Submission port (587) which accepts TLS.

This should work for just about any setup.

Props

There are tons of howto's. I own much to Bens Bits, Patrick Koetter, Postfix Documentation, and of course, Google.

inotify

Posted by Joshua Schmidlkofer 03/03/2008 at 12h54

We were messing w/ Postfix and Cyrus IMAPD today. Our prime goal was making a sensical approach to authenticating against a PostgreSQL-based directory. LDAP (OpenLDAP and FDS) based tools sucks for most people. Using native-box-auth is actually quite messy. The mail data cannot be easily associated with the users. You end up with data spread everywhere.

Our basic tenants are:

  • Simple Database Schema - there is no need for a highly relational approach for something so simple.
  • Embedded procedures where possible.
  • Simple front-end.

My esteemed colleague John implemented our thoughts. He ended up with a few PGSQL functions, a couple views and a very straight-forward process.

The actual setup for IMAPD and Postfix is nearly as simple. He will be documenting it at his site later. For now, we wanted to verify the actual behaviour of postfix and imapd during SASL auth in realtime. We turned to inotify. I install pyinotify, and used thier Quick Start script. This ended up leaving me a simple script which monitored the directories which I wanted.

This will not show you files which failed to open. But it does good enough.

import os
from pyinotify import WatchManager, Notifier, ThreadedNotifier, EventsCodes, ProcessEvent

wm = WatchManager()

mask = EventsCodes.INDELETE | EventsCodes.INACCESS | EventsCodes.INOPEN | EventsCodes.INCREATE # watched events

class PTmp(ProcessEvent):

def process_IN_CREATE(self, event):
    print "Create: %s" %  os.path.join(event.path, event.name)

def process_IN_DELETE(self, event):
    print "Remove: %s" %  os.path.join(event.path, event.name)

def process_IN_ACCESS(self, event):
    print "Access: %s" % os.path.join(event.path, event.name)

def process_IN_OPEN(self,event):
    print "Open: %s" % os.path.join(event.path, event.name)

notifier = Notifier(wm, PTmp()) wdd = wm.addwatch('/etc', mask, rec=True) wdd = wm.addwatch('/usr/lib/sasl2', mask, rec=True)

while True: # loop forever

try:
    # process the queue of events as explained above
    notifier.process_events()
    if notifier.check_events():
        # read notified events and enqeue them
        notifier.read_events()
    # you can do some tasks here...
except KeyboardInterrupt:
    # destroy the inotify's instance on this interrupt (stop monitoring)
    notifier.stop()
    break