From wiki


This article is part of the emails series. It is assumed that you already covered Dovecot.

This guide also uses the following software:


$ sudo apt install exim4-daemon-heavy

Note: The heavy version is needed to use Dovecot as an authentication mechanism.



Create file /etc/exim4/conf.d/main/00_local_settings

daemon_smtp_ports = smtp : 587

TLS Certificates

Create folder

Unlike other programs, Exim doesn't read it's certificate as the root user. So it will be unable to read them from the standard let’sencrypt folder. We will create a folder readable by Exim where we can safely drop certificates later

$ sudo mkdir -m 710 /etc/exim4/private
$ sudo chgrp Debian-exim /etc/exim4/private

Get certificate

  1. Edit file /etc/nginx/sites-enabled/noweb an add a server_name line for smtp.example.org
  2. Activate your new domain in Nginx
    $ sudo systemctl reload nginx.service
  3. Edit file /usr/local/sbin/renew_certificates and add the following to the config list
        "domains": ["smtp.example.org"],
        "reload": [["cp", "--preserve=all", "/etc/letsencrypt/live/smtp.example.org/fullchain.pem", "/etc/letsencrypt/live/smtp.example.org/privkey.pem", "/etc/exim4/private/"], ["/bin/systemctl", "reload", "exim4.service"]]
  4. Get Your certificate
    $ sudo /usr/local/sbin/certmanage
    Renewing certificate for smtp.example.org that will expire on 0001-01-01
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
    Obtaining a new certificate
    Performing the following challenges:
    http-01 challenge for smtp.example.org
    Using the webroot path /var/www/acme-challenge for all unmatched domains.
    Waiting for verification...
    Cleaning up challenges
    Generating key (2048 bits): /etc/letsencrypt/keys/1764_key-certbot.pem
    Creating CSR: /etc/letsencrypt/csr/1764_csr-certbot.pem
     - Congratulations! Your certificate and chain have been saved at
       /etc/letsencrypt/live/smtp.example.org/fullchain.pem. Your cert
       will expire on 2024-10-19. To obtain a new or tweaked version of
       this certificate in the future, simply run certbot again. To
       non-interactively renew *all* of your certificates, run "certbot
     - If you like Certbot, please consider supporting our work by:
       Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
       Donating to EFF:                    https://eff.org/donate-le
    Restarting services:
    cp --preserve=all /etc/letsencrypt/live/smtp.example.org/{fullchain,privkey}.pem /etc/exim4/private/
    /bin/systemctl reload exim4.service

Use Certificate

Edit /etc/exim4/conf.d/main/00_local_settings and add the following lines

MAIN_TLS_CERTIFICATE = /etc/exim4/private/fullchain.pem
MAIN_TLS_PRIVATEKEY = /etc/exim4/private/privkey.pem
# GNUTLS ciphers: https://www.gnutls.org/manual/html_node/Priority-Strings.html
# test using: gnutls-cli -l --priority PFS:+RSA:...


We will use dovecot to verify user login and password. It lets us have only one database of users and share it between the different email infrastructure parts (smtp, imap...)


First modify the file /etc/dovecot/conf.d/10-master.conf. Find the section service auth and add the following lines

service auth {
    # Authentication socket used by Exim
    unix_listener auth-client {
        mode = 0600
        user = Debian-exim

And apply config with

$ sudo systemctl restart dovecot.service


Create file /etc/exim4/conf.d/auth/15_dovecot

  driver = dovecot
  public_name = LOGIN
  server_socket = /run/dovecot/auth-client
  server_set_id = $auth1

  driver = dovecot
  public_name = PLAIN
  server_socket = /run/dovecot/auth-client
  server_set_id = $auth1

Smart catch

This is my #1 spam fighting technique. It allows me to have an infinite number of email addresses while still preventing spammers to generate them.

You can check the installation instructions.

Dovecot Delivery

Create file /etc/exim4/conf.d/router/899_dovecot

## router/899_dovecot

  debug_print = "R: dovecot for $local_part@$domain"
  driver = accept
  domains = +local_domains
  transport = dovecot_virtual_delivery
  cannot_route_message = Unknown user

Then create /etc/exim4/conf.d/transport/99_dovecot_virtual_delivery

  driver = pipe
  command = /usr/lib/dovecot/dovecot-lda -d $local_part -a $original_local_part@$original_domain  -f $sender_address -e
  message_prefix =
  message_suffix =
  user = vmail
  temp_errors = 64 : 69 : 70: 71 : 72 : 73 : 74 : 75 : 78


Assuming that you configured nftables as described, you can edit file /etc/nftables/main_config.conf and add

# Exim
add element  inet main  tcp_port_in { 25, 587 }
add element  inet main  tcp_port_out { 25 }

and activate it using

$ sudo /etc/nftables/reload_main.conf




In case Exim encounter a grave problem (cannot start, lost email…) it will write a log to /var/log/exim4/paniclog. There is a cron job that monitor this file and will send you a daily mail if it is not empty.

It is important to not miss these emails and act on them quickly. I use a Sieve script to mark them as important:

if header :matches "Subject" "exim paniclog on * has non-zero size" {
    addflag "\\Flagged";

Also note that this log file is never rotated. So you will get the same email over and over until you do it manually. It can be done with:

$ sudo logrotate -f /etc/logrotate.d/exim4-paniclog

To have this rotation done automatically (and thus receive the email only once), edit /etc/default/exim4

# Rotate /var/log/exim4/paniclog after email is sent to admin


The filter for Exim is already included in Debian, we just need to activate it. It will filter people trying to log on your server, trying to make it relay spam, and sending nonsense command.

Create file /etc/fail2ban/jail.d/exim.conf

enabled  = true
port     = 25,587
logpath  = %(exim_main_log)s