Ubuntu: install and configure SMTP server with Exim

We use Ubuntu 22.04

Step 1: install Exim via command line:
apt install exim4

Selecting previously unselected package exim4-config.
(Reading database ... 73634 files and directories currently installed.)
Preparing to unpack .../exim4-config_4.95-4ubuntu2.5_all.deb ...
Unpacking exim4-config (4.95-4ubuntu2.5) ...
Selecting previously unselected package exim4-base.
Preparing to unpack .../exim4-base_4.95-4ubuntu2.5_amd64.deb ...
Unpacking exim4-base (4.95-4ubuntu2.5) ...
Selecting previously unselected package libgnutls-dane0:amd64.
Preparing to unpack .../libgnutls-dane0_3.7.3-4ubuntu1.5_amd64.deb ...
Unpacking libgnutls-dane0:amd64 (3.7.3-4ubuntu1.5) ...
Selecting previously unselected package exim4-daemon-light.
Preparing to unpack .../exim4-daemon-light_4.95-4ubuntu2.5_amd64.deb ...
Unpacking exim4-daemon-light (4.95-4ubuntu2.5) ...
Selecting previously unselected package exim4.
Preparing to unpack .../exim4_4.95-4ubuntu2.5_all.deb ...
Unpacking exim4 (4.95-4ubuntu2.5) ...
Setting up libgnutls-dane0:amd64 (3.7.3-4ubuntu1.5) ...
Setting up exim4-config (4.95-4ubuntu2.5) ...
Adding system-user for exim (v4)
Setting up exim4-base (4.95-4ubuntu2.5) ...
exim: DB upgrade, deleting hints-db
Created symlink /etc/systemd/system/timers.target.wants/exim4-base.timer → /lib/systemd/system/exim4-base.timer.
exim4-base.service is a disabled or a static unit, not starting it.
Setting up exim4-daemon-light (4.95-4ubuntu2.5) ...
Setting up exim4 (4.95-4ubuntu2.5) ...
Processing triggers for man-db (2.10.2-1) ...
Processing triggers for libc-bin (2.35-0ubuntu3.7) ...
Scanning processes...
Scanning candidates...
Scanning processor microcode...
Scanning linux images...

The processor microcode seems to be up-to-date.

Restarting services...
 systemctl restart irqbalance.service packagekit.service php8.1-fpm.service polkit.service supervisor.service
Service restarts being deferred:
 systemctl restart networkd-dispatcher.service
 systemctl restart unattended-upgrades.service

No containers need to be restarted.

No user sessions are running outdated binaries.

No VM guests are running outdated hypervisor (qemu) binaries on this host.

After the installation is complete, you can check the installed Exim version with the command:

exim --version


root@tutorialspots ~ # exim --version
Exim version 4.95 #2 built 11-Jan-2024 13:16:58
Copyright (c) University of Cambridge, 1995 - 2018
(c) The Exim Maintainers and contributors in ACKNOWLEDGMENTS file, 2007 - 2020
Berkeley DB: Berkeley DB 5.3.28: (September  9, 2013)
Support for: crypteq iconv() IPv6 GnuTLS TLS_resume move_frozen_messages DANE DKIM DNSSEC Event I18N OCSP PIPE_CONNECT PRDR Experimental_Queue_Ramp SOCKS SRS TCP_Fast_Open
Lookups (built-in): lsearch wildlsearch nwildlsearch iplsearch cdb dbm dbmjz dbmnz dnsdb dsearch nis nis0 passwd
Authenticators: cram_md5 external plaintext
Routers: accept dnslookup ipliteral manualroute queryprogram redirect
Transports: appendfile/maildir/mailstore autoreply lmtp pipe smtp
Fixed never_users: 0
Configure owner: 0:0
Size of off_t: 8
Configuration file search path is /etc/exim4/exim4.conf:/var/lib/exim4/config.autogenerated
Configuration file is /var/lib/exim4/config.autogenerated

Step 2: Configure Exim
use command:
dpkg-reconfigure exim4-config

config exim4

config exim4 2

config exim4 3

config exim4 4

config exim4 5

config exim4 6

config exim4 7

config exim4 8

config exim4 8

config exim4 9

config exim4 10

Edit file /etc/exim4/conf.d/main/02_exim4-config_options , add line
disable_ipv6 = true

Restart service exim4

Step 3: SPF configuration:
Add SPF Record to DNS :
Log in to your domain’s DNS admin account. Usually through the administration interface of the domain name provider or DNS service you are using.
Add a new TXT record with the following content:

v=spf1 a:mail.yourdomain.com ip4:<server_ip> include:_spf.google.com ~all

v=spf1 a:mail.yourdomain.com ip4: include:_spf.google.com ~all

Save changes.

read more about SPF: https://support.google.com/a/answer/10685031?sjid=14440567733282704103-AP

Step 4: Install OpenDKIM using the following command:
sudo apt install opendkim opendkim-tools

Unpacking libopendkim11:amd64 (2.11.0~beta2-6) ...
Selecting previously unselected package libmemcached11:amd64.
Preparing to unpack .../01-libmemcached11_1.0.18-4.2ubuntu4_amd64.deb ...
Unpacking libmemcached11:amd64 (1.0.18-4.2ubuntu4) ...
Selecting previously unselected package libmilter1.0.1:amd64.
Preparing to unpack .../02-libmilter1.0.1_8.15.2-22ubuntu3_amd64.deb ...
Unpacking libmilter1.0.1:amd64 (8.15.2-22ubuntu3) ...
Selecting previously unselected package libopendbx1.
Preparing to unpack .../03-libopendbx1_1.4.6-16_amd64.deb ...
Unpacking libopendbx1 (1.4.6-16) ...
Selecting previously unselected package librbl1:amd64.
Preparing to unpack .../04-librbl1_2.11.0~beta2-6_amd64.deb ...
Unpacking librbl1:amd64 (2.11.0~beta2-6) ...
Selecting previously unselected package libunbound8:amd64.
Preparing to unpack .../05-libunbound8_1.13.1-1ubuntu5.4_amd64.deb ...
Unpacking libunbound8:amd64 (1.13.1-1ubuntu5.4) ...
Selecting previously unselected package libvbr2:amd64.
Preparing to unpack .../06-libvbr2_2.11.0~beta2-6_amd64.deb ...
Unpacking libvbr2:amd64 (2.11.0~beta2-6) ...
Selecting previously unselected package dns-root-data.
Preparing to unpack .../07-dns-root-data_2023112702~ubuntu0.22.04.1_all.deb ...
Unpacking dns-root-data (2023112702~ubuntu0.22.04.1) ...
Selecting previously unselected package opendkim.
Preparing to unpack .../08-opendkim_2.11.0~beta2-6_amd64.deb ...
Unpacking opendkim (2.11.0~beta2-6) ...
Selecting previously unselected package libopendbx1-sqlite3.
Preparing to unpack .../09-libopendbx1-sqlite3_1.4.6-16_amd64.deb ...
Unpacking libopendbx1-sqlite3 (1.4.6-16) ...
Selecting previously unselected package opendkim-tools.
Preparing to unpack .../10-opendkim-tools_2.11.0~beta2-6_amd64.deb ...
Unpacking opendkim-tools (2.11.0~beta2-6) ...
Setting up libopendkim11:amd64 (2.11.0~beta2-6) ...
Setting up libopendbx1 (1.4.6-16) ...
Setting up dns-root-data (2023112702~ubuntu0.22.04.1) ...
Setting up libunbound8:amd64 (1.13.1-1ubuntu5.4) ...
Setting up libmilter1.0.1:amd64 (8.15.2-22ubuntu3) ...
Setting up libmemcached11:amd64 (1.0.18-4.2ubuntu4) ...
Setting up librbl1:amd64 (2.11.0~beta2-6) ...
Setting up libvbr2:amd64 (2.11.0~beta2-6) ...
Setting up libopendbx1-sqlite3 (1.4.6-16) ...
Setting up opendkim-tools (2.11.0~beta2-6) ...
Setting up opendkim (2.11.0~beta2-6) ...
Created symlink /etc/systemd/system/multi-user.target.wants/opendkim.service → /lib/systemd/system/opendkim.service.
Processing triggers for man-db (2.10.2-1) ...
Processing triggers for libc-bin (2.35-0ubuntu3.7) ...
Scanning processes...
Scanning processor microcode...
Scanning linux images...

Running kernel seems to be up-to-date.

The processor microcode seems to be up-to-date.

No services need to be restarted.

No containers need to be restarted.

No user sessions are running outdated binaries.

No VM guests are running outdated hypervisor (qemu) binaries on this host.

Step 5: Generate a key pair for DKIM with the following command:

sudo opendkim-genkey -t -s <selector> -d <your_domain>



with a name of your choice (eg:postmaster) and your domain name.

If you want to use email admin@yourdomain.com you use


is admin

This command will create two files:




Step 6: create OpenDKIM’s key directory: /etc/opendkim/keys/

mkdir -p /etc/opendkim/keys/<your_domain>

Step 7: Move the private key into OpenDKIM’s key directory:

sudo mv <selector>.private /etc/opendkim/keys/<your_domain>/<selector>.private

Step 8: Specify ownership for the lock file

sudo chown opendkim:opendkim /etc/opendkim/keys/<your_domain>/<selector>.private

sudo chown opendkim:opendkim /etc/opendkim/keys/tutorialspots.com/postmaster.private

Step 9: Edit OpenDKIM’s configuration file /etc/opendkim.conf

uncomment then change default:

#Domain                 example.com
#Selector               2020
#KeyFile                /etc/dkimkeys/example.private


Domain                  <your_domain>
Selector                <selector>
KeyFile                 /etc/opendkim/keys/<your_domain>/<selector>.private

Step 10: edit file /etc/default/opendkim

you will see

# default:
# listen on all interfaces on port 54321:
# listen on loopback on port 12345:
# listen on on port 12345:

change to

# default:
# listen on all interfaces on port 54321:
# listen on loopback on port 12345:
# listen on on port 12345:

Step 11: Restart the OpenDKIM service
sudo systemctl restart opendkim

Step 12: Add DKIM Records to DNS :
open file


cat postmaster.txt

You will see content like:

postmaster._domainkey   IN      TXT     ( "v=DKIM1; h=sha256; k=rsa; t=y; "
          "kCcy8NZ16mMTZ7qXqmPabXmjY4+aeIhFXf8b87ELPmG7zZwvdyfFg82c7hmNN8MFgTGBLu52QWb3umvAvmZRDrSET+it4sfPH1ikPdRBBCa0l7AUyUmIBzM0XXtVvC1iHCMXL7YQIDAQAB" )  ; ----- DKIM key postmaster for yourdomain.com

you only need to copy parts


of the recording.


Add TXT record postmaster._domainkey

Step 13: Configure Exim to use DKIM:
Exim configuration :
Edit Exim’s configuration file /etc/exim4/conf.d/main/02_exim4-config_options

add theses lines at top

DKIM_DOMAIN = tutorialspots.com
DKIM_SELECTOR = postmaster
DKIM_PRIVATE_KEY = /etc/opendkim/keys/tutorialspots.com/postmaster.private

Step 14: Restart Exim and OpenDKIM :
Restart Exim :

sudo systemctl restart exim4

Restart OpenDKIM:

sudo systemctl restart opendkim

Verify SMTP server:

root@tutorialspots ~ # telnet 25
Connected to
Escape character is '^]'.
220 Ubuntu-2204-jammy-amd64-base ESMTP Exim 4.95 Ubuntu Mon, 13 May 2024 08:36:07 +0000

Leave a Reply