MTA - Mail Transfer Server

Postfix Logo

Postfix is a free and open-source mail transfer agent (MTA) that routes and delivers electronic mail on a Linux system. It is estimated that around 26% of public mail servers on the internet run Postfix.

Prerequisites

Install Software

$ sudo apt-get install postfix postfix-mysql

On Ubuntu server 20.04 (focal) the installed version is Postfix version 3.4.13, released on June 14, 2020.

Main Configuration

Postfix uses a number of different configuration files, with the /etc/postfix/main.cf being the most important.

The documentation website has a page dedicated to main.cf which includes every possible configuration paramter.

The whole file, as presented below, is also provided for download at /server/config-files/etc/postfix/main-mta.cf here.

General Settings

15# General Mail Server Setttings
16# ------------------------------------------------------------
17
18# Disable backwards-compatibility safety net
19compatibility_level = 2
20
21# What is my domainname?
22mydomain = example.net
23
24# What is my hostname (FQDN)?
25myhostname = mail.${mydomain}
26
27# What domain name do I append to local sender addresses on outbound mail?
28myorigin = charlotte.${mydomain}
29
30# What characters in a recipient address separate users from extensions?
31recipient_delimiter = +-
32
33# Should I refuse mails with non-standard FROM or RCPT address formats?
34strict_rfc821_envelopes = yes
35
36# What trouble do I need to report to a human (postmaster)?
37notify_classes = bounce, 2bounce, data, delay, resource, software
38
39# After how long should I notify if mail-delivery is delayed?
40delay_warning_time = 6h
41confirm_delay_cleared = yes
42
43# Do I need to notify local users of new mail?
44biff = no
45
46# What is the maximum message size (in bytes)?
47# 25 Mebibytes = 26,214,400 Bytes
48message_size_limit = 26214400
49
50# Whats the size limit of mailboxes (in bytes)?
51# 15 Gibibytes = 16,106,127,360 Bytes
52mailbox_size_limit = 16106127360
53
54
55# ------------------------------------------------------------

Trusted networks

56# Trusted (allowed to relay) Networks Maps
57# ------------------------------------------------------------
58
59# Which clients do I trust and will relay mail to other domains?
60mynetworks = cidr:${config_directory}/mynetworks.cidr
61
62
63# ------------------------------------------------------------

Local and Virtual Mailboxes and Aliases Maps

64# Maps for Virtual (Local) Domains, Mailboxes and Aliases
65# ------------------------------------------------------------
66
67# How can I lookup virtual mail-domains hosted here?
68virtual_mailbox_domains = mysql:${config_directory}/sql/virtual-domains.cf
69
70# How do I lookup individual mailbox addresses of virtual mail-domains?
71virtual_mailbox_maps = mysql:${config_directory}/sql/virtual-mailboxes.cf
72
73# Where do I forward messages to root, postmaster or webmaster?
74alias_maps = $alias_database
75
76# How do I lookup aliases of virtual domain mailbox addresses?
77virtual_alias_maps =
78
79    # Lookup table to foward local mail to virtual mailboxes
80    hash:${config_directory}/virtual
81
82    # MySQL query to lookup aliases in hosted domains
83    mysql:${config_directory}/sql/virtual-aliases.cf
84
85
86# ------------------------------------------------------------

Relayed and Outgoing Mail Transport Maps

 87# Relayed and Outgoing Mail Transport Maps
 88# ------------------------------------------------------------
 89
 90# Since our outgoing SMTP servers are also our MX hosts, postfix can look at
 91# our onw MX records in DNS to find out which servers to use for outgoing mail.
 92default_transport = smtp:exmaple.net
 93
 94# Deliver all local mail via LMTP to the Dovecot server
 95virtual_transport = lmtp:unix:private/dovecot-lmtp
 96
 97# More specific transport mapping for individal addresses or doamins
 98transport_maps = hash:${config_directory}/transport
 99
100
101# ------------------------------------------------------------

TCP/IP Protocols Settings

102# TCP/IP Protocols Settings
103#
104# Changes made here need a full server restart:
105#     'sudo systemctl restart postfix.service'
106# ------------------------------------------------------------
107
108# On which interfaces / IP addresses do I listen for inbound connections?
109inet_interfaces =
110
111    # Localhost
112    127.0.0.1, ::1,
113
114    # Private local LAN IPv4 address
115    172.27.88.40,
116
117    # Public global IPv6 address
118    2001:db8:3414:6b1d::40,
119
120    # Private VPN addresses
121    10.195.171.241,
122    fdc1:d89e:b128:6a04::29ab
123
124# Our Firewall/Gateway is doing NAT. What is my external IPv4 address?
125proxy_interfaces = ipv4.home.example.net
126
127
128# ------------------------------------------------------------

General TLS Settings

129# General TLS Settings
130#
131# Ciphers suites to use in different situations.
132# Note: While using non-mandatory opportunistic encryption,
133# its preferable to use bad encryption, then no encrpytion
134# at all.
135# ------------------------------------------------------------
136
137# Generated 2020-12-13, Mozilla Guideline v5.6,
138# Postfix 3.4.13, OpenSSL 1.1.1f, old configuration
139# https://ssl-config.mozilla.org/
140tls_low_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA
141
142# Generated 2020-12-13, Mozilla Guideline v5.6,
143# Postfix 3.4.13, OpenSSL 1.1.1f, intermediate configuration
144# https://ssl-config.mozilla.org/
145tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
146
147# What ciphers suites do I use when I am high?
148# The Postfix built-in defaults are okay here.
149#tls_high_cipherlist = aNULL:-aNULL:HIGH:@STRENGTH
150
151# Should I enable server cipher preferences?
152tls_preempt_cipherlist = yes
153
154# What OpenSSL options do I enable or disable?
155tls_ssl_options =
156    NO_COMPRESSION
157    NO_RENEGOTIATION
158    NO_SESSION_RESUMPTION_ON_RENEGOTIATION
159
160
161# ---------------------------------------------------------

SMTP TLS Client Settings

162# SMTP TLS Client Settings
163# ---------------------------------------------------------
164
165# What DNS lookup methods do I use for outgoing SMTP sessions?
166smtp_dns_support_level = dnssec
167
168# Which default TLS policy applies when connecting to other SMTP servers?
169smtp_tls_security_level = dane-only
170
171# Where do I lookup domain specific TLS policies when sending mail?
172smtp_tls_policy_maps =
173    mysql:${config_directory}/sql/tls-policy.cf
174    socketmap:inet:127.0.0.1:8461:postfix
175
176# Which ciphers I have to exclude for opportunistic TLS policies?
177# (if smtp_tls_security_level is set to "may", "dane")
178smtp_tls_exclude_ciphers = aNULL, eNULL, EXPORT, RC4, DES, SSLv2, MD5
179
180# Which TLS protocols do I use for mandatory TLS policies?
181# (if smtp_tls_security_level is set to "encrypt", "dane-only", "verify", "secure")
182smtp_tls_mandatory_protocols = $smtp_tls_protocols, !TLSv1, !TLSv1.1
183
184# Which cipher list do I use for mandatory TLS policies?
185# (if smtp_tls_security_level is set to "encrypt", "dane-only", "verify", "secure")
186smtp_tls_mandatory_ciphers = high
187
188# Which ciphers I have to exclude for mandatory TLS policies?
189# (if smtp_tls_security_level is set to "encrypt", "dane-only", "verify", "secure")
190smtp_tls_mandatory_exclude_ciphers = ${smtp_tls_exclude_ciphers}, SHA1
191
192# Where are CA files stored to verify TLS certificates?
193smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
194
195# Where do I find trusted CA certificates to verify SMTP server certificates?
196smtp_tls_CApath = /etc/ssl/certs
197
198# Files containing TLS private keys, certificates and issueing intermediate CA
199smtp_tls_chain_files =
200     /etc/dehydrated/certs/postfix/keycertchain.pem
201     /etc/dehydrated/certs/postfix-rsa/keycertchain.pem
202
203# Where do I cache outgoing SMTP TLS sessions?
204smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
205
206# Should I make a note if I encounter servers who offer encryption?
207smtp_tls_note_starttls_offer = yes
208
209# How much of the outgoing TLS transactions should I log?
210smtp_tls_loglevel = 1
211
212
213# ---------------------------------------------------------

SMTPD TLS Server Settings

214# SMTPD TLS Server Settings
215# ---------------------------------------------------------
216
217# Is TLS encryption required for incoming connections?
218# Possible values:
219# 'none', 'may' or ''encrypt
220smtpd_tls_security_level = encrypt
221
222# Do I refuse password authentication over unencrypted connections?
223smtpd_tls_auth_only = yes
224
225# Which TLS protocols do I accept for opportunistic TLS policies?
226# (if smtpd_tls_security_level is set to "may")
227smtpd_tls_protocols = $smtp_tls_protocols
228
229# Which ciphers I don't accept for opportunistic TLS policies?
230# (if smtpd_tls_security_level is set to "may")
231smtpd_tls_exclude_ciphers = $smtp_tls_exclude_ciphers
232
233# Which TLS protocols do I use for mandatory TLS policies?
234# (if smtpd_tls_security_level is set to "encrypt")
235smtpd_tls_mandatory_protocols = $smtp_tls_mandatory_protocols
236
237# Which cipher list do I accept for mandatory TLS policies?
238# (if smtpd_tls_security_level is set to "encrypt")
239smtpd_tls_mandatory_ciphers = $smtp_tls_mandatory_ciphers
240
241# Which ciphers I don't accept for mandatory TLS policies?
242# (if smtpd_tls_security_level is set to "encrypt")
243smtpd_tls_mandatory_exclude_ciphers = $smtp_tls_mandatory_exclude_ciphers
244
245# What security grade do I use for ephemeral elliptic-curve Diffie-Hellman
246# (EECDH) key exchange?
247smtpd_tls_eecdh_grade = ultra
248
249# Where are CA files stored to verify TLS certificates?
250smtpd_tls_CAfile = $smtp_tls_CAfile
251
252# Where do I find trusted CA certificates to verify SMTP server certificates?
253smtpd_tls_CApath = $smtp_tls_CApath
254
255# Where do I get Diffie-Hellmann key-exchange (DHE) parameters from?
256# (for perfect forward secrecy)
257# https://github.com/internetstandards/dhe_groups
258# not actually 1024 bits, this applies to all DHE >= 1024 bits
259smtpd_tls_dh1024_param_file = /etc/ssl/dhe_groups/ffdhe4096.pem
260
261# Files containing TLS private keys, certificates and issueing intermediate CA
262smtpd_tls_chain_files = ${smtp_tls_chain_files}
263
264# Where do I cache incoming SMTP TLS sessions?
265smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
266
267# Should I ask connecting clients for their own certificate?
268smtpd_tls_ask_ccert = yes
269
270# Should I include protocol and cipher used in the "Received:" message headers?
271smtpd_tls_received_header = yes
272
273# How much of the incoming TLS transactions should I log?
274smtpd_tls_loglevel = ${smtp_tls_loglevel}
275
276
277# ---------------------------------------------------------

SMTPD Server User Authentication

278# SMTPD Submission Server SASL Authentication Settings
279# ---------------------------------------------------------
280
281# Which SASL implementation shoudl I use? (default: Cyrus)
282smtpd_sasl_type = dovecot
283
284# Where can I contact the Dovecot authentication server?
285smtpd_sasl_path = private/auth
286
287# Don't let in any strangers,
288# Don't accept plaintext passowrds over unencrypted connections!
289smtpd_sasl_security_options = noanonymous, noplaintext
290
291# Don't let in any strangers over encrypted connections
292smtpd_sasl_tls_security_options = noanonymous
293
294# Do I refuse user authentication over unencrypted connections?
295smtpd_tls_auth_only = yes
296
297# Add the sender's login name to mail message headers.
298smtpd_sasl_authenticated_header = yes
299
300
301# ---------------------------------------------------------

SMTP Server Restrictions

302# SMTPD Server Restrictions
303# ---------------------------------------------------------
304
305# What restrictins apply to connecting clients?
306smtpd_client_restrictions =
307    permit_mynetworks
308    permit_sasl_authenticated
309    reject_unknown_client_hostname
310
311# Are connecting clients required to greet me properly before anything else?
312smtpd_helo_required = yes
313
314# What restrictins apply to SMTP HELO greetings
315smtpd_helo_restrictions =
316    permit_mynetworks
317    reject_invalid_helo_hostname
318    reject_non_fqdn_helo_hostname
319    reject_unknown_helo_hostname
320
321# What restrictins apply to any mail sender address?
322smtpd_sender_restrictions =
323    permit_mynetworks
324    #reject_non_fqdn_sender
325    #reject_unknown_sender_domain
326    reject_unlisted_sender
327    warn_if_reject reject_unverified_sender
328
329# What should I tell clients when their sender address verification fails?
330unverified_sender_reject_reason = Sender address verification failed
331
332# What restrictions apply to relayed mails?
333smtpd_relay_restrictions =
334    permit_mynetworks
335    permit_sasl_authenticated
336    reject_unauth_destination
337
338# What restrictins apply to any mail recipient address?
339smtpd_recipient_restrictions =
340    permit_auth_destination
341    reject_non_fqdn_recipient
342    reject_unauth_destination
343    reject_unknown_recipient_domain
344    reject_unlisted_recipient
345    reject_unverified_recipient
346
347# What restrictins apply to mail content?
348smtpd_data_restrictions = reject_unauth_pipelining
349
350
351# ---------------------------------------------------------

Mail User Agent (MUA) Restrictions

352# Mail User Agent (MUA) Restrictions
353# These will be applied Submission server in master.conf to
354# override the SMTPD server retrictions above for
355# authenticated submission clients only.
356# ---------------------------------------------------------
357mua_client_restrictions =
358    permit_sasl_authenticated
359    permit
360
361mua_helo_restrictions =
362    permit
363
364mua_sender_restrictions =
365    permit
366
367
368# ---------------------------------------------------------

Spam Filters (Milters)

369# Spam Filter (Milter) and DKIM Mail Message Signing
370# ---------------------------------------------------------
371
372# Milters to handle remote incomfing mail that arrives via smtpd(8)
373# Note: UNIX Socket files are relative to '/var/spool/postfix'
374smtpd_milters =
375    unix:/var/spool/postfix/clamav/clamav-milter.ctl
376    #unix:/var/spool/postfix/rspamd/rspamd_proxy.sock
377
378# Milters to handle local mail that arrives via sendmail(1) command-line or
379# qmqpd(8)
380# Note: UNIX Socket files are relative to '/var/spool/postfix'
381non_smtpd_milters =
382    unix:/var/spool/postfix/clamav/clamav-milter.ctl
383    #unix:/var/spool/postfix/rspamd/rspamd_proxy.sock
384
385# Which macros do I have to send to the Rspamd milter?
386milter_mail_macros =  i {mail_addr} {client_addr} {client_name} {auth_authen}
387
388# Default action when a Milter (mail filter) application is unavailable.
389milter_default_action = tempfail
390
391
392# ------------------------------------------------------------
393# SOFT BOUNCE - Set to while debugging delivery issues
394# ------------------------------------------------------------
395#
396# The soft_bounce parameter provides a limited safety net for
397# testing.  When soft_bounce is enabled, mail will remain queued that
398# would otherwise bounce. This parameter disables locally-generated
399# bounces, and prevents the SMTP server from rejecting mail permanently
400# (by changing 5xx replies into 4xx replies). However, soft_bounce
401# is no cure for address rewriting mistakes or mail routing mistakes.
402#
403#soft_bounce = no
404
405#-*- mode: ini; tab-width: 4; indent-tabs-mode:nil  -*-

Map Files and Databases

Postfix uses several maps stored in files to translate things like domains and mail-addresses at runtime. As these maps can be quite large and change often, they are not saved in configuration files, but in map files.

The map files are referenced in the postfix server-configuration. Examples already used above are the mynetowrks, alias_maps or virtual_mailbox_domains above.

Such configuration values usually contain a prefix like cidr:, hash: or mysql:, which tell the server in what type of data store the mapping information is accessible.

If the prefix starts with hash: the map is initially is stored as plain text in the file referenced, but cached later in a hash-database for faster access. A hashed map or database can change anythme while the server is running, unlike configuration values, which are only read when the server reloads or fully restarted.

After every change to any of the map files discussed below, their databases need to be refreshed as follows:

$ cd /etc/postfix && sudo postmap <prefix:>/etc/postfix/<filename>

Alias Map

The file /etc/aliases resides outside of the postifx configuration directory /etc/postifx as it is a standard Linux system file also used by other software packages, besides Postfix.

It contains information on where mails for certain system accounts should be delivered to.

This is needed for notification and warning mails created by system programs (like cronjobs) to reach human beings (like the person responsible for system administration).

Some software packages will add their system accounts to it.

1# See man 5 aliases for format
2postmaster:    root
3clamav: root

The contents of the file are cached in the database /etc/postfix/aliases.db. Because of that the database must be refreshed after each and every change made in /etc/postfix/aliases.map:

$ cd /etc/postfix && sudo postalias

See the manpage aliases(5) for more information.

Virtual Domains Map

We referenced this the file /etc/postfix/sql/virtual-domains.cf in the main configuration file main.cf above as virtual_mailbox_domains. It contains the MariaDB database server connection information and the SQL Query for Postfix to lookup the virtual domains hosted here:

 1#
 2# MySQL connection and query to lookup which mail domains are hosted here
 3#
 4# Note: Postfix can't access UNIX sockets outside of '/var/spool/postfix'
 5# so make sure to use a numerical IP addresses only for 'hosts'!
 6hosts = 127.0.0.1
 7user = postfix
 8password = ****************
 9dbname = vimbadmin
10query = SELECT 1 FROM domain WHERE domain='%s' AND active = '1'

Use the user, password and database defined in Virtual Domains and Mailboxes.

Virtual Mailboxes Map

Same as with the virtual domain map above, the following MySQL connection defined in /etc/postfix/sql/virtual-mailboxes.cf is used to lookup which mailboxes are hosted here:

 1#
 2# MySQL connection and query to lookup which mailboxes are hosted here
 3#
 4# Note: Postfix can't access UNIX sockets outside of '/var/spool/postfix'
 5# so make sure to use a numerical IP addresses only for 'hosts'!
 6hosts = 127.0.0.1
 7user = postfix
 8password = ****************
 9dbname = vimbadmin
10query = SELECT 1 FROM mailbox WHERE username = '%s' AND active = '1'

Note that the only difference to the above one is the SQL query. looking for mailboxes instead of domains.

Virtual Alias Maps

On our MTA server we use two virtual alias maps:

/etc/postfix/virtual contains local system account names and destination mail addresses for these accounts:

 1# *****************************************************************************
 2# virtual - Postfix virtual alias table
 3# *****************************************************************************
 4#
 5# The  optional  virtual(5)  alias table rewrites recipient addresses for
 6# all local, all virtual, and all  remote  mail  destinations.   This  is
 7# unlike  the  aliases(5) table which is used only for local(8) delivery.
 8# This feature is implemented in the  Postfix  cleanup(8)  daemon  before
 9# mail is queued.
10#
11# Virtual  aliasing  is  recursive; to terminate recursion for a specific
12# address, alias that address to itself.
13#
14# Virtual aliasing is applied only to recipient envelope  addresses,  and
15# does  not  affect message headers.  Use canonical(5) mapping to rewrite
16# header and envelope addresses in general.
17#
18# See https://www.postfix.org/virtual.5.html
19#
20# This is a hash-type indexed Postfix lookup table.
21# The Postfix main configuration file /etc/postfix/main.ch includes this file as
22# follows:
23#   virtual_alias_maps = hash:${config_directory}/virtual
24#
25# Update the database after changing this file with the following commands:
26#   $ cd /etc/postfix
27#   $ sudo postmap virtual
28# *****************************************************************************
29
30# Redirect mail for local users of this host to example.net
31abuse       abuse@example.net
32clamav      admin@example.net
33daemon      admin@example.net
34hostmaster  hostmaster@example.net
35list        postmaster@example.net
36postmaster  postmaster@example.net
37root        admin@example.net
38security    admin@example.net
39support     admin@example.net
40webmaster   webmaster@example.net
41john        john@alainwolf.ch
42www-data    webmaster@example.net
43
44#-*- mode: ini; tab-width: 4; indent-tabs-mode:nil  -*-

/etc/postfix/sql/virtual-aliases.cf contains the SQL server connection information and SQL query lookup mailbox aliases at the MySQL database server:

 1#
 2# MySQL connection and query to lookup mail-address aliase and their mailbox
 3#
 4# Note: Postfix can't access UNIX sockets outside of '/var/spool/postfix'
 5# so make sure to use a numerical IP addresses only for 'hosts'!
 6hosts = 127.0.0.1
 7user = postfix
 8password = ****************
 9dbname = vimbadmin
10query = SELECT goto FROM alias WHERE address = '%s' AND active = '1'

TLS Policy Maps

The /etc/postfix/sql/tls-policy.cf file :

1hosts = 127.0.0.1
2user = postfix
3password = ****************
4dbname = vimbadmin
5query = SELECT policy, params FROM tlspolicies WHERE domain = '%s'

Master Process Configuration

Postfix consists of many daemons and utilities, some running all the time and others started when needed. The /etc/postfix/master.cf confiugration file is the centralized control center from where the Postfix master process gets his guidelines on what, when and how all these programs have to be started.

Where no command-line options are specified, the program uses relevant configuration values from the main.cf configuration file. Alternatively options can be overridden by command-line parameters like -o.

The official documentation website provides a manual page online.

The whole file, as presented below, is also provided for download at /server/config-files/etc/postfix/master.cf here.

Standard SMTP Dameon

The first daemon specified here is the SMTP daemon smtpd which runs on the dedicated SMTP TCP port 25, it is enabled by default:

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
smtp      inet  n       -       y       -       -       smtpd

Postscreen SMTP Firewall

The postscreen damon on the second line is a daemon which runs a mininmal SMTP subset to perform some compliance tests on incoming SMTP client connections. If the client passes all tests he gets whitelistet and the connection is passed along to the real SMTP server running behind it. That is what the second line above is for. An smtpd daemon that takes over connections from postscreen only. The tlsproxy handles TLS encryption for postscreen and dnsblog does the DNS blacklist lookups.

Since we use the Rspamd milter to separate legitimate from undesired SMTP connections, the postscreen line can be commented out.

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
#smtp     inet  n       -       y       -       1       postscreen
#  -o smtpd_sasl_auth_enable=no

Internal Postfix SMTP Daemon

If the conneting SMTP client has passed all the checks performed by postscreen, the client IP address is temporarely whitelisted.

If possible the TCP connection is then handed over to the SMTPD daemon internally (that is what the “pass” keyword means).

Sometimes this is not possible, depeneding on the checks. If the client had to start already some message delivery in order to complete a check, the connection can not be handed over to a new SMTP server, as this would confuse the SMTP client who is already in the middle of a message delivery. In this case, postscreen will tell the connecting SMTP client to abort message delivery for now and try again later. If the same client connects again later, it will be already whitelisted and then the connection is “passed” directly to the postfix SMTP daemon.

Since we don’t use postscreen, this daemon can be disabled by commenting out the line.

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
#smtpd    pass  -       -       y       -       -       smtpd

DNS Blacklist & Whitelist Lookup

The dnsblog is a helper service for the postscreen SMTP firewall to lookup, if connecting hosts are found in any of configured the DNS blacklists or whitelists.

Since we use the Rspamd milter to separate legitimate from undesired SMTP connections, the dnsblog line can be commented out.

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
#dnsblog  unix  -       -       y       -       0       dnsblog

TLS Proxy

It is used by postscreen server to handle TLS connections with inbound SMTP client connections and by the local smtp client to support TLS connection reuse.

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
tlsproxy   unix  -      -       y       -       0       tlsproxy

Submission Daemon

The submission daemon is a SMTP daemon listening on TCP port 587 for mail user agents (MUAs aka mail clients like Thunderbird or Outlook) of authorized users to connecting and submit their outgoing mail.

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
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=$mua_client_restrictions
  -o smtpd_helo_restrictions=$mua_helo_restrictions
  -o smtpd_sender_restrictions=$mua_sender_restrictions
  -o smtpd_recipient_restrictions=
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

The connecting MUA is required to initialize TLS encryption of the connection with the STARTTLS command before anything else. This controlled by the “smtpd_tls_security_level=encrypt” option.

The following options enable user authentication over encrypted connections and various settings to allow mail from authenticated and authorized users to be sent anywhere.

The last options, marks the submitted mail messages as our own, to be handles accordingly by our spam filters.

SMTPS Daemon

The SMTPS daemon is very simliar to the submission daemon. The difference being, it runs on TCP port 465 and connections are already encrypted, therefore no STARTTLS is required.

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
smtps      inet  n       -       y       -       -      smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_reject_unlisted_recipient=no
  -o smtpd_client_restrictions=$mua_client_restrictions
  -o smtpd_helo_restrictions=$mua_helo_restrictions
  -o smtpd_sender_restrictions=$mua_sender_restrictions
  -o smtpd_recipient_restrictions=
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

Other Postfix Daemons and Programs

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
#628      inet  n       -       -       -       -       qmqpd
pickup    unix  n       -       -       60      1       pickup
cleanup   unix  n       -       -       -       0       cleanup
qmgr      unix  n       -       n       300     1       qmgr
#qmgr     unix  n       -       n       300     1       oqmgr
tlsmgr    unix  -       -       -       1000?   1       tlsmgr
rewrite   unix  -       -       -       -       -       trivial-rewrite
bounce    unix  -       -       -       -       0       bounce
defer     unix  -       -       -       -       0       bounce
trace     unix  -       -       -       -       0       bounce
verify    unix  -       -       -       -       1       verify
flush     unix  n       -       -       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       -       -       -       smtp
relay     unix  -       -       -       -       -       smtp
#       -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq     unix  n       -       -       -       -       showq
error     unix  -       -       -       -       -       error
retry     unix  -       -       -       -       -       error
discard   unix  -       -       -       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       -       -       -       lmtp
anvil     unix  -       -       -       -       1       anvil
scache    unix  -       -       -       -       1       scache
#
# ==========================================================================
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.

qmqpd - QMQP (Quick Mail Queueing Protocol) daemon. A mail protocol orginally devloped by Daniel J. Bernstein as part of QMAIL. Disabled.

pickup - Postfix local mail pickup. The pickup(8) daemon waits for hints that new mail has been dropped into the maildrop directory, and feeds it into the cleanup(8) daemon.

cleanup - canonicalize and enqueue Postfix message. The cleanup(8) daemon processes inbound mail, inserts it into the incoming mail queue, and informs the queue manager of its arrival.

qmgr - Postfix queue manager. The qmgr(8) daemon awaits the arrival of incoming mail and arranges for its delivery via Postfix delivery processes. The actual mail routing strategy is delegated to the trivial-rewrite(8) daemon.

oqmgr - old Postfix queue manager. Disabled.

tlsmgr - Postfix TLS session cache and PRNG manager. The tlsmgr(8) manages the Postfix TLS session caches. It stores and retrieves cache entries on request by smtpd(8) and smtp(8) processes, and periodically removes entries that have expired.

trivial-rewrite - Postfix address rewriting and resolving daemon. The trivial-rewrite(8) daemon processes three types of client service requests:

  1. rewrite context address - Rewrite an address to standard form, according to the address rewriting context (local or remote).

  2. resolve sender address - Resolve the address to a (transport, nexthop, recipient, flags) quadruple.

  3. verify sender address - Resolve the address for address verification purposes.

bounce - Postfix delivery status reports. Maintains per-message log files with delivery status information.

verify - Postfix address verification server. Maintains a record of what recipient addresses are known to be deliverable or undeliverable.

flush - Postfix fast flush server. Maintains a record of deferred mail by destination. This information is used to improve the performance of the SMTP ETRN request, and of its command-line equivalent, “sendmail -qR” or “postqueue -f”.

proxymap - Postfix lookup table proxy server. Provides read-only or read-write table lookup service to Postfix processes. These services are implemented with dis- tinct service names: proxymap and proxywrite, respectively. The purpose of these services is:

  • Overcome chroot restrictions.

  • Consolidate the number of open lookup tables, by open connections and files.

  • Provide write access to tables, who don’t support more than one simultanious write access.

showq - list the Postfix mail queue. Reports the Postfix mail queue status. The output is meant to be formatted by the postqueue(1) command, as it emulates the Sendmail mailq command.

error - Postfix error/retry mail delivery agent. Processes delivery requests from the queue manager. Each request specifies a queue file, a sender address, the reason for non-delivery (specified as the next-hop destination), and recipient information.

discard - Postfix discard mail delivery agent. Processes delivery requests from the queue manager. Each request specifies a queue file, a sender address, a next-hop destination that is treated as the reason for dis- carding the mail, and recipient information.

local - Postfix local mail delivery. Processes delivery requests from the Postfix queue manager to deliver mail to local recipients. Each delivery request specifies a queue file, a sender address, a domain or host to deliver to, and one or more recipients.

virtual - Postfix virtual domain mail delivery agent. Designed for virtual mail hosting services. Originally based on the Postfix local(8) delivery agent, this agent looks up recipients with map lookups of their full recipient address, instead of using hard-coded unix password file lookups of the address local part only.

anvil - Postfix session count and request rate control. Maintains statistics about client connection counts or client request rates.

scache - Postfix shared connection cache server. Maintains a shared multi-connection cache. This information can be used by, for example, Postfix SMTP clients or other Postfix delivery agents.

submission-header-cleanup

postlog - Postfix-compatible logging utility. Implements a Postfix-compatible logging interface for use in, for example, shell scripts.

By default, postlog(1) logs the text given on the command line as one record. If no text is specified on the command line, postlog(1) reads from standard input and logs each input line as one record.

By default, logging is sent to syslogd(8) or postlogd(8); when the standard error stream is connected to a terminal, logging is sent there as well.

Systemd Service Dependencies

Our Postfix MTA depends on various other services, we want to ensure that Postfix is always able to connect to them while running:

  • Wireguard VPN network interface

  • MariaDB database server

  • Rspamd Spam Filter

  • ClamAV virus scanner

  • Postfix MTA-STS resolver

The Systemd services file for the Postfix server /lib/systemd/system/postfix@.service is created as part of the software package installation. The recommended method is to create a Systemd override-file and not change anything in the provided service file, as it would be lost on software package updates.

You can create a override file easily with the help of the systemctl command:

$ sudo systemctl edit postfix@.service

This will start your editor with an empty file, where you can add your own custom Systemd service configuration options.

[Unit]
After=sys-devices-virtual-net-wg0.device
After=mariadb.service rspamd.service clamav-daemon.service postfix-mta-sts-resolver.service
BindsTo=sys-devices-virtual-net-wg0.device mariadb.service

The configuration statement After=mariadb.service ensures that mariadb.service is fully started up before the postfix@.service is started.

The line BindsTo=mariadb.service ensures that if the Database service is stopped, the PowerDNS server will be stopped too.

After you save and exit of the editor, the file will be saved as /etc/systemd/system/postfix@.service.d/override.conf and Systemd will reload its configuration:

systemctl show postfix@.service |grep -E "After=|BindsTo="

References