Last updated: 2026-02-11
Exim TLS/SSL Configuration Guide
This guide provides recommended TLS/SSL settings for Exim, a highly configurable mail transfer agent. Exim is the default MTA on Debian and Ubuntu systems. Unlike most MTAs, Exim can be built against either OpenSSL or GnuTLS, and the syntax for cipher and protocol configuration differs between the two. This guide covers both variants.
Prerequisites
- Exim 4.93 or later (4.96+ recommended)
- OpenSSL 1.1.1 or later, or GnuTLS 3.6 or later
- A valid SSL/TLS certificate from a trusted CA
Determine Your TLS Library
Exim's TLS behavior depends on which library it was compiled against. Check with:
exim -bV | grep TLS
You will see either OpenSSL or GnuTLS in the output. This determines which cipher and protocol syntax to use throughout this guide.
Distribution defaults: Debian and Ubuntu build Exim with GnuTLS. RHEL and derivatives build Exim with OpenSSL.
Certificate Configuration
tls_certificate = /etc/exim/ssl/fullchain.pem
tls_privatekey = /etc/exim/ssl/privkey.pem
Path note: RHEL-based systems use
/etc/exim/. Debian and Ubuntu use/etc/exim4/. On Debian/Ubuntu with split configuration, place TLS settings in/etc/exim4/conf.d/main/01_exim4-config_tlsor usedpkg-reconfigure exim4-configand edit the unsplit config file.
Server TLS Configuration (Incoming SMTP)
These settings control how Exim handles incoming SMTP connections on port 25.
Advertise STARTTLS
tls_advertise_hosts = *
This advertises STARTTLS to all connecting hosts. Exim does not have a single "security level" setting like Postfix; instead, you control mandatory TLS through ACLs (see Submission Port).
Protocol Versions
OpenSSL builds:
openssl_options = +no_sslv2 +no_sslv3 +no_tlsv1 +no_tlsv1_1
GnuTLS builds:
Protocol versions are controlled through the GnuTLS priority string in tls_require_ciphers (see Cipher Suites below). The -VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3 component restricts to TLS 1.2 and 1.3.
The
+no_tlsv1and+no_tlsv1_1options require Exim 4.91+. Earlier versions only support+no_sslv2and+no_sslv3.
Cipher Suites
OpenSSL builds:
tls_require_ciphers = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
GnuTLS builds:
tls_require_ciphers = SECURE256:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3
The GnuTLS priority string controls both cipher suites and protocol versions in a single directive. SECURE256 selects strong cipher suites with 256-bit security level (it also includes 128-bit AES-GCM). The -VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3 portion restricts to TLS 1.2 and 1.3.
Important:
tls_require_ciphersin the main configuration section applies to incoming (server-side) connections. The same directive used inside a transport block applies to outgoing (client-side) connections.
ECDH Curve Selection
tls_eccurve = P-256:P-384
This selects the elliptic curves for ECDHE key exchange. Requires Exim 4.93+.
Logging
log_selector = +tls_cipher +tls_peerdn +tls_sni
This adds TLS cipher, peer certificate DN, and SNI information to the main log.
Client TLS Configuration (Outgoing SMTP)
These settings control how Exim connects to other mail servers when delivering outbound mail. They are configured in the remote_smtp transport block.
Enable Opportunistic TLS
In the remote_smtp transport:
remote_smtp:
driver = smtp
hosts_try_tls = *
- hosts_try_tls -- Attempt STARTTLS with all remote servers, but fall back to plaintext if it fails (recommended for general delivery)
- hosts_require_tls -- Require TLS for specific destinations (mail will be deferred if TLS fails)
Certificate Verification
remote_smtp:
driver = smtp
hosts_try_tls = *
tls_try_verify_hosts = *
tls_verify_certificates = /etc/ssl/certs/ca-certificates.crt
- tls_try_verify_hosts -- Attempt to verify the remote server's certificate but deliver anyway if verification fails (opportunistic verification)
- tls_verify_hosts -- Require certificate verification for specific destinations (mail will be deferred if verification fails)
- tls_verify_certificates -- Path to the CA bundle. Use
/etc/ssl/certs/ca-certificates.crton Debian/Ubuntu or/etc/pki/tls/certs/ca-bundle.crton RHEL.
Client Cipher Settings
You can set client-side cipher preferences in the transport block:
OpenSSL builds:
remote_smtp:
driver = smtp
hosts_try_tls = *
tls_require_ciphers = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
GnuTLS builds:
remote_smtp:
driver = smtp
hosts_try_tls = *
tls_require_ciphers = SECURE256:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3
DANE Support
DANE (DNS-Based Authentication of Named Entities) uses TLSA DNS records to verify server certificates without relying on certificate authorities.
Enable DANE
In the remote_smtp transport:
remote_smtp:
driver = smtp
hosts_try_dane = *
hosts_try_tls = *
tls_try_verify_hosts = *
tls_verify_certificates = /etc/ssl/certs/ca-certificates.crt
dane_require_tls_ciphers = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
- hosts_try_dane -- Attempt DANE verification for all destinations; falls back to normal TLS if no TLSA records exist
- hosts_require_dane -- Require DANE for specific destinations (mail deferred if DANE fails)
- dane_require_tls_ciphers -- Cipher list used when DANE is active (OpenSSL syntax; for GnuTLS, use the priority string format)
DNSSEC Requirement
DANE requires a DNSSEC-validating DNS resolver. Exim must also be compiled with SUPPORT_DANE=yes (enabled by default in Exim 4.91+ on most distributions).
Submission Port (587)
For authenticated email submission from mail clients, configure Exim to listen on port 587 with mandatory TLS. Add to the main configuration:
daemon_smtp_ports = 25 : 587
tls_on_connect_ports = 465
Port 465 (SMTPS) uses implicit TLS, where the connection is encrypted from the start. Ports 25 and 587 use STARTTLS.
Require TLS on Port 587
In the acl_check_rcpt ACL (or your RCPT ACL), add a rule early in the ACL to deny unauthenticated or unencrypted submission:
deny
condition = ${if eq{$interface_port}{587}}
!encrypted = *
message = TLS required on submission port
deny
condition = ${if eq{$interface_port}{587}}
!authenticated = *
message = Authentication required on submission port
These rules ensure that connections on port 587 must use TLS encryption and SMTP authentication before mail is accepted.
Version Notes
Several features depend on specific Exim versions. Enterprise distributions often ship older versions:
openssl_optionswith+no_tlsv1/+no_tlsv1_1-- Requires Exim 4.91+. Earlier versions only support+no_sslv2and+no_sslv3.tls_eccurve-- Requires Exim 4.93+. Omit on older versions.- DANE support -- Requires Exim 4.91+ compiled with
SUPPORT_DANE=yes. - ECDHE key exchange -- Requires Exim 4.85+.
Distribution versions:
- RHEL 8: Exim 4.92 (OpenSSL)
- RHEL 9: Exim 4.96 (OpenSSL)
- Debian 11 (Bullseye): Exim 4.94 (GnuTLS)
- Debian 12 (Bookworm): Exim 4.96 (GnuTLS)
- Ubuntu 22.04: Exim 4.95 (GnuTLS)
- Ubuntu 24.04: Exim 4.97 (GnuTLS)
SLES 15 does not include Exim in its base repositories.
Complete Configuration
The following is a complete TLS configuration for an OpenSSL-based Exim build. GnuTLS alternatives are noted in comments.
Main Configuration
# Certificate files
tls_certificate = /etc/exim/ssl/fullchain.pem
tls_privatekey = /etc/exim/ssl/privkey.pem
# Advertise STARTTLS to all hosts
tls_advertise_hosts = *
# Listen on SMTP, submission, and SMTPS ports
daemon_smtp_ports = 25 : 587
tls_on_connect_ports = 465
# Protocol versions (OpenSSL)
# On GnuTLS builds, protocol versions are controlled in tls_require_ciphers below
openssl_options = +no_sslv2 +no_sslv3 +no_tlsv1 +no_tlsv1_1
# Server cipher suites (OpenSSL)
# On GnuTLS builds, use instead:
# tls_require_ciphers = SECURE256:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3
tls_require_ciphers = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
# ECDH curves (requires Exim 4.93+; omit on older versions)
tls_eccurve = P-256:P-384
# TLS logging
log_selector = +tls_cipher +tls_peerdn +tls_sni
ACL Configuration
In your acl_check_rcpt ACL:
# Require TLS on submission port 587
deny
condition = ${if eq{$interface_port}{587}}
!encrypted = *
message = TLS required on submission port
# Require authentication on submission port 587
deny
condition = ${if eq{$interface_port}{587}}
!authenticated = *
message = Authentication required on submission port
Transport Configuration
remote_smtp:
driver = smtp
hosts_try_tls = *
hosts_try_dane = *
tls_try_verify_hosts = *
tls_verify_certificates = /etc/ssl/certs/ca-certificates.crt
# On RHEL, use: /etc/pki/tls/certs/ca-bundle.crt
# Client cipher suites (OpenSSL)
# On GnuTLS builds, use instead:
# tls_require_ciphers = SECURE256:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3
tls_require_ciphers = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
dane_require_tls_ciphers = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
Verification
Check the Exim build and TLS library:
exim -bV | grep TLS
Test inbound STARTTLS on port 25:
openssl s_client -connect mail.example.com:25 -starttls smtp
Test implicit TLS on port 465:
openssl s_client -connect mail.example.com:465
Debug TLS for a specific address:
exim -d+tls -bt user@example.com
Check the main log for TLS connections:
grep tls_cipher /var/log/exim/mainlog
Test your MX server's TLS configuration at https://www.checktls.com/ or https://ssl-tools.net/mailservers.