Simple e-mail config with postfix and Cyrus IMAP

This is a quick’n’dirty tutorial on how to get e-mail working on a basic Linux (Redhat/Fedora/CentOS) installation like the one you may get if you deploy a node in AWS with a predefined AMI (Amazon Machine Image).

The Redhat linux distributions come by default with postfix as MTA (Mail Transport Agent) and Cyrus IMAP as the MDA (Mail Delivery Agent) so this small tutorial is focused on these. Having the packages installed we can go to the configuration files:

  • /etc/postfix/main.cf: the postfix file, where we configure which e-mails we accept and what to do with them.

  • /etc/imapd.conf: settings for Cyrus IMAP – where to look for the mailbox passwords, what authentication mechanisms should be supported for pop/imap.

  • /etc/sasl2/smtpd.conf: for smtp authentication, if an e-mail relay is required (NB: this file can also be located in /usr/lib/sasl2/smtpd.conf).

There is also another file, /etc/cyrus.conf that usually contains the proper defaults upon installation so there may be no need to look into that. It contains settings like the supported protocols (pop3/pop3s/imap/imaps) and the lmtp socket location (the interface between postfix and Cyrus IMAP).

In the postfix configuration file, the following settings are essential:

# cat /etc/postfix.main.cf
...
mailbox_transport = lmtp:unix:/var/lib/imap/socket/lmtp
virtual_transport = $mailbox_transport
virtual_mailbox_domains = /etc/postfix/virtual_domains
virtual_mailbox_maps = hash:/etc/postfix/virtual_maps
...

Explanation: the e-mails for the domains specified in virtual_mailbox_maps are to be, before anything else, accepted for further processing. The final mailbox must be determined by looking into virtual_mailbox_maps (if no such mailbox is determined, some error will be returned to the sender). The effective delivery should be done through the socket specified at mailbox_transport.

Some example file contents:

# cat /etc/postfix/virtual_domains
brainware.ro

# cat /etc/postfix/virtual_maps
john.doe@brainware.ro	brainware.ro/john.doe

The “virtual_maps” file is to be “hashed” with postmap (have a hashmap generated out of it):

# postmap hash:/etc/postfix/virtual_maps

On the Cyrus IMAP side, we must first check that the daemon listens on the proper lmtp socket (by default it should):

# cat /etc/cyrus.conf | grep lmtp
lmtpunix	cmd="lmtpd" listen="/var/lib/imap/socket/lmtp" prefork=1

NB: at this point one may want to disable SELinux in order to allow for the socket communication between postfix and Cyrus IMAP.


Now to the other options; assuming that we want corporate-style addresses (name.surname@domain), the mailbox namespace should be changed so that the separator becomes a different character than “.” (dot). This can be achieved easily:

# cat /etc/imapd.conf
...
unixhierarchysep: 1		#this changes the separator to "/"
...

Other settings to look for in imapd.conf, apart from this one:

# cat /etc/imapd.conf
...
admins: cyrus					#to be able to run cyrus admin
sasl_mech_list: plain login cram-md5 digest-md5 ntlm gssapi		#full house
sasl_pwcheck_method: auxprop	#to look in /etc/sasldb2 for passwords
virtdomains: userid				#to determine the domain from the mailbox name (user@domain)
allowanonymouslogin: no			#security
allowplaintext: yes				#allow older login methods (e.g. testing with telnet)
...

The services should be restarted to activate the new configuration:

# service postfix restart
Shutting down postfix:				[  OK  ]
Starting postfix:					[  OK  ]

# service cyrus-imapd restart
Shutting down cyrus-imapd:			[  OK  ]
Exporting cyrus-imapd databases:	[  OK  ]
Importing cyrus-imapd databases:	[  OK  ]
Starting cyrus-imapd:				[  OK  ]

We are now pretty close to wrapping things up. First let’s check /etc/sasldb2 for the proper access rights (NB: the passwords are not stored with any encryption in there!):

# ls -la /etc/sasldb2 
-rw-r----- 1 cyrus mail 12288 Oct 15 12:34 sasldb2

Preparing for running cyradm (Cyrus IMAP admin) for the first time, we need to set the password for the user “cyrus” – the admin that we have specified in /etc/imapd.conf:

# saslpasswd2 -c "cyrus"
Password:
...

Now we can run cyradm and define our first mailbox and set its password:

# cyradm -u cyrus localhost
IMAP Password:
localhost> cm user/john.doe@brainware.ro
localhost> quit
# saslpasswd2 -c "john.doe@brainware.ro"
Password:
....

Let’s now test the pop3 protocol (plaintext) login with telnet:

# telnet localhost 110
Trying ::1...
Connected to localhost.
Escape character is '^]'.
+OK ...
user john.doe@brainware.ro
+OK Name is a valid mailbox
pass ...
+OK Mailbox locked and ready
list
+OK scan listing follows
...
quit
+OK
Connection closed by foreign host.

Are we good? Mostly yes. We may also want to implement e-mail relaying with smtp authentication. First we need to enable it in postfix:

# cat /etc/postfix/main.cf
...
smtpd_sender_restrictions = permit_mynetworks, permit_sasl_authenticated
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, permit
smtpd_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
...

Then we need to configure the authentication mechanism in /etc/sasl2/smtpd.conf (please also note the alternate location of this file at the top of the document):

# cat /etc/sasl2/smtpd.conf
pwcheck_method: auxprop 		#use /etc/sasldb2
auxprop_plugin: sasldb
mech_list: plain login cram-md5 digest-md5 ntlm gssapi		#full house

After another postfix restart it’s very likely that now we are good. We have a simple e-mail service running with postfix and Cyrus IMAP. Thank you for your read!

Leave a Reply

Your email address will not be published. Required fields are marked *