Streaming & Messaging AWS

Dovecot IMAP and POP3 Mail Server on AWS User Guide

| Product: Dovecot IMAP and POP3 Mail Server

Overview

This guide covers deploying and operating Dovecot on AWS using the cloudimg AWS Marketplace image. Dovecot is one of the most widely deployed open source IMAP and POP3 servers in the world, chosen for its security focus, standards compliance and excellent performance. It runs as a headless daemon administered through the configuration files in /etc/dovecot and the doveadm command line, with no web console.

The image installs the Ubuntu 24.04 archive packages dovecot-core, dovecot-imapd, dovecot-pop3d and dovecot-lmtpd (Dovecot 2.3.21, dual licensed MIT and LGPL 2.1) and configures a self contained, secure by default single node mail store. One virtual mailbox is provisioned with its mail kept in Maildir format under a dedicated unprivileged vmail account, delivery is over LMTP so the whole setup works end to end with no external dependency, and IMAP and POP3 are served over TLS.

Security by design, no default credential. No default or shared credential ships in the image. On the first boot of every instance the dovecot-firstboot.service runs once. It generates a per instance mailbox password, hashes it into the Dovecot password database, regenerates the TLS private key and certificate, and writes the plaintext login to /root/dovecot-credentials.txt (mode 0600, root only). The captured image ships no certificate, no password and only an empty password database, so no mailbox can authenticate until first boot provisions your instance.

Security by design, no plaintext authentication over the network. Dovecot is configured with disable_plaintext_auth = yes and ssl = required, so a remote client's plaintext LOGIN on the non TLS ports (143 and 110) is refused until the connection is upgraded with STARTTLS. IMAP over implicit TLS (993) and POP3 over implicit TLS (995) are the recommended client ports. Only the virtual mailbox user can authenticate, because system and shell accounts are excluded from mail login.

Dovecot provides mailbox access (IMAP and POP3) and local delivery (LMTP). It is not an SMTP mail transfer agent: to send and receive mail with the outside world, pair it with an MTA such as Postfix (covered in Step 9).

What is included:

  • Dovecot 2.3.21 from the Ubuntu 24.04 archive (dovecot-core, dovecot-imapd, dovecot-pop3d, dovecot-lmtpd), run under systemd (dovecot.service)

  • A self contained single node mail store: one virtual mailbox in Maildir format under a dedicated unprivileged vmail account, with local delivery over LMTP

  • IMAP served over TLS on 993 and with STARTTLS on 143, and POP3 over TLS on 995 and with STARTTLS on 110

  • A per instance mailbox password and a fresh TLS key and certificate generated on first boot, documented in /root/dovecot-credentials.txt (0600), so no image ever ships a usable or default credential

  • Plaintext authentication disabled on non TLS connections (disable_plaintext_auth = yes, ssl = required)

  • Ubuntu 24.04 LTS base with the latest security patches applied at build time

  • 24/7 cloudimg support

Connecting to your instance

Connect over SSH on port 22 as the default login user for your OS variant, using your EC2 key pair:

OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i your-key.pem ubuntu@<instance-ip>

Prerequisites

  • An AWS account subscribed to the Dovecot listing on AWS Marketplace

  • An EC2 key pair for SSH access

  • A Security Group allowing TCP 22 (admin), TCP 993 (IMAPS) and TCP 995 (POP3S) for secure client access, and optionally TCP 143 (IMAP with STARTTLS) and TCP 110 (POP3 with STARTTLS)

Recommended instance type: m5.large (2 vCPU, 8 GB RAM) is a comfortable starting point for a small mailbox server. Scale up for more mailboxes, larger mail volumes or higher concurrency.

Step 1: Launch from AWS Marketplace

Subscribe to the Dovecot listing, choose Launch through EC2, and pick your instance type, key pair, subnet and Security Group. Configure the Security Group to allow TCP 22 for administration and TCP 993 and TCP 995 for secure IMAP and POP3 access. Assign a public IP (or Elastic IP) so remote mail clients can connect.

You can also launch from the AWS CLI (replace the AMI id with the one shown on your subscription's launch page, and the ids with your own):

aws ec2 run-instances \
  --image-id ami-xxxxxxxxxxxxxxxxx \
  --instance-type m5.large \
  --key-name your-key \
  --security-group-ids sg-xxxxxxxx \
  --subnet-id subnet-xxxxxxxx \
  --associate-public-ip-address

Step 2: First boot

On the first boot of every instance the dovecot-firstboot.service runs once. It generates the per instance mailbox password, hashes it into the Dovecot password database, regenerates the TLS private key and certificate, writes the plaintext login to /root/dovecot-credentials.txt, and starts Dovecot. Allow about 20 seconds after the instance is first reachable.

Step 3: Confirm the service is running

SSH in, confirm Dovecot is active and check the version.

sudo systemctl is-active dovecot
sudo dovecot --version

Dovecot running under systemd with the dovecot service active, dovecot reporting version 2.3.21, and doveconf reporting the effective configuration including the imap, pop3 and lmtp protocols and Maildir storage

Step 4: Read the per instance mailbox login

The mailbox password is unique to this instance and is written to a root only file on first boot. Read it with:

sudo cat /root/dovecot-credentials.txt

The file contains the mailbox username (mailbox@localhost), the per instance password, and the IMAP host and ports. Store it somewhere safe. (This command is shown in a plain block rather than a runnable one so your password is never echoed into logs.)

Step 5: Inspect the TLS mail listeners

Dovecot serves IMAP on 143 (STARTTLS) and 993 (implicit TLS), and POP3 on 110 (STARTTLS) and 995 (implicit TLS), plus an LMTP loopback listener on 127.0.0.1:24 for local delivery.

sudo ss -tlnp | grep -E ':(143|993|110|995|24) ' | sort
sudo doveconf disable_plaintext_auth ssl ssl_min_protocol

The disable_plaintext_auth = yes and ssl = required settings mean a remote client's plaintext authentication on 143 or 110 is refused until the connection is upgraded with STARTTLS.

The Dovecot TLS mail listeners bound on ports 143, 993, 110 and 995 plus the LMTP loopback listener on 127.0.0.1 port 24, and doveconf confirming disable_plaintext_auth is yes and ssl is required

Step 6: Prove the mailbox credential round trip

The image ships a self contained round trip check that connects over implicit TLS on 993, proves a wrong password is rejected and the per instance password is accepted, selects the INBOX, then delivers a message over LMTP and reads it back over IMAP. It never prints your password.

sudo python3 /usr/local/sbin/cloudimg-dovecot-roundtrip.py

The final OK full: line confirms the whole path works: implicit TLS on 993, a wrong password rejected, the per instance password accepted and the INBOX selectable, and an LMTP delivered message read back over IMAP.

An authenticated IMAPS session over implicit TLS on port 993 with the per instance self signed certificate: the TLS handshake, then a LOGIN with the password shown redacted, SELECT INBOX showing a real message, and a FETCH of the message headers

Step 7: Review the hardened configuration

The password database is a root readable Dovecot password file with a SHA512 hashed per instance password, the TLS certificate and key are unique to this instance and root owned, the system PAM login path is disabled so only the virtual mailbox can authenticate, and plaintext authentication is refused on non TLS connections.

sudo stat -c '%n %a %U:%G' /etc/dovecot/cloudimg-users /etc/dovecot/private/dovecot-cloudimg.pem /etc/dovecot/private/dovecot-cloudimg.key
sudo grep -n 'auth-system.conf.ext' /etc/dovecot/conf.d/10-auth.conf

The hardened Dovecot configuration: the per instance password file and self signed TLS certificate and key with their root only permissions, the system PAM passdb disabled so only the virtual mailbox can authenticate, and disable_plaintext_auth set to yes with ssl required

Step 8: Connect a mail client

Point any standards compliant IMAP or POP3 client at the instance public IP using the mailbox username and the per instance password from the credentials file.

  • IMAP over TLS: host <instance-ip>, port 993, SSL/TLS, username mailbox@localhost, password from the file
  • POP3 over TLS: host <instance-ip>, port 995, SSL/TLS, same username and password
  • IMAP or POP3 with STARTTLS: ports 143 or 110, connection security STARTTLS

The TLS certificate is self signed and unique to this instance, so a client will prompt to trust it. Step 10 covers replacing it with a certificate for your own domain.

Step 9: Front Dovecot with an MTA for real mail

Dovecot is the mailbox store (IMAP and POP3) and local delivery agent (LMTP). To send and receive mail with the outside world, put a mail transfer agent such as Postfix in front of it and have Postfix deliver inbound mail to Dovecot over LMTP. Configure Postfix for your own domain and DNS (MX, SPF, DKIM and DMARC records), and keep outbound relay restricted to authenticated submission.

# example only — install and configure Postfix for your own domain
sudo apt-get install -y postfix
sudo postconf -e "mailbox_transport = lmtp:inet:127.0.0.1:24"
sudo postconf -e "myhostname = mail.<your-domain>"
sudo systemctl restart postfix

Note: AWS blocks outbound SMTP on port 25 by default for new accounts. To send mail directly you can request removal of the port 25 restriction from AWS, or relay outbound mail through a smart host on port 587. Inbound mail and IMAP or POP3 access are unaffected.

Step 10: Add more mailboxes

Add further virtual mailboxes by generating a hashed password with doveadm pw and appending a line to the password file, then reloading Dovecot. Each line is user:hash:uid:gid::home:: with the vmail uid and gid (5000).

# generate a hash for a new mailbox (you will be prompted for the password)
HASH=$(doveadm pw -s SHA512-CRYPT -p '<new-password>')
echo "alice@<your-domain>:${HASH}:5000:5000::/var/vmail/alice@<your-domain>::" \
  | sudo tee -a /etc/dovecot/cloudimg-users
sudo systemctl reload dovecot

Step 11: Install a real TLS certificate

For production, replace the per instance self signed certificate with a certificate for your own domain, for example from Let's Encrypt, and point Dovecot at it.

sudo certbot certonly --standalone -d mail.<your-domain>
sudo sed -i 's#^ssl_cert = .*#ssl_cert = </etc/letsencrypt/live/mail.<your-domain>/fullchain.pem#' /etc/dovecot/conf.d/99-cloudimg.conf
sudo sed -i 's#^ssl_key = .*#ssl_key = </etc/letsencrypt/live/mail.<your-domain>/privkey.pem#' /etc/dovecot/conf.d/99-cloudimg.conf
sudo systemctl restart dovecot

Step 12: Support and Licensing

Dovecot Community Edition is dual licensed under the MIT and LGPL 2.1 licenses, both permissive and redistributable. cloudimg provides the packaging, hardening and AWS integration, with 24/7 support.

Trademark notice. cloudimg is not affiliated with or endorsed by the Dovecot project or Open-Xchange. This image packages the open source Dovecot software for convenient deployment on AWS.

Need Help?

Contact cloudimg support at support@cloudimg.co.uk for deployment assistance, configuration guidance, or licensing questions.