Introduction
Postfix is the most widely deployed open-source MTA (Mail Transfer Agent) on Linux. It handles sending and receiving email with excellent security and performance. This guide covers setting up a complete production mail server with Postfix, Dovecot (for IMAP), and anti-spam measures.
Architecture Overview
TEXT
Internet → [Postfix SMTP Port 25] → [SpamAssassin/ClamAV] → [Dovecot] → User IMAP/POP3
|
[Postfix Submission Port 587] ← Outgoing mail from clientsInstallation
BASH
apt install postfix dovecot-core dovecot-imapd dovecot-pop3d
# During postfix install: choose "Internet Site", enter your domainPostfix Main Configuration
Edit /etc/postfix/main.cf:
TEXT
# Basic settings
myhostname = mail.company.com
mydomain = company.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = all
# Who can receive email
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
# Where to store mail
home_mailbox = Maildir/
# Size limits
message_size_limit = 52428800 # 50MB
mailbox_size_limit = 1073741824 # 1GB per mailbox
# TLS (required for modern email)
smtpd_tls_cert_file = /etc/ssl/certs/mail.company.com.crt
smtpd_tls_key_file = /etc/ssl/private/mail.company.com.key
smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_security_level = may
# SASL Authentication (for outgoing mail)
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
# Restrictions
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
reject_invalid_hostname,
reject_unknown_recipient_domain
smtpd_helo_restrictions =
permit_mynetworks,
reject_invalid_helo_hostname,
reject_non_fqdn_helo_hostnamePostfix Master (services) Configuration
Edit /etc/postfix/master.cf to enable submission port:
TEXT
# SMTP (receiving from internet)
smtp inet n - y - - smtpd
# Submission port 587 (for authenticated clients sending outgoing mail)
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
# SMTPS port 465 (legacy but still used)
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,rejectDovecot IMAP/POP3 Configuration
Edit /etc/dovecot/dovecot.conf:
TEXT
protocols = imap pop3 lmtp
ssl = required
ssl_cert = </etc/ssl/certs/mail.company.com.crt
ssl_key = </etc/ssl/private/mail.company.com.key
ssl_min_protocol = TLSv1.2
# Authentication
auth_mechanisms = plain login
# Where emails are stored
mail_location = maildir:~/Maildir
# LMTP socket for Postfix delivery
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
# Auth socket for Postfix SASL
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
}Anti-Spam with SpamAssassin
BASH
apt install spamassassin spamc
# Enable SpamAssassin
systemctl enable spamassassin
systemctl start spamassassin
# Update rules
sa-update
# Add to postfix main.cf
smtpd_milters = unix:/var/spool/postfix/spamass/spamass.sock
milter_default_action = acceptDNS Records Required
TEXT
# MX record
@ IN MX 10 mail.company.com.
# A record for mail server
mail IN A 203.0.113.10
# SPF
@ IN TXT "v=spf1 mx -all"
# Reverse DNS (PTR) - set via your ISP/datacenter
10.113.0.203.in-addr.arpa IN PTR mail.company.com.Testing
BASH
# Test SMTP connection
telnet mail.company.com 25
# Should see: 220 mail.company.com ESMTP Postfix
# Send test email
echo "Test body" | mail -s "Test Subject" test@example.com
# Check mail queue
postqueue -p
# View mail logs
tail -f /var/log/mail.log
# Test TLS
openssl s_client -starttls smtp -connect mail.company.com:587
# Test authentication
echo -ne 'usernamepassword' | base64
# Then in telnet: AUTH PLAIN <base64_string>Mail Queue Management
BASH
# View queue
postqueue -p
# Flush queue (attempt delivery now)
postqueue -f
# Delete specific message
postsuper -d MSG_ID
# Delete all deferred messages
postsuper -d ALL deferred
# Hold/release messages
postsuper -h MSG_ID
postsuper -H MSG_ID