Server administration Setting Up a Mail Server from Scratch – Part 3: Postfix Configuration

  • Thread starter D•Jass
  • Start date
  • Tags
    server
D•Jass

D•Jass

Staff member
Verified
  • #1

Postfix Configuration for Virtual Domains​

Postfix is our Mail Transfer Agent (MTA). We'll configure it to work with virtual domains and users stored in a database, as well as integrate it with Dovecot and OpenDKIM.

3.1. Main Configuration File: /etc/postfix/main.cf​

Replace the contents of the file or adjust the listed parameters:
Hostname and domain (replace example.com with your domain)
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain

Network settings
inet_interfaces = all
inet_protocols = ipv4

Where to deliver local mail (for system users)
mydestination = localhost

Mailbox format
home_mailbox = Maildir/

TLS settings (paths will be valid after obtaining certificate)
smtpd_tls_cert_file = /etc/postfix/ssl/fullchain.pem
smtpd_tls_key_file = /etc/postfix/ssl/privkey.pem
smtpd_use_tls = yes
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes

Outgoing TLS settings (recommended)
smtp_tls_security_level = may
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

SASL authentication via Dovecot
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous

Recipient restrictions (basic)
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
permit

Milter (DKIM signing)
milter_protocol = 6
milter_default_action = accept
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters

Virtual domains and users via MySQL
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf

Other recommended settings
message_size_limit = 52428800

mailbox_size_limit = 0
disable_vrfy_command = yes

3.2. SQL Mapping Files for Postfix​

Important: In the files below, replace StrongPostfixPass with the password of the postfix_admin MariaDB user.
/etc/postfix/mysql-virtual-mailbox-domains.cf
user = postfix_admin
password = StrongPostfixPass
hosts = 127.0.0.1
dbname = postfix_accounts
query = SELECT DomainName FROM domains_table WHERE DomainName='%s' AND IsActive = TRUE

/etc/postfix/mysql-virtual-mailbox-maps.cf
user = postfix_admin
password = StrongPostfixPass
hosts = 127.0.0.1
dbname = postfix_accounts
query = SELECT 1 FROM accounts_table WHERE Email='%s' AND IsActive = TRUE

/etc/postfix/mysql-virtual-alias-maps.cf
user = postfix_admin
password = StrongPostfixPass
hosts = 127.0.0.1
dbname = postfix_accounts
query = SELECT Destination FROM alias_table WHERE Source='%s' AND IsActive = TRUE

Set secure permissions for these files:
chown root:postfix /etc/postfix/mysql-.cf
chmod 640 /etc/postfix/mysql-.cf

3.3. Service Configuration File: /etc/postfix/master.cf​

Edit or add the following sections to control how Postfix services behave:
==========================================================================
service type private unpriv chroot wakeup maxproc command + args
==========================================================================
smtp inet n - y - - smtpd

Submission port (587) for client email sending with TLS and SASL
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_sasl_security_options=noanonymous
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_sender_restrictions=reject_sender_login_mismatch
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject_unauth_destination,reject

-o header_checks=pcre:/etc/postfix/submission_header_checks
SMTPS port (465) - legacy but still used by some clients
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_sender_restrictions=reject_sender_login_mismatch
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject_unauth_destination,reject

Dovecot LMTP over Unix socket
dovecot unix - n n - - lmtp

Optional LMTP timeouts
-o lmtp_connect_timeout=5s
-o lmtp_data_done_timeout=600s
Standard Postfix services (typically unchanged)
pickup unix n - y 60 1 pickup
cleanup unix n - y - 0 cleanup
qmgr unix n - n 300 1 qmgr
tlsmgr unix - - y 1000? 1 tlsmgr
rewrite unix - - y - - trivial-rewrite
bounce unix - - y - 0 bounce
defer unix - - y - 0 bounce
trace unix - - y - 0 bounce
verify unix - - y - 1 verify
flush unix n - y 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxywrite
smtp unix - - y - - smtp
relay unix - - y - - smtp
showq unix n - y - - showq
error unix - - y - - error
retry unix - - y - - error
discard unix - - y - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - y - - lmtp
anvil unix - - y - 1 anvil
scache unix - - y - 1 scache

3.4. Reloading Postfix​

Apply all changes:
# Check configuration
postfix check

Reload configuration
systemctl reload postfix

Or fully restart if needed
systemctl restart postfix

Verify that Postfix is listening on the correct ports (25, 587, 465):
ss -tulnp | grep -E ':(25|465|587)\b'
 
Top