LINUXOR.SK ... open source notes ...

Email - Postfix main.cf, internal servers

category: solutionz · date: 2019-12-31 · updated: 2026-10-02 · author: LALA

Email Solution · Config document · referenced from Internal servers: Postfix

noteTwo things in this file do not do what their comments say: reject_sender_login_mismatch is placed after a lookup that already permits every legitimate sender, and the TLS block still names 512-bit and 1024-bit Diffie-Hellman files. Read the Article before copying any of it.

The global Postfix configuration of the internal pair: identity, routing to the mailbox server and to the relays, SASL through Dovecot, the three restriction lists that separate internal-only senders from senders allowed to reach the internet, TLS and the hardening block. The file started as the distribution's main.cf; the stock comments of its upper half are left out here, the section banners, every active line and all of my own comments are kept. CFG-ON marks a setting I turned on.

ItemValue
Path on the server/etc/postfix/main.cf
Shown hereDC2-A-VCMSX001, the Keepalived master of the internal pair in site 2
Also onDC2-B-VCMSX001 (differences below); DC2-A-VCMSX002 has its own variant, see Postfix main.cf, mailbox server
SoftwarePostfix 2.10.1 from the RHEL 7 repository
Activated withpostfix reload; a change of inet_interfaces needs a stop and start, as the stock comment says
Check withpostconf -n, which the first design used to print the running configuration

The file

ini
######################################################################
# LOCAL PATHNAME INFORMATION
######################################################################
queue_directory = /var/spool/postfix

command_directory = /usr/sbin

daemon_directory = /usr/libexec/postfix

data_directory = /var/lib/postfix

######################################################################
# QUEUE AND PROCESS OWNERSHIP
######################################################################
mail_owner = postfix

######################################################################
# INTERNET HOST AND DOMAIN NAMES
######################################################################
myhostname = dc2-a-vcmsx001.adm.example.net

mydomain = ad-dc2.example.net

######################################################################
# SENDING MAIL
######################################################################
myorigin = $mydomain

######################################################################
# RECEIVING MAIL
######################################################################
inet_interfaces = all

# Enable IPv4, and IPv6 if supported
inet_protocols = all

# Bind to cluster VIP address (IPv4)
smtp_bind_address = 10.12.19.33

# Bind to cluster VIP address (IPv6)
smtp_bind_address6 = 2001:db8:a2:b6f::f:1

mydestination = $myhostname, localhost.$mydomain, localhost

######################################################################
# REJECTING MAIL FOR UNKNOWN LOCAL USERS
######################################################################
unknown_local_recipient_reject_code = 550

######################################################################
# ALIAS DATABASE
######################################################################
alias_maps = hash:/etc/aliases

alias_database = hash:/etc/aliases

######################################################################
# DELIVERY TO MAILBOX
######################################################################
home_mailbox = Maildir/

######################################################################
# SHOW SOFTWARE VERSION OR NOT
######################################################################
smtpd_banner = $myhostname ESMTP

######################################################################
# DEBUGGING CONTROL
######################################################################
debug_peer_level = 2

debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         ddd $daemon_directory/$process_name $process_id & sleep 5

######################################################################
# INSTALL-TIME CONFIGURATION INFORMATION
######################################################################
sendmail_path = /usr/sbin/sendmail.postfix

newaliases_path = /usr/bin/newaliases.postfix

mailq_path = /usr/bin/mailq.postfix

setgid_group = postdrop

html_directory = no

manpage_directory = /usr/share/man

sample_directory = /usr/share/doc/postfix-2.10.1/samples

readme_directory = /usr/share/doc/postfix-2.10.1/README_FILES

######################################################################
# TRANSPORT
######################################################################
# Definition of transports
transport_maps = hash:/etc/postfix/transport
dovecot_destination_recipient_limit = 1

######################################################################
# RELAYHOST (SMARTHOST)
######################################################################
# Definition of relayhost
relayhost = [10.12.19.34]

# Definition of backup relayhost
smtp_fallback_relay = [10.12.19.35]

######################################################################
# SASL
######################################################################
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous

######################################################################
# RESTRICTIONS
######################################################################
# Definition of mynetworks
mynetworks = 10.12.19.34/32, 10.12.19.35/32, 10.12.19.43/32

# AD users which are in the AD group "ESMTP_ACCESS" are allowed to send emails to external domains (ad_allow_external_emails.cf).
# Others AD users in domain "ad-dc2.example.net" are not allowed to send emails to external domains (restricted_senders).
# Authenticated users are allowed to send emails (permit_sasl_authenticated).
smtpd_recipient_restrictions =
        reject_non_fqdn_recipient,
        reject_unknown_recipient_domain,
        check_sender_access ldap:/etc/postfix/ad_allow_external_emails.cf,
        check_sender_access hash:/etc/postfix/restricted_senders,
        permit_sasl_authenticated,
        permit_mynetworks,
        reject_unauth_destination,
        reject

smtpd_client_restrictions=
        permit_sasl_authenticated,
        permit_mynetworks,
        reject

# AD users which are in the AD group "SMTP_ACCESS" are allowed to send emails to internal domains (ad_allow_internal_emails.cf).
# Using email address (MAIL FROM) which is different from login credentials (user@domain) is not allowed (reject_sender_login_mismatch).
smtpd_sender_restrictions=
        check_sender_access ldap:/etc/postfix/ad_allow_internal_emails.cf,
        permit_mynetworks,
        reject_sender_login_mismatch,
        reject

# RESTRICTION CLASSES
smtpd_restriction_classes = local_only
local_only = check_recipient_access hash:/etc/postfix/virtual_domains, reject

######################################################################
# NOTIFICATION
######################################################################

# Configure NDR (NonDeliveryReports) to by sent to specific email address
#notify_classes = resource, software, bounce
#bounce_notice_recipient = customerportal@example.net

######################################################################
# VIRTUAL DOMAINS, USERS, MAILBOXES, GROUPS
######################################################################

# Valid virtual domains
virtual_mailbox_domains = hash:/etc/postfix/virtual_domains

# LDAP (Active Directory) users/senders
smtpd_sender_login_maps = proxy:ldap:/etc/postfix/ad_sender_login_maps.cf

# LDAP (Active Directory) mailboxes
virtual_mailbox_maps = proxy:ldap:/etc/postfix/ad_virtual_mailbox_maps.cf

# LDAP (Active Directory) lists/groups
virtual_alias_maps = proxy:ldap:/etc/postfix/ad_virtual_group_maps.cf

######################################################################
# TLS
######################################################################

# Enable TLS (required to encrypt the plaintext SASL authentication)
smtpd_tls_security_level = encrypt

# Only offer SASL in a TLS session
smtpd_tls_auth_only = yes

# Certification Authority
# smtpd_tls_CAfile = /etc/postfix/ssl/ca.cer

# Public Certificate
smtpd_tls_cert_file = /etc/pki/tls/certs/dc2-a-vcmsx001.adm.example.net.crt

# Private Key (without passphrase)
smtpd_tls_key_file = /etc/pki/tls/private/dc2-a-vcmsx001.adm.example.net.key

# Randomizer for key creation
tls_random_source = dev:/dev/urandom

# TLS related logging (set to 2 for debugging)
smtpd_tls_loglevel = 0

# Avoid Denial-Of-Service-Attacks
smtpd_client_new_tls_session_rate_limit = 10

# Activate TLS Session Cache
smtpd_tls_session_cache_database = btree:/etc/postfix/smtpd_session_cache

# Deny some TLS-Ciphers
smtpd_tls_exclude_ciphers =
        EXP
        EDH-RSA-DES-CBC-SHA
        ADH-DES-CBC-SHA
        DES-CBC-SHA
        SEED-SHA

# Diffie-Hellman Parameters for Perfect Forward Secrecy
# Can be created with:
# openssl dhparam -2 -out dh_512.pem 512
# openssl dhparam -2 -out dh_1024.pem 1024
# openssl dhparam -2 -out dh_2048.pem 2048
smtpd_tls_dh512_param_file = /etc/pki/tls/certs/dh_512.pem
smtpd_tls_dh1024_param_file = /etc/pki/tls/certs/dh_1024.pem

######################################################################
# HARDENING
######################################################################

# CFG-ON  -> Disable the SMTP VRFY command. This stops some techniques used to harvest email addresses.
disable_vrfy_command=yes

# CFG-ON  -> Require that a remote SMTP client sends HELO or EHLO before commencing a MAIL transaction.
smtpd_helo_required=yes

# CFG-ON  -> Limit Denial of Service Attacks
default_process_limit = 100
smtpd_client_connection_count_limit = 10
smtpd_client_connection_rate_limit = 30
queue_minfree = 31457280
header_size_limit = 51200
message_size_limit = 20971520
smtpd_recipient_limit = 100

# CFG-ON  -> Require that addresses received in SMTP MAIL FROM and RCPT TO commands are enclosed
# CFG-ON  -> with <>, and that those addresses do not contain RFC 822 style comments or phrases.
strict_rfc821_envelopes = yes

# CFG-ON  -> Reject the request when the client sends SMTP commands ahead of time where it is
# CFG-ON  -> not allowed, or when the client sends SMTP commands ahead of time without knowing that
# CFG-ON  -> Postfix actually supports ESMTP command pipelining. This stops mail from bulk mail
# CFG-ON  -> software that improperly uses ESMTP command pipelining in order to speed up deliveries.
smtpd_data_restrictions = reject_unauth_pipelining

# CFG-ON  -> List of commands that cause the Postfix SMTP server to immediately terminate the
# CFG-ON  -> session with a 221 code.
smtpd_forbidden_commands = CONNECT,GET,POST,USER,PASS

# CFG-ON  -> Appending .domain is the MUA's job.
append_dot_mydomain = no

# CFG-ON  -> Turning off SSLv2 / v3 due to the DROWN attack
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
smtp_tls_protocols = !SSLv2, !SSLv3

lmtp_tls_mandatory_protocols = !SSLv2, !SSLv3
lmtp_tls_protocols = !SSLv2, !SSLv3

smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
smtpd_tls_protocols = !SSLv2, !SSLv3

# CFG-ON  -> Enable using TLS if remote server supports it
smtp_tls_security_level = may

# CFG-ON (26.11.2018)
# Set the maximal number of recipients per message delivery for transport "bash-encrypt-content-filter".
# Setting this parameter to a value of 1 affects email deliveries as follows:
# - It changes the meaning of the corresponding per-destination concurrency limit, from concurrency
#   of deliveries to the same domain into concurrency of deliveries to the same recipient. Different
#   recipients are delivered in parallel, subject to the process limits specified in master.cf.
# - It changes the meaning of the corresponding per-destination rate delay, from the delay between
#   deliveries to the same domain into the delay between deliveries to the same recipient. Again,
#   different recipients are delivered in parallel, subject to the process limits specified in master.cf.
# - It changes the meaning of other corresponding per-destination settings in a similar manner, from
#   settings for delivery to the same domain into settings for delivery to the same recipient.
#
# REF1: http://www.postfix.org/postconf.5.html#default_destination_recipient_limit
# REF2: http://www.postfix.org/postconf.5.html#transport_destination_recipient_limit
bash-postfix-encrypt-filter_destination_recipient_limit=1

Differences on the other hosts

diff between node A and node B shows the lines below plus white space: node B indents the restriction lists with tabs where node A uses spaces, and carries trailing blanks on a few comment lines.

HostLineValue
DC2-B-VCMSX001myhostnamedc2-b-vcmsx001.adm.example.net
DC2-B-VCMSX001mydomainad.example.net, the mail domain of site 1, where node A has ad-dc2.example.net
DC2-B-VCMSX001comment above smtpd_recipient_restrictionsnames the domain ad.example.net
DC2-B-VCMSX001smtpd_tls_cert_file/etc/pki/tls/certs/dc2-b-vcmsx001.adm.example.net.crt
DC2-B-VCMSX001smtpd_tls_key_file/etc/pki/tls/private/dc2-b-vcmsx001.adm.example.net.key

The mydomain of node B is a leftover of the site 1 configuration the file was copied from. Through myorigin = $mydomain it gives mail posted locally on node B, and addresses without a domain, the site 1 domain. The tables virtual_domains, restricted_senders and transport name the site 2 domain literally on both nodes, so mail arriving over SMTP is treated the same on both.

The third internal server uses the same file with these changes; its complete file is a Config document of its own.

HostLineValue
DC2-A-VCMSX002myhostnamedc2-a-vcmsx002.adm.example.net
DC2-A-VCMSX002smtp_bind_address, smtp_bind_address6not present
DC2-A-VCMSX002relayhost[10.12.19.41]
DC2-A-VCMSX002smtp_fallback_relay[10.12.19.42]
DC2-A-VCMSX002mynetworks10.12.19.33/32, 10.12.19.34/32, 10.12.19.35/32, 10.12.19.41/32, 10.12.19.42/32
DC2-A-VCMSX002comment above smtpd_recipient_restrictionsnames the domain ad.example.net
DC2-A-VCMSX002smtpd_tls_cert_file, smtpd_tls_key_filethe files of dc2-a-vcmsx002.adm.example.net
DC2-A-VCMSX002bash-postfix-encrypt-filter_destination_recipient_limitnot present, with its comment block

Checked against Postfix 3.11

As builtToday
Postfix 2.10.1 on RHEL 7current stable release is Postfix 3.11.7 (September 2026); RHEL 7 maintenance ended on 30 June 2024
no compatibility_level (did not exist)introduced in 3.0; with a level below the built-in one Postfix logs that it uses backwards-compatible defaults
all relay control in smtpd_recipient_restrictions; smtpd_relay_restrictions not setsmtpd_relay_restrictions (since 2.10) defaults to permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination and is the preferred place for relay permission rules; the lists as built still work
reject_sender_login_mismatch, smtpd_sender_login_maps, smtpd_restriction_classesall still valid with the same meaning
smtpd_sasl_type = dovecot, smtpd_sasl_path = private/authstill the documented way to use Dovecot SASL
hash: for transport_maps, virtual_mailbox_domains, restricted_senders, alias_maps; btree: for the TLS session cacheRHEL 10 no longer provides the Berkeley DB libraries; the default table type of its Postfix is lmdb: and existing tables have to be converted. Postfix 3.11 describes the migration in NON_BERKELEYDB_README
smtpd_tls_protocols = !SSLv2, !SSLv3 and the five sibling linesthe exclusion syntax is still accepted; the preferred form is a lower bound such as >=TLSv1.2. As built, TLS 1.0 and 1.1 are still allowed
smtpd_tls_dh512_param_filesilently ignored since 3.6: export-grade Diffie-Hellman is no longer supported
smtpd_tls_dh1024_param_filedeprecated, with a warning since 3.9: do not specify
smtpd_tls_cert_file, smtpd_tls_key_filestill valid; since 3.4 smtpd_tls_chain_files is the preferred way
smtpd_tls_exclude_ciphers with five namesstill valid; the documentation says not to exclude ciphers unless it is essential
smtpd_tls_auth_only = yes next to encryptstill valid; redundant on port 25 but harmless
smtp_tls_security_level = maystill valid; it is the default from 3.11 on
smtpd_data_restrictions = reject_unauth_pipeliningstill valid; since 3.9 smtpd_forbid_unauth_pipelining = yes is the default and disconnects such clients
smtpd_forbidden_commands = CONNECT,GET,POST,USER,PASSstill valid; the default since 3.7 is CONNECT GET POST plus a pattern for lines that do not start with a capital letter
no setting for bare newlines (did not exist)smtpd_forbid_bare_newline defaults to normalize since 3.9, a defence against SMTP smuggling
append_dot_mydomain = nothe default since 3.0
relayhost, smtp_fallback_relay, smtp_bind_addressall still valid; smtp_bind_address_enforce exists since 3.7
bash-postfix-encrypt-filter_destination_recipient_limit=1per-transport recipient limits are still valid

Nothing in the file stops a current Postfix from starting except the Berkeley DB tables on a system without that library, but the TLS block has aged most: one of its parameters is ignored, one is deprecated, and the protocol lists permit versions that should be gone. The table types are the part that needs work on a current distribution.

← solutionz