Setting up an SMTP server with Exim is less about installing software and more about configuring a sophisticated mail routing engine that can be surprisingly simple or incredibly complex, depending on your needs.

Let’s get Exim installed and ready to send mail. We’ll focus on a basic setup that allows local mail delivery and sending mail out to the internet.

First, the installation. On a Debian/Ubuntu system, it’s straightforward:

sudo apt update
sudo apt install exim4 mailutils

During installation, you’ll be prompted with a configuration wizard. For this basic setup, choose "smarthost; sent mail directly, from this machine to any host" if you want Exim to send mail directly. If you have an existing mail relay (like a Gmail account or another server), choose "smarthost; sent mail directly, from this machine to any host" and then specify your smarthost later. For now, let’s assume direct sending.

The core of Exim’s configuration lives in /etc/exim4/exim4.conf.template. This is a template file, and the actual configuration is generated from it. We’ll be editing this template.

The most important file for defining how mail is sent is routers. This section dictates how Exim decides where to send an email. In exim4.conf.template, find the ROUTERS section.

For direct delivery, you’ll want a router that handles local users and another that handles remote delivery. A common setup looks like this:

# This router handles mail for local users (e.g., user@localhost)
localuser:
  driver = localuser
  transport = local_delivery
  no_more

# This router handles mail to remote hosts (e.g., user@example.com)
remote_smtp:
  driver = smtprelay
  transport = remote_smtp
  no_more

The localuser router uses the localuser driver to deliver mail to local system users. The transport = local_delivery tells it to use the built-in local delivery mechanism. no_more is crucial: it tells Exim to stop processing this message if it successfully routes it here.

The remote_smtp router is where the magic for sending mail outside your server happens. driver = smtprelay is a simple driver that uses DNS (specifically, MX records) to find the next hop for the email. transport = remote_smtp specifies that Exim should use the remote_smtp transport definition (which we’ll cover next) to actually send the mail.

Next, we need to define the transports. This section tells Exim how to deliver the mail once a router has decided where it should go. Find the TRANSPORTS section.

For our setup, we need definitions for local_delivery and remote_smtp:

local_delivery:
  driver = appendfile
  directory = /var/mail/${local_part}
  # Use this if you want to deliver to mbox format (older systems)
  # file = /var/mail/${local_part}
  # Use this for Maildir format (modern, recommended)
  # directory = /var/mail/${local_part}/Maildir
  # For simplicity, we'll stick with the default /var/mail/user for now.

remote_smtp:
  driver = smtp
  protocol = smtp
  port = 25
  # If using an smarthost, uncomment and configure below:
  # hosts = smtp.gmail.com::587
  # hosts_require_auth = smtp.gmail.com
  # You'll need to configure authentication for this, which is more complex.
  # For direct delivery, no specific hosts are needed here.

The local_delivery transport uses the appendfile driver to write the email to a file, typically in /var/mail/username. The remote_smtp transport uses the smtp driver to connect to the destination server using the SMTP protocol on port 25.

After modifying exim4.conf.template, you need to update Exim’s configuration:

sudo update-exim4.conf

This command reads the template and generates the actual Exim configuration file (usually /etc/exim4/exim4.conf).

To test sending mail, use the mail command:

echo "This is a test email." | mail -s "Test Subject" your-external-email@example.com

Check your external inbox for the email. If it doesn’t arrive, check Exim’s logs. The primary log file is /var/log/exim4/mainlog. You can view it with:

sudo tail -f /var/log/exim4/mainlog

Look for lines indicating connection attempts, delivery status, or any errors.

A common issue is firewall blocking. Ensure port 25 (SMTP) is open outbound on your server. If you’re sending mail via a smarthost (like Gmail), you’ll need to configure authentication in the remote_smtp transport, which involves creating an authentication file and referencing it. This is a more advanced topic.

A common mistake is forgetting no_more in the routers. If you have multiple routers that could potentially match, and no_more is missing, Exim might try to deliver the same email multiple times through different paths, leading to unexpected behavior.

If you find your emails are consistently getting marked as spam, you’ll need to delve into DNS records like SPF, DKIM, and DMARC, which are configured outside of Exim but are essential for deliverability.

The next hurdle you’ll likely face is handling incoming mail, which involves configuring MX records for your domain and setting up Exim to accept and deliver mail to local users.

Want structured learning?

Take the full Smtp course →