Setting Up a Complete Linux Mail Server with Postfix,

Deploying a production-ready mail server on Linux is a complex undertaking that requires careful configuration of multiple components. A modern mail server must handle SMTP for sending, IMAP/POP3 for retrieval, implement proper authentication mechanisms, and include anti-spam measures and sender verification through SPF, DKIM, and DMARC. This comprehensive guide walks through building a complete, secure mail server using Postfix and Dovecot on Ubuntu/Debian Linux.

Prerequisites and Planning

Before beginning installation, ensure you have:

  • A dedicated server with at least 2GB RAM and 20GB storage
  • A fully qualified domain name (FQDN) properly configured
  • Static IP address with reverse DNS (PTR record) configured
  • DNS access to create required mail records
  • Root or sudo access to the server
  • Basic understanding of email protocols (SMTP, IMAP, POP3)

DNS Configuration Requirements

Configure these DNS records before installation:

# A record for mail server
mail.example.com.     IN  A     192.0.2.1

## MX record pointing to mail server
example.com.          IN  MX 10 mail.example.com.

## PTR record (reverse DNS) - configured with hosting provider
1.2.0.192.in-addr.arpa. IN PTR mail.example.com.

Verify DNS propagation:

dig example.com MX
dig -x 192.0.2.1
host mail.example.com

System Preparation

Update system and set hostname:

## Update system packages
sudo apt update && sudo apt upgrade -y

## Set hostname
sudo hostnamectl set-hostname mail.example.com

## Verify hostname
hostname -f

Edit /etc/hosts:

127.0.0.1       localhost
192.0.2.1       mail.example.com mail

Install essential utilities:

sudo apt install -y vim curl wget ufw net-tools

Installing and Configuring Postfix

Postfix is a robust, secure Mail Transfer Agent (MTA) that handles SMTP operations.

Postfix Installation

sudo apt install -y postfix postfix-mysql

During installation, select:

  • General type: Internet Site
  • System mail name: example.com

Basic Postfix Configuration

Backup original configuration:

sudo cp /etc/postfix/main.cf /etc/postfix/main.cf.backup

Edit /etc/postfix/main.cf:

sudo nano /etc/postfix/main.cf

Essential configuration directives:

## Basic Settings
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4

## TLS/SSL Configuration
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_tls_security_level = may
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_ciphers = high
tls_high_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384

## SMTP Client TLS
smtp_tls_security_level = may
smtp_tls_loglevel = 1

## SASL Authentication
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes

## Restrictions
smtpd_helo_required = yes
smtpd_helo_restrictions = 
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_invalid_helo_hostname,
    reject_non_fqdn_helo_hostname

smtpd_sender_restrictions = 
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_non_fqdn_sender,
    reject_unknown_sender_domain

smtpd_recipient_restrictions = 
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_non_fqdn_recipient,
    reject_unknown_recipient_domain,
    reject_unauth_destination,
    reject_rbl_client zen.spamhaus.org,
    reject_rbl_client bl.spamcop.net

## Mailbox Configuration
home_mailbox = Maildir/
virtual_alias_maps = hash:/etc/postfix/virtual

Edit /etc/postfix/master.cf for submission ports:

sudo nano /etc/postfix/master.cf

Enable submission and submissions ports:

submission inet n       -       y       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_tls_auth_only=yes
  -o smtpd_reject_unlisted_recipient=no
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_helo_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

submissions inet n       -       y       -       -       smtpd
  -o syslog_name=postfix/submissions
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_reject_unlisted_recipient=no
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_helo_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

Installing SSL Certificates with Let’s Encrypt

## Install Certbot
sudo apt install -y certbot

## Stop Postfix temporarily
sudo systemctl stop postfix

## Obtain certificate
sudo certbot certonly --standalone -d mail.example.com

## Start Postfix
sudo systemctl start postfix

## Auto-renewal
sudo certbot renew --dry-run

Set up auto-reload after renewal:

sudo nano /etc/letsencrypt/renewal-hooks/deploy/postfix-reload.sh

Add:

#!/bin/bash
systemctl reload postfix dovecot

Make executable:

sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/postfix-reload.sh

Installing and Configuring Dovecot

Dovecot provides IMAP and POP3 services for mail retrieval.

Dovecot Installation

sudo apt install -y dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd

Dovecot Configuration

Backup configurations:

sudo cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.backup
sudo cp -r /etc/dovecot/conf.d /etc/dovecot/conf.d.backup

Edit /etc/dovecot/dovecot.conf:

sudo nano /etc/dovecot/dovecot.conf
## Enable protocols
protocols = imap pop3 lmtp

## Listen on all interfaces
listen = *, ::

## Log file location
log_path = /var/log/dovecot.log
info_log_path = /var/log/dovecot-info.log

Configure mail location in /etc/dovecot/conf.d/10-mail.conf:

sudo nano /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:~/Maildir
mail_privileged_group = mail

## Namespace configuration
namespace inbox {
  inbox = yes
  
  mailbox Drafts {
    special_use = \Drafts
    auto = subscribe
  }
  
  mailbox Sent {
    special_use = \Sent
    auto = subscribe
  }
  
  mailbox Trash {
    special_use = \Trash
    auto = subscribe
  }
  
  mailbox Spam {
    special_use = \Junk
    auto = subscribe
  }
}

Configure authentication in /etc/dovecot/conf.d/10-auth.conf:

sudo nano /etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = yes
auth_mechanisms = plain login

## Include auth configuration
!include auth-system.conf.ext

Configure SSL in /etc/dovecot/conf.d/10-ssl.conf:

sudo nano /etc/dovecot/conf.d/10-ssl.conf
ssl = required

ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem

ssl_min_protocol = TLSv1.2
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
ssl_prefer_server_ciphers = yes

ssl_dh = </etc/dovecot/dh.pem

Generate DH parameters:

sudo openssl dhparam -out /etc/dovecot/dh.pem 2048

Configure master service in /etc/dovecot/conf.d/10-master.conf:

sudo nano /etc/dovecot/conf.d/10-master.conf
service imap-login {
  inet_listener imap {
    port = 143
  }
  inet_listener imaps {
    port = 993
    ssl = yes
  }
}

service pop3-login {
  inet_listener pop3 {
    port = 110
  }
  inet_listener pop3s {
    port = 995
    ssl = yes
  }
}

service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}

service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
  
  unix_listener auth-userdb {
    mode = 0600
    user = vmail
  }
  
  user = dovecot
}

service auth-worker {
  user = vmail
}

Creating Mail Users

Create system user for mail storage:

sudo groupadd -g 5000 vmail
sudo useradd -g vmail -u 5000 vmail -d /var/mail

Create actual mail users:

## Add user
sudo useradd -m -s /sbin/nologin user1
sudo passwd user1

## Alternatively, use system users
sudo adduser john

Configuring SPF, DKIM, and DMARC

Email authentication protocols prevent spoofing and improve deliverability.

SPF (Sender Policy Framework)

SPF specifies which mail servers can send email for your domain.

Add TXT record to DNS:

example.com.  IN  TXT  "v=spf1 mx ip4:192.0.2.1 -all"

Explanation:

  • v=spf1: SPF version
  • mx: Servers in MX records can send
  • ip4:192.0.2.1: This IP can send
  • -all: Reject all others (use ~all for soft fail)

Test SPF:

dig example.com TXT

DKIM (DomainKeys Identified Mail)

DKIM signs outgoing emails with cryptographic signatures.

Install OpenDKIM:

sudo apt install -y opendkim opendkim-tools

Configure OpenDKIM:

sudo nano /etc/opendkim.conf
Syslog                  yes
SyslogSuccess          yes
LogWhy                 yes

UMask                  002
Mode                   sv
Canonicalization       relaxed/simple
ExternalIgnoreList     refile:/etc/opendkim/TrustedHosts
InternalHosts          refile:/etc/opendkim/TrustedHosts
KeyTable               refile:/etc/opendkim/KeyTable
SigningTable           refile:/etc/opendkim/SigningTable
Socket                 inet:8891@localhost

PidFile                /var/run/opendkim/opendkim.pid
SignatureAlgorithm     rsa-sha256
UserID                 opendkim:opendkim

Create configuration directory and files:

sudo mkdir -p /etc/opendkim/keys/example.com

Create /etc/opendkim/TrustedHosts:

127.0.0.1
localhost
192.0.2.1
*.example.com

Create /etc/opendkim/KeyTable:

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

Create /etc/opendkim/SigningTable:

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

Generate DKIM keys:

cd /etc/opendkim/keys/example.com
sudo opendkim-genkey -b 2048 -d example.com -s mail
sudo chown opendkim:opendkim mail.private

View public key:

sudo cat /etc/opendkim/keys/example.com/mail.txt

Add DKIM DNS TXT record:

mail._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."

Connect OpenDKIM to Postfix:

sudo nano /etc/default/opendkim

Add:

SOCKET="inet:8891@localhost"

Edit Postfix main.cf:

sudo nano /etc/postfix/main.cf

Add:

## OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters

Restart services:

sudo systemctl restart opendkim postfix

DMARC (Domain-based Message Authentication)

DMARC builds on SPF and DKIM, specifying how receivers should handle authentication failures.

Add DMARC DNS TXT record:

_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=1"

Explanation:

  • v=DMARC1: DMARC version
  • p=quarantine: Policy (none/quarantine/reject)
  • rua: Aggregate report email
  • ruf: Forensic report email
  • fo=1: Reporting options

Anti-Spam Configuration

Installing SpamAssassin

sudo apt install -y spamassassin spamc

Enable SpamAssassin:

sudo systemctl enable spamassassin
sudo systemctl start spamassassin

Configure SpamAssassin:

sudo nano /etc/default/spamassassin
ENABLED=1
CRON=1
OPTIONS="--create-prefs --max-children 5 --helper-home-dir"

Update rules:

sudo sa-update
sudo systemctl restart spamassassin

Integrate with Postfix by editing /etc/postfix/master.cf:

smtp      inet  n       -       y       -       -       smtpd
  -o content_filter=spamassassin
  
spamassassin unix -     n       n       -       -       pipe
  user=spamd argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}

Installing ClamAV

sudo apt install -y clamav clamav-daemon clamav-freshclam

Update virus definitions:

sudo systemctl stop clamav-freshclam
sudo freshclam
sudo systemctl start clamav-freshclam

Firewall Configuration

Configure UFW to allow mail ports:

## Enable UFW
sudo ufw enable

## Allow SSH (if not already)
sudo ufw allow 22/tcp

## SMTP
sudo ufw allow 25/tcp

## Submission
sudo ufw allow 587/tcp

## SMTPS
sudo ufw allow 465/tcp

## IMAP
sudo ufw allow 143/tcp

## IMAPS
sudo ufw allow 993/tcp

## POP3
sudo ufw allow 110/tcp

## POP3S
sudo ufw allow 995/tcp

## Check status
sudo ufw status verbose

Testing the Mail Server

Testing SMTP

telnet mail.example.com 25
EHLO test.local
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
Subject: Test Email
This is a test.
.
QUIT

Testing IMAP

openssl s_client -connect mail.example.com:993 -crlf
a1 LOGIN [email protected] password
a2 LIST "" "*"
a3 SELECT INBOX
a4 LOGOUT

Sending Test Email

echo "Test email body" | mail -s "Test Subject" [email protected]

Testing Authentication

Check SPF:

dig example.com TXT

Check DKIM:

dig mail._domainkey.example.com TXT

Check DMARC:

dig _dmarc.example.com TXT

Use online tools:

Monitoring and Maintenance

Log Monitoring

Monitor Postfix logs:

sudo tail -f /var/log/mail.log

Monitor Dovecot logs:

sudo tail -f /var/log/dovecot.log

Queue Management

View mail queue:

sudo mailq
sudo postqueue -p

Flush queue:

sudo postfix flush
sudo postqueue -f

Delete specific message:

sudo postsuper -d <queue_id>

Delete all messages:

sudo postsuper -d ALL

Performance Monitoring

Check Postfix status:

sudo systemctl status postfix

Check Dovecot status:

sudo systemctl status dovecot

Monitor connections:

sudo netstat -tulnp | grep -E ':(25|587|465|143|993|110|995)'

Regular Maintenance Tasks

  1. Update spam rules:
sudo sa-update
sudo systemctl restart spamassassin
  1. Update virus definitions (automated via freshclam):
sudo systemctl status clamav-freshclam
  1. Certificate renewal (automated via certbot):
sudo certbot renew
  1. Monitor disk space:
df -h /var/mail
  1. Backup configuration:
sudo tar -czf mail-server-backup-$(date +%F).tar.gz \
  /etc/postfix \
  /etc/dovecot \
  /etc/opendkim \
  /var/mail

Security Best Practices

  1. Use strong passwords for all mail accounts
  2. Restrict relay to authenticated users only
  3. Enable TLS/SSL for all connections
  4. Keep software updated regularly
  5. Monitor logs for suspicious activity
  6. Implement rate limiting to prevent abuse
  7. Use fail2ban to block brute force attempts:
sudo apt install -y fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Configure fail2ban for mail services:

sudo nano /etc/fail2ban/jail.local
[postfix]
enabled = true

[dovecot]
enabled = true
  1. Regular backups of mail data and configurations
  2. Test deliverability regularly with mail-tester.com
  3. Monitor reputation on blacklists

Troubleshooting Common Issues

Email Not Sending

Check Postfix logs:

sudo tail -100 /var/log/mail.log | grep error

Test SMTP connection:

telnet mail.example.com 25

Verify DNS records:

dig example.com MX
dig -x <your-ip>

Email Not Receiving

Check if Postfix is listening:

sudo netstat -tulnp | grep :25

Test with telnet from external server.

Check spam filters and rules.

Authentication Failures

Check SASL configuration in Postfix and Dovecot.

Verify user credentials:

doveadm auth test [email protected] password

Check permissions on auth socket.

SSL/TLS Errors

Verify certificate paths in configuration files.

Test SSL connection:

openssl s_client -connect mail.example.com:993 -servername mail.example.com

Check certificate validity:

sudo certbot certificates

Conclusion

Building a production-ready mail server requires careful attention to numerous components: SMTP with Postfix, IMAP/POP3 with Dovecot, SSL/TLS encryption, authentication mechanisms, and email validation through SPF, DKIM, and DMARC. While complex, a properly configured mail server provides complete control over email infrastructure, ensuring privacy, security, and deliverability.

This guide provides a solid foundation for a functional mail server. Additional enhancements might include webmail (Roundcube), calendar/contacts (CalDAV/CardDAV), and advanced filtering. Regular maintenance, monitoring, and security updates are essential for long-term reliability.

Remember that email deliverability depends not just on technical configuration but also on server reputation. Start with low volumes, maintain good practices, and gradually build trust with receiving mail servers.


References

Thank you for reading! If you have any feedback or comments, please send them to [email protected].