Complete Email Server Setup Tutorial with Dovecot, Postfix, and Virtual Users (Debian)

Complete Email Server Setup Tutorial with Dovecot, Postfix, and Virtual Users (Debian)

This guide walks you through a complete setup of a self-hosted email server using Postfix for sending mail, Dovecot for IMAP access, and virtual users stored in a flat file. This tutorial avoids using any personal domain or user information.


βœ… Prerequisites

  • Debian 12 VPS
  • Root access
  • Domain name with DNS control (e.g., example.com)
  • Ports 993 (IMAPS) and 587 (SMTP with STARTTLS) open in firewall

πŸ”§ System Setup

1. Create Mail Directory Structure

mkdir -p /var/mail/vhosts/example.com/user

# Create virtual mail user and group
groupadd -g 5000 vmail
useradd -u 5000 -g vmail -s /sbin/nologin -d /var/mail/vhosts vmail

# Set ownership
chown -R vmail:vmail /var/mail/vhosts

πŸ“¨ Dovecot Configuration

2. Install Dovecot

apt update
apt install dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-managesieved

3. Configure /etc/dovecot/conf.d/10-mail.conf

mail_location = maildir:/var/mail/vhosts/%d/%n
mail_privileged_group = mail

namespace inbox {
  inbox = yes
}

4. Create /etc/dovecot/users

user@example.com:{PLAIN}password123
chown dovecot:dovecot /etc/dovecot/users
chmod 600 /etc/dovecot/users

5. Configure /etc/dovecot/conf.d/10-auth.conf

auth_username_format = %Lu
disable_plaintext_auth = no
auth_mechanisms = plain login

#!include auth-system.conf.ext
!include auth-passwdfile.conf.ext

6. Configure /etc/dovecot/conf.d/auth-passwdfile.conf.ext

passdb {
  driver = passwd-file
  args = /etc/dovecot/users
}

userdb {
  driver = static
  args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

7. Restart Dovecot

systemctl restart dovecot

8. Test Dovecot

doveadm user user@example.com

Should show: home=/var/mail/vhosts/example.com/user and uid/gid info.


βœ‰οΈ Postfix Configuration

9. Install Postfix

apt install postfix

Select “Internet Site” and set system mail name to example.com

10. Edit /etc/postfix/main.cf

Add or modify the following lines:

myhostname = mail.example.com
mydomain = example.com
myorigin = /etc/mailname
inet_interfaces = all
inet_protocols = ipv4

virtual_mailbox_domains = example.com
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_minimum_uid = 5000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_alias_maps = hash:/etc/postfix/virtual
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.example.com/privkey.pem
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_recipient_restrictions =
  permit_sasl_authenticated,
  permit_mynetworks,
  reject_unauth_destination

11. Create /etc/postfix/vmailbox

user@example.com example.com/user/
postmap /etc/postfix/vmailbox

12. Create /etc/postfix/virtual

(Optional aliases)

admin@example.com user@example.com
postmap /etc/postfix/virtual

13. Configure Dovecot SASL for Postfix

Create /etc/dovecot/conf.d/10-master.conf (edit service auth block):

service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
}

14. Reload Postfix

systemctl reload postfix

πŸ”’ DKIM Setup (with OpenDKIM)

15. Install OpenDKIM

apt install opendkim opendkim-tools

16. Configure /etc/opendkim.conf

Add:

Mode                sv
Canonicalization    relaxed/simple
Domain              example.com
KeyFile             /etc/opendkim/keys/example.com/mail.private
Selector            mail
Socket              local:/var/spool/postfix/opendkim/opendkim.sock
InternalHosts       127.0.0.1
KeyTable            /etc/opendkim/key.table
SigningTable        /etc/opendkim/signing.table

17. Key Setup

mkdir -p /etc/opendkim/keys/example.com
cd /etc/opendkim/keys/example.com
opendkim-genkey -s mail -d example.com
chown opendkim:opendkim mail.private

18. Create Supporting Files

/etc/opendkim/key.table

mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private

/etc/opendkim/signing.table

*@example.com mail._domainkey.example.com

/etc/opendkim/trusted.hosts

127.0.0.1
localhost
example.com

19. Connect Postfix to OpenDKIM

In /etc/postfix/main.cf:

milter_default_action = accept
milter_protocol = 2
smtpd_milters = unix:/var/spool/postfix/opendkim/opendkim.sock
non_smtpd_milters = unix:/var/spool/postfix/opendkim/opendkim.sock

20. Restart Services

systemctl restart opendkim
systemctl restart postfix

21. Add DKIM DNS Record

Use the contents of mail.txt in /etc/opendkim/keys/example.com/ Add it as a TXT record:

  • Name: mail._domainkey
  • Type: TXT
  • Value: (contents of p=… string, one line, no quotes)

πŸ“± Email Client Settings (IMAP)

SettingValue
IMAP Servermail.example.com
IMAP Port993
EncryptionSSL/TLS
SMTP Servermail.example.com
SMTP Port587
EncryptionSTARTTLS
Usernameuser@example.com
Passwordpassword123
AuthenticationRequired (no SPA)

βœ… Test Tools

  • IMAP test: openssl s_client -connect mail.example.com:993
  • SMTP test: openssl s_client -starttls smtp -connect mail.example.com:587
  • DKIM check: dkimvalidator.com
  • Mail delivery logs:
journalctl -u postfix -f
journalctl -u dovecot -f

This setup supports multiple users and domains and is ideal for small businesses or self-hosters seeking privacy and control.

Share this post

Leave a Reply

Your email address will not be published. Required fields are marked *