Install and Configure a Courier MTA Mail Server on Debian
- Last updated: Jul 31, 2026
Introduction
This guide explains how to install and configure a Courier MTA mail server on Debian. It covers SMTP and IMAP services, virtual mail users, aliases, mail relaying, authentication and troubleshooting. We will also secure email communications using TLS encryption and SSL/TLS certificates.
Test Environment
This guide was originally tested with the following software versions:
- Operating system: Debian 7.8 “Wheezy”
- Courier MTA: 0.68
- Courier IMAP: 4.10
Install Courier MTA and IMAP
Install Courier MTA, the secure SMTP and IMAP services, and the Gamin file monitoring utility:
root@host:~# apt-get update
root@host:~# apt-get install gamin courier-mta courier-mta-ssl courier-imap courier-imap-ssl
If you plan to provide POP3 access, install the corresponding Courier packages:
root@host:~# apt-get update
root@host:~# apt-get install courier-pop courier-pop-ssl
Configure Courier Authentication
Configure Courier to use its UserDB authentication backend. Edit the /etc/courier/authdaemonrc file and set the following value:
authmodulelist="authuserdb"
Courier UserDB stores virtual user account information in a database based on the Berkeley DB format.
Create the Virtual Mail User
To avoid creating a separate system account for each mailbox, create a dedicated system user named vmail. This account will own the mail directories for all virtual users.
root@host:~# useradd --system --uid 7200 --home-dir /data/vmail \
--create-home --shell /usr/sbin/nologin vmail
Create the directory that will contain the Courier UserDB source files, then restrict access to the root user:
root@host:~# mkdir -p /etc/courier/userdb
root@host:~# chmod 700 /etc/courier/userdb
Create a Virtual Mail User
Add the virtual mailbox user1@domain1 to the UserDB file for domain1. The uid and gid values must match the identifiers assigned to the vmail account:
root@host:~# userdb -f /etc/courier/userdb/domain1 \
user1@domain1 set \
home=/data/vmail/domain1/user1 \
mail=/data/vmail/domain1/user1/Maildir \
uid=7200 \
gid=7200
Set the Virtual User Password
Generate and store the password hashes used to authenticate the virtual mailbox:
root@host:~# userdbpw -md5 | \
userdb -f /etc/courier/userdb/domain1 \
user1@domain1 set systempw
root@host:~# userdbpw -hmac-sha1 | \
userdb -f /etc/courier/userdb/domain1 \
user1@domain1 set hmac-sha1pw
Create the User Maildir
Create the directory structure that will store the virtual mailboxes. In this example, all mail data is stored under /data/vmail.
root@host:~# mkdir -p /data/vmail/domain1
root@host:~# chown -R vmail:vmail /data/vmail
root@host:~# chmod 750 /data/vmail
root@host:~# chmod 750 /data/vmail/domain1
The resulting directory permissions should be similar to the following:
/data: owned byroot:root, with permissions755/data/vmail: owned byvmail:vmail, with permissions750/data/vmail/domain1: owned byvmail:vmail, with permissions750
Create the mailbox directory for user1@domain1 and initialize its Maildir structure as the vmail user:
root@host:~# install -d -o vmail -g vmail -m 750 /data/vmail/domain1/user1
root@host:~# runuser -u vmail -- maildirmake /data/vmail/domain1/user1/Maildir
The maildirmake command creates the standard cur, new and tmp subdirectories required by the Maildir format.
Build the User Database
Ensure that the Courier UserDB directory and its source files are accessible only to the root user:
root@host:~# chmod 700 /etc/courier/userdb
root@host:~# chmod 600 /etc/courier/userdb/*
Compile the UserDB source files into the database used by Courier:
root@host:~# makeuserdb
Restart the Courier authentication service to apply the changes:
root@host:~# /etc/init.d/courier-authdaemon restart
Test authentication for the virtual mailbox:
root@host:~# authtest user1@domain1
Configure Email Aliases
Courier aliases redirect one email address to another. Edit the alias file associated with the hosted domain, for example /etc/courier/aliases/domain1:
alias@domain1: user1@domain1
Check the alias configuration without rebuilding the database:
root@host:~# makealiases -chk
If no error is reported, compile the alias database:
root@host:~# makealiases
Display the aliases currently stored in the compiled database:
root@host:~# makealiases -dump
Configure Local and Hosted Domains
Define the hostnames that Courier must treat as local. The /etc/courier/locals file should contain the local hostnames of the mail server:
root@host:~# echo "localhost" > /etc/courier/locals
root@host:~# echo "mail.domain1" >> /etc/courier/locals
Next, configure the email domains hosted by the server. Create one file for each hosted domain in the /etc/courier/hosteddomains directory:
root@host:~# mkdir -p /etc/courier/hosteddomains
root@host:~# echo "domain1" > /etc/courier/hosteddomains/domain1
root@host:~# makehosteddomains
Configure Courier SMTP to accept incoming messages addressed to domain1:
root@host:~# mkdir -p /etc/courier/esmtpacceptmailfor.dir
root@host:~# echo "domain1" > /etc/courier/esmtpacceptmailfor.dir/domain1
root@host:~# makeacceptmailfor
Configure an Outgoing SMTP Relay
If the server cannot deliver messages directly to recipient mail servers, Courier can forward all outgoing email through an external SMTP relay, also known as a smarthost. This may be required by your internet service provider or hosting provider.
Edit the /etc/courier/esmtproutes file and define the relay server:
: smtp.domain1
The colon at the beginning of the line applies the route to all destination domains. To use a specific TCP port, append it to the relay hostname:
: smtp.domain1,587
If the SMTP relay requires authentication, add the corresponding credentials to /etc/courier/esmtpauthclient:
smtp.domain1,587 username password
Restrict access to the authentication file because it contains the relay password in plain text:
root@host:~# chown root:root /etc/courier/esmtpauthclient
root@host:~# chmod 600 /etc/courier/esmtpauthclient
Enable SMTP TLS and Authentication
Edit /etc/courier/esmtpd to configure the SMTP service, enable STARTTLS and define the supported authentication mechanisms.
Check or update the following parameters:
COURIERTLS=/usr/bin/couriertls
TLS_CERTFILE=/etc/courier/esmtpd.pem
TLS_TRUSTCERTS=/etc/ssl/certs
TLS_VERIFYPEER=NONE
ESMTPAUTH="PLAIN LOGIN"
ESMTPAUTH_TLS="PLAIN LOGIN"
ESMTPDSTART=YES
The TLS_CERTFILE file must contain the SMTP server certificate and its unencrypted private key. It must not be readable by unprivileged users.
root@host:~# chown root:root /etc/courier/esmtpd.pem
root@host:~# chmod 600 /etc/courier/esmtpd.pem
Require TLS 1.2 or Later
Configure Courier to accept only TLS 1.2 or later. Edit /etc/courier/esmtpd and set:
TLS_PROTOCOL="TLSv1.2+"
Enable IMAP IDLE
The IMAP IDLE extension allows compatible email clients to receive mailbox updates without repeatedly polling the server. For example, clients can be notified when a message is added, removed or marked as read.
Edit /etc/courier/imapd and check that the following parameters are enabled:
IMAP_CAPABILITY="IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE"
IMAP_USELOCKS=1
IMAP_ENHANCEDIDLE=1
Restart the Courier IMAP service to apply the changes:
root@host:~# /etc/init.d/courier-imap restart
See the Courier IMAP documentation for more information.
Set the Maximum Email Size
Courier reads the maximum accepted message size, expressed in bytes, from /etc/courier/sizelimit. The following example sets a limit of 50 MiB:
root@host:~# echo "52428800" > /etc/courier/sizelimit
Configure a Catch-All Address
A catch-all address receives messages sent to addresses that do not otherwise exist in a hosted domain. In this example, all unmatched messages for domain1 are delivered to the mailbox associated with the virtual user alias@domain1.
Ensure that the catch-all mailbox exists, then create its default Courier delivery instruction:
root@host:~# install -d -o vmail -g vmail -m 750 /data/vmail/domain1/alias
root@host:~# runuser -u vmail -- maildirmake /data/vmail/domain1/alias/Maildir
root@host:~# printf '%s\n' "./Maildir" > /data/vmail/domain1/alias/.courier-default
root@host:~# chown vmail:vmail /data/vmail/domain1/alias/.courier-default
root@host:~# chmod 600 /data/vmail/domain1/alias/.courier-default
Configure IMAP over TLS
Courier IMAP can provide encrypted mailbox access through IMAPS on TCP port 993. Edit /etc/courier/imapd-ssl and check the following parameters:
SSLPORT=993
SSLADDRESS=0
SSLPIDFILE=/var/run/courier/imapd-ssl.pid
SSLLOGGEROPTS="-name=imapd-ssl"
IMAPDSSLSTART=YES
IMAPDSTARTTLS=YES
IMAP_TLS_REQUIRED=0
COURIERTLS=/usr/bin/couriertls
TLS_CERTFILE=/etc/courier/imapd.pem
TLS_TRUSTCERTS=/etc/ssl/certs
TLS_VERIFYPEER=NONE
TLS_PROTOCOL="TLSv1.2+"
TLS_CACHEFILE=/var/lib/courier/couriersslcache
TLS_CACHESIZE=524288
MAILDIRPATH=Maildir
Protect the private key contained in the Courier certificate file:
root@host:~# chown root:root /etc/courier/imapd.pem
root@host:~# chmod 600 /etc/courier/imapd.pem
Create a Self-Signed Certificate
A self-signed certificate can be used for testing or for an internal environment where the certificate authority is manually trusted by all mail clients.
root@host:~# openssl req -x509 -newkey rsa:4096 -sha256 -nodes \
-days 3650 \
-keyout server.key \
-out server.crt \
-subj "/CN=mail.domain1" \
-addext "subjectAltName=DNS:mail.domain1"
Create the PEM files expected by Courier for the SMTP and IMAP services:
root@host:~# cat server.key server.crt > /etc/courier/esmtpd.pem
root@host:~# cat server.key server.crt > /etc/courier/imapd.pem
root@host:~# chown root:root /etc/courier/esmtpd.pem /etc/courier/imapd.pem
root@host:~# chmod 600 /etc/courier/esmtpd.pem /etc/courier/imapd.pem
Use Let’s Encrypt Certificates
For a publicly accessible mail server, use a certificate issued for the server hostname. Courier expects the private key and the complete certificate chain in a single PEM file.
root@host:~# cat \
/etc/letsencrypt/live/mail.domain1/privkey.pem \
/etc/letsencrypt/live/mail.domain1/fullchain.pem \
> /etc/courier/esmtpd.pem
root@host:~# cp /etc/courier/esmtpd.pem /etc/courier/imapd.pem
root@host:~# chown root:root /etc/courier/esmtpd.pem /etc/courier/imapd.pem
root@host:~# chmod 600 /etc/courier/esmtpd.pem /etc/courier/imapd.pem
Restart the Courier SMTP and IMAP TLS services:
root@host:~# /etc/init.d/courier-mta-ssl restart
root@host:~# /etc/init.d/courier-imap-ssl restart
Test and Troubleshoot Courier MTA
Send a Test Email from the Server
Send a test message through the local Courier MTA using the sendmail command:
root@host:~# printf 'To: user2@domain2\nFrom: user1@domain1\nSubject: Courier test\n\nThis is a test message.\n' | /usr/sbin/sendmail -t
The -t option instructs sendmail to read the recipient addresses from the message headers.
Test Authentication Locally
Use authtest to verify that Courier can authenticate a virtual mailbox:
root@host:~# authtest -s imap user1@domain1 password
Test POP3 and IMAP from a Client
Test POP3 with STARTTLS
Connect to the POP3 service on TCP port 110 and upgrade the connection to TLS:
user@client:~$ openssl s_client \
-connect mail.domain1:110 \
-starttls pop3 \
-servername mail.domain1 \
-crlf
Once the TLS connection is established, enter:
USER user1@domain1
PASS password
STAT
QUIT
Test POP3 over Implicit TLS
Test the encrypted POP3 service on TCP port 995:
user@client:~$ openssl s_client \
-connect mail.domain1:995 \
-servername mail.domain1 \
-crlf
Then enter:
USER user1@domain1
PASS password
STAT
QUIT
Test IMAP with STARTTLS
Connect to the IMAP service on TCP port 143 and negotiate STARTTLS:
user@client:~$ openssl s_client \
-connect mail.domain1:143 \
-starttls imap \
-servername mail.domain1 \
-crlf
Once connected, authenticate and display the mailbox status:
a LOGIN user1@domain1 password
a EXAMINE INBOX
a LOGOUT
Test IMAP over Implicit TLS
Test the encrypted IMAP service on TCP port 993:
user@client:~$ openssl s_client \
-connect mail.domain1:993 \
-servername mail.domain1 \
-crlf
Then enter:
a LOGIN user1@domain1 password
a EXAMINE INBOX
a LOGOUT
Verify the TLS Certificate
Add -verify_return_error to make the test fail if OpenSSL cannot validate the certificate chain:
user@client:~$ openssl s_client \
-connect mail.domain1:993 \
-servername mail.domain1 \
-verify_hostname mail.domain1 \
-verify_return_error
A successful verification should end with:
Verify return code: 0 (ok)
Test the SMTP Service
The following examples use S: for responses returned by the server and C: for commands entered by the client.
Test SMTP without Authentication
Connect to the SMTP service on TCP port 25 and negotiate a TLS connection using STARTTLS:
user@client:~$ openssl s_client \
-connect mail.domain1:25 \
-starttls smtp \
-servername mail.domain1 \
-crlf
Once the connection is established, enter the following SMTP commands:
S: 220 mail.domain1 ESMTP Courier
C: EHLO client.domain1
S: 250-mail.domain1
S: 250-STARTTLS
S: 250-SIZE 52428800
S: 250 HELP
C: MAIL FROM:<test@sender.example>
S: 250 Ok
C: RCPT TO:<user1@domain1>
S: 250 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: test@sender.example
C: To: user1@domain1
C: Subject: Courier SMTP test
C:
C: This is a test message.
C: .
S: 250 Ok
C: QUIT
S: 221 Bye
Test SMTP with Authentication
To test authenticated SMTP submission, connect to the server on TCP port 587 using STARTTLS. The example below uses the AUTH LOGIN authentication mechanism.
First, encode the username and password in Base64. Use printf to avoid adding a newline character:
user@client:~$ printf '%s' 'user1@domain1' | base64
dXNlcjFAZG9tYWluMQ==
user@client:~$ printf '%s' 'P@ssw0rd' | base64
UEBzc3cwcmQ=
Connect to the SMTP submission service and negotiate STARTTLS:
user@client:~$ openssl s_client \
-connect mail.domain1:587 \
-starttls smtp \
-servername mail.domain1 \
-crlf
Once the TLS connection is established, enter the following SMTP commands:
S: 220 mail.domain1 ESMTP Courier
C: EHLO client.domain1
S: 250-mail.domain1
S: 250-AUTH LOGIN PLAIN
S: 250 SIZE 52428800
C: AUTH LOGIN
S: 334 VXNlcm5hbWU6
C: dXNlcjFAZG9tYWluMQ==
S: 334 UGFzc3dvcmQ6
C: UEBzc3cwcmQ=
S: 235 Authentication successful
C: MAIL FROM:<user1@domain1>
S: 250 Ok
C: RCPT TO:<recipient@example.net>
S: 250 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: user1@domain1
C: To: recipient@example.net
C: Subject: Courier authenticated SMTP test
C:
C: This is a test message sent through authenticated SMTP.
C: .
S: 250 Ok
C: QUIT
S: 221 Bye
Authorize SMTP Relay for Trusted Clients
By default, Courier should only accept messages addressed to domains hosted by the server. To allow a trusted device or application to relay messages to external domains without SMTP authentication, add its IP address to the Courier SMTP access rules.
Create or edit a file in /etc/courier/smtpaccess, for example /etc/courier/smtpaccess/trusted-clients:
root@host:~# nano /etc/courier/smtpaccess/trusted-clients
Add the trusted client IP address followed by a tab character and the allow,RELAYCLIENT rule:
192.168.1.50<TAB>allow,RELAYCLIENT
Rebuild the Courier SMTP access database:
root@host:~# makesmtpaccess
Restart the Courier SMTP services to apply the new rule:
root@host:~# /etc/init.d/courier-mta restart
root@host:~# /etc/init.d/courier-mta-ssl restart
Archive Maildir Messages by Date
The following example moves messages whose Date header contains the year 2012 to the .Sent.2012 Maildir folder.
First, create the destination Maildir folder if it does not already exist:
root@host:~# runuser -u vmail -- maildirmake /data/vmail/domain1/user1/Maildir/.Sent.2012
Move to the cur directory containing the messages to archive:
root@host:~# cd /data/vmail/domain1/user1/Maildir/.Sent/cur
Before moving any messages, display the files whose Date header contains 2012:
root@host:~# find . -maxdepth 1 -type f -print0 | \
while IFS= read -r -d '' message; do
if grep -qm1 '^Date:.*2012' "$message"; then
printf '%s\n' "$message"
fi
done
After checking the results, move the matching messages to the destination folder:
root@host:~# find . -maxdepth 1 -type f -print0 | \
while IFS= read -r -d '' message; do
if grep -qm1 '^Date:.*2012' "$message"; then
mv -- "$message" ../../.Sent.2012/cur/
printf 'Moved: %s\n' "$message"
fi
done
Common Courier MTA Errors
Corrupted or Malformed MIME Message
Courier may replace an email with a warning when it detects malformed MIME content, an incorrectly encoded attachment or invalid message formatting.
The recipient may receive a message similar to the following:
CORRUPTED MESSAGE
This is the Courier Mail Server 0.68 on mailserver.
I received the following message for delivery to your address. This message
contains several internal formatting errors.
This message contains improperly-formatted binary content, or attachment.
This error is commonly caused by a mail client that generated an invalid MIME message, an incorrectly encoded attachment or, in some cases, deliberately malformed content.
To allow Courier to accept malformed MIME messages, create or edit the /etc/courier/bofh file and add:
opt BOFHBADMIME=accept
Restart Courier MTA to apply the change:
root@host:~# /etc/init.d/courier-mta restart
Accept Uppercase Characters in Email Addresses
By default, Courier may reject local email addresses containing uppercase characters. Create the /etc/courier/locallowercase file to make local address handling case-insensitive:
root@host:~# touch /etc/courier/locallowercase
root@host:~# /etc/init.d/courier-mta restart
Clear Addresses Blocked by Backscatter Protection
If Courier encounters a local delivery failure, for example because the Maildir does not exist, the mailbox has incorrect ownership or a mail delivery command fails, it may temporarily stop accepting messages for the affected recipient.
This mechanism reduces the risk of generating repeated non-delivery reports, also known as backscatter. Errors such as the following may appear in the logs or be returned to the sending server:
456 Address temporarily unavailable
502 ESMTP command error
Correct the underlying mailbox or delivery problem before clearing the blocked address.
List all addresses currently blocked by Courier’s backscatter protection:
root@host:~# courier show all
Clear a specific address:
root@host:~# courier clear user1@domain1
Clear all blocked addresses:
root@host:~# courier clear all
“No Route to Host” Error
courieresmtp: id=00000000008002CF.0000000050C99F63.00003ECE,from=<>,addr=<user@example.net> No route to host
This error indicates that Courier cannot establish a network connection to the destination SMTP server. Possible causes include an incorrect network route, a firewall rule, a DNS resolution problem, an unavailable remote server or blocked outbound SMTP traffic.
First, verify network connectivity and DNS resolution:
root@host:~# getent hosts example.net
root@host:~# ip route
root@host:~# nc -vz mail.example.net 25
If direct SMTP delivery is blocked by your internet service provider, configure Courier to forward outgoing messages through an authorized SMTP relay. Edit /etc/courier/esmtproutes:
: smtp.provider.example,587
Restart Courier MTA after changing the route:
root@host:~# /etc/init.d/courier-mta restart
Maximum IMAP Connection Limit Reached
The following error indicates that Courier IMAP has reached either the global connection limit or the maximum number of simultaneous connections allowed for a single client IP address:
Maximum connection limit reached for ::ffff:192.168.X.X
Edit /etc/courier/imapd and review the following parameters:
MAXDAEMONS=300
MAXPERIP=60
MAXDAEMONS defines the maximum number of simultaneous IMAP processes, while MAXPERIP limits the number of concurrent connections from a single IP address.
Restart the Courier IMAP services after changing the limits:
root@host:~# /etc/init.d/courier-imap restart
root@host:~# /etc/init.d/courier-imap-ssl restart
“513 Relaying Denied” Error
This error occurs when Courier refuses to relay a message. If the recipient belongs to a domain hosted by the server, ensure that the domain is listed in the accepted mail domains configuration:
root@host:~# mkdir -p /etc/courier/esmtpacceptmailfor.dir
root@host:~# echo "domain1" > /etc/courier/esmtpacceptmailfor.dir/domain1
root@host:~# makeacceptmailfor
Restart Courier MTA to apply the updated configuration:
root@host:~# /etc/init.d/courier-mta restart
Slow SMTP Connections or Message Delivery
Slow SMTP connections may be caused by reverse DNS lookups or Ident queries performed when a client connects. To disable these checks, edit /etc/courier/esmtpd:
TCPDOPTS="-nodnslookup -noidentlookup -stderrlogger=/usr/sbin/courierlogger"
Restart Courier MTA after modifying the configuration:
root@host:~# /etc/init.d/courier-mta restart
See the Courier MTA documentation for additional information about SMTP connection delays.
Useful Courier MTA Commands
- Display the current mail queue:
root@host:~# mailq
- Display the files stored in the Courier mail spool:
root@host:~# ls -Rhl /var/lib/courier/msgs/
- Remove a specific message from the queue:
root@host:~# cancelmsg message-id
- Remove all messages from the queue:
root@host:~# mailq | awk '/^[[:space:]]*[0-9A-F]+\./ { print $2 }' | \
while IFS= read -r message_id; do
cancelmsg "$message_id"
done