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 versionmx: Servers in MX records can sendip4:192.0.2.1: This IP can send-all: Reject all others (use~allfor 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 versionp=quarantine: Policy (none/quarantine/reject)rua: Aggregate report emailruf: Forensic report emailfo=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:
- MX Toolbox: https://mxtoolbox.com/
- Mail Tester: https://www.mail-tester.com/
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
- Update spam rules:
sudo sa-update
sudo systemctl restart spamassassin
- Update virus definitions (automated via freshclam):
sudo systemctl status clamav-freshclam
- Certificate renewal (automated via certbot):
sudo certbot renew
- Monitor disk space:
df -h /var/mail
- Backup configuration:
sudo tar -czf mail-server-backup-$(date +%F).tar.gz \
/etc/postfix \
/etc/dovecot \
/etc/opendkim \
/var/mail
Security Best Practices
- Use strong passwords for all mail accounts
- Restrict relay to authenticated users only
- Enable TLS/SSL for all connections
- Keep software updated regularly
- Monitor logs for suspicious activity
- Implement rate limiting to prevent abuse
- 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
- Regular backups of mail data and configurations
- Test deliverability regularly with mail-tester.com
- 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
Related Articles
- Advanced systemd Service Management and Unit File Creation
- What is Cyber Essentials, Cyber Essentials Plus and how do
- Raspberry Pi Network Sensor Transforms Workflow
- Essential Penetration Testing Tools
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
- Postfix Documentation: http://www.postfix.org/documentation.html
- Dovecot Documentation: https://doc.dovecot.org/
- OpenDKIM Documentation: http://www.opendkim.org/
- SPF Project: http://www.openspf.org/
- DMARC Guide: https://dmarc.org/