Installing Courier on Gentoo

On my previous system, I had used qmail (netqmail actually, which is qmail with some patches). Qmail is moderately difficult to set up and in its 3 years lifespan on my system, it has broken down on several occasions. That’s why I decided to use another mail server when I moved my domains to a different system.

Because the Courier IMAP server has never let me down before, I decided to give the Courier Mail Server a chance. Lots of people are using Courier IMAP to access their mail but Exim, Postfix or Qmail to accept incoming emails. Even the Gentoo Wiki contains various HowTos for these combinations, but not a single one for a homogenous Courier setup. After trying out Courier, I don’t see why, so this is my attempt to rectify the situation (and to remember what needs to be done for the next time I’m moving my domains to another system!)

1. Install Courier

To install Courier, simply emerge the Courier package on your system:

emerge courier

You can enable the ‘web‘ USE flag for Courier if you want to use its web adminstration frontend, but it’s written in Perl and doesn’t offer anything you couldn’t change in Courier’s configuration files.

After Courier has been installed, its configuration in /etc/courier needs to be modified to suit your system.

To check your mailbox, you’ll want to enable one of the mail access services through their respective configuration files, either pop3d / pop3d-ssl if you plan on using POP3 or imapd / imapd-ssl if you plan on using IMAP. Look for a statement saying <servicename>START= and set it to yet to activate one of the mail access services.

Personally, I’m using a VPN to connect to my server so I don’t have to publicly open any ports other people shouldn’t be concerned with. I enabled imapd (without SSL because OpenVPN already has SSL encryption) and made it listen only on my server’s VPN IP:

# file: /etc/courier/imapd

# Example from my own server. You don't need a VPN, of course. If you decide
# to make your mail access ports publicly accessible, I'd recommend the usage
# if imapd-ssl or pop3d-ssl.

# IP address the IMAP server will be listening on
ADDRESS=4.3.2.1 # My server's VPN IP

# Default port for unencrypted IMAP
PORT=143

# Enable the IMAP service
IMAPDSTART=YES

Courier contains its own authentication system, authlib, which you need to set up before you can access your mail via POP3 or IMAP. To do this, edit /etc/courier/authlib/authdaemonrc.

I want to use normal user accounts on my system for authentication, so I enabled the authpam module, which uses PAM, which will by default accept normal system users:

# Authentication modules authdaemond will query
authmodulelist="authpam "

You can also keep users in a MySQL database for a virtual email setup or adjust the PAM configuration (/etc/pam.d/pop or /etc/pam.d/imap) to authenticate users against other services.

2. Create a Mailbox

You probably already have your own user account (no, root is not the right account to receive emails with :D), but if not, here’s how you create one.

your system already should have a group “users” (defined in /etc/group. If not, you can create one like this:

groupadd users

Add a new user with the useradd command:

useradd \
  --comment "Myself" \
  --home-dir /home/yourusername \
  --gid users \
  --create-home \
  --no-user-group \
  --shell /bin/bash \
  yourusername

Replace yourusername with the actual login you want to use. It’s established practice to use only lowercase characters for unix user names.

Next, set a password for your new user account:

passwd yourusername

To create a mailbox, you can impersonate your user in order to make sure the mailbox is readable and writable by that user:

su yourusername
cd ~
maildirmake Maildir
exit

I wasn’t sure how the mailbox should actually be called, but using Maildir with an uppercase ‘M‘ seemed to be the agreed standard from the references I could find through google. Courier does indeed find the thusly named directory.

3. Enable Public SMTP

Traditionally, a single SMTP server was used both to accept incoming emails from other servers as well as accept new emails submitted by a user. To avoid becoming an open relay – an email server where anyone can submit new email, modern SMTP servers only accept email destined for the local system and decline to forward emails to other servers unless the client submitting the message authenticates itself with a login and password.

To provide additional security, RFC-2476 recommended the use of a second SMTP server on port 587 that is only used for submitting new email. This also makes things simpler to set up. For example, the public SMTP server running on port 25 can now be configured to never relay messages and to refuse authentication outright (no dictionary attacks on weak passwords possible anymore).

Courier supports this. First, you’ll want to enable Courier’s public SMTP server by editing /etc/courier/emstpd so you can receive incoming emails and test whether they arrive in your mailbox. Make sure you have at least these options set:

# file: /etc/courier/esmtpd

# IP address the public SMTP server will be listening on
ADDRESS=1.2.3.4 # Your server's public IP

# Port at which the public SMTP server can be reached
PORT=smtp

# Enable the public SMTP server
ESMTPDSTART=YES

Courier uses access lists to control who may submit new emails. The default access list (stored in /etc/courier/smtpaccess/default) only allows relaying for 127.0.0.1. For the public SMTP server, this is just right, as it completely prevents any outsider from using the SMTP server as a relay.

If you want to modify the access list, you can find a list of possible commands here in the makesmtpaccess documentation. After any change, you need to recompile Courier’s smtpaccess.dat by running:

makesmtpaccess

4. Test Public SMTP

Let’s start courier now!

/etc/init.d/courier start

On Windows, you can either use the telnet utility provided with earlier versions of the operating system or the excellent PuTTY, a single-file, no-install telnet and SSH client.

Screenshot of PuTTY manually submitting an email to an SMTP server via telnet

This is how it works: connect to your server’s public SMTP port (which is port 25) and wait for the server’s greeting line. Then follow this script:

#Server: 220 server.com ESMTP
 Client: HELO notgmail.com
#Server: 250 notgmail.com ok.
 Client: MAIL to: <yourusername@server.com>
#Server: 250 Ok
 Client: RCPT from: <me@notgmail.com>
#Server: 250 Ok
 Client: DATA
#Server: 250 Transmit message, terminate with a single line containing '.'
 Client: From: Me <me@notgmail.com>
 Client: To: Me Too <yourusername@server.com>
 Client: Subject: Test
 Client:
 Client: This is a test message. Make sure this text is separated from the
 Client: headers with an empty line.
 Client: .
#Server: 250 Ok. Message accepted.
 Client: QUIT
#Server: 221 Bye.

You could also send yourself an email from another email provider such as gmail, but submitting an email manually allows for easier debugging (for example, if your server’s firewall blocks port 25, this will be pretty obvious).

Once the delivery succeeded and you can see the test message in your account with IMAP or POP3, shut down courier again:

/etc/init.d/courier stop

5. Enable Private SMTP

As explained in step 3, courier has two SMTP servers, one for receiving incoming emails from other servers and one for you to submit new emails (running on port 587 as per RFC-2476). The public SMTP server could be configured through /etc/courier/esmtpd, the private SMTP now needs to be set up by editing /etc/courier/esmtpd-msa (msa stands for mail submission agent, referring to software such as Mozilla Thunderbird or Evolution).

# file: /etc/courier/esmtpd-msa

# Require authentication to submit new emails. This is especially important if
# you open port 587 on your public IP (I opened it only to localhost and my VPN)
AUTH_REQUIRED=1

# Access List controlling who can access this smtp server
ACCESSFILE=${sysconfdir}/smtpaccess-msa # '-msa' appended!

# Whether to enable the ESMTPD-MSA service
ESMTPDSTART=YES

# Authentication methods allowed for unencrypted connections
# (copied from /etc/courier/esmtpd)
#
# If logging in exclusively via VPN (which is already SSL-encrypted)
#ESMTPAUTH="PLAIN CRAM-MD5 CRAM-SHA1 CRAM-SHA256"
#
# If logging in without a VPN, it's good to disable cleartext passwords
ESMTPAUTH="CRAM-MD5 CRAM-SHA1 CRAM-SHA256"

# Authentication methods allowed for SSL-encrypted connections
ESMTPAUTH_TLS="PLAIN LOGIN CRAM-MD5"

As you can see, a different access list (smtpaccess-msa instead of smtpaccess) is used for the MSA SMTP port.

To create this access list, do the following:

cp -rp /etc/courier/smtpaccess /etc/courier/smtpaccess-msa
nano /etc/courier/smtpaccess-msa/default

For you convenience, here’s the link to the makesmtpaccess documentation that explains the commands to Courier’s SMTP access lists again. This special access list for the MSA should only allow access to those networks your email clients connect from (which may include the internet). The Courier docs state:

NOTE: Authenticated SMTP is preferred over defining explicit IP address ranges. When combined with SSL, authenticated SMTP enables relaying privileges to any sender that securely provides a valid login/password, from any IP address, instead of only a small range of preauthorized IP addresses.

If you changed anything, you need to recompile the smtpaccess-msa file by running

makesmtpaccess-msa

6. Test Private SMTP

If you start Courier now, both the esmtp and the esmtp-msa daemon should be starting. You can repeat the telnet / PuTTY check with port 587 here to make sure esmtpd-msa is reachable, though the authentication is a bit complicated, so I suggest just doing a HELO and then using your favorite email client to send a test email.

In case your login is not accepted, check your /var/log/messages. You can also enable authentication debugging in /etc/courier/authlib/authdaemonrc by setting the DEBUG_LOGIN:

# Verbosity level for login messages
DEBUG_LOGIN=2

Then watch your /var/log/messages as you attempt to send the email. Hint: if pam_authenticate fails with result 7, like this:

authdaemond: authpam: trying this module
authdaemond: authpam: sysusername=yourusername, sysuserid=<null>,
                      sysgroupid=1006, homedir=/home/yourusername,
                      address=yourusername, fullname=Myself,
                      maildir=<null>, quota=<null>,
                      options=<null>
authdaemond: authpam: clearpasswd=<null>, passwd=x
authdaemond: pam_service=esmtp, pam_username=yourusername
authdaemond: pam_authenticate failed, result 7
authdaemond: authpam: REJECT - try next module
authdaemond: FAIL, all modules rejected

…then your PAM probably doesn’t know the service. I had this issue and after checking the contents of /etc/pam.d, it was clear why I could log in with imapd but not with esmtpd: there were no authentication rules defined for esmtpd. I fixed it by cloning the imap authentication rules:

cp -p /etc/pam.d/imap /etc/pam.d/esmtp

For other problems, I recommend the courier-users mailing list and the always helpful Gentoo Forums ;-)

Remember to set your…

# Debug level for login messages
DEBUG_LOGIN=0

…once authentication is working, otherwise, passwords will be written into /var/log/messages as courier’s configuration file prominently states.

That’s it! You should have a working and secure mail server by now :)