The upstream postfix documentation is detailed and well maintained. It is
provided in the postfix-doc package. This README supplements the upstream
documentation and provides information on Debian specific differences.
Note: This file is work-in-progress, being reviewed.
Notes about extra map types
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some map types with external dependencies, namely cdb, ldap, mysql, pcre,
pgsql, sqlite, are shipped in Debian in separate packages. For example, to
use cdb: map, please install postfix-cdb package.
When you run Postfix chrooted and use certain network-based map types, notable
ldap, mysql, pgsql, especially when also using TLS, please consider proxying
map access through proxymap(8) service which is designed for this very purpose.
So instead of "ldap:users.cf", use "proxy:ldap:users.cf", - this avoids issues
with missing files in chroot. See man:proxymap(8) for more details.
Controlling chroot
~~~~~~~~~~~~~~~~~~
Postfix has an excellent security track. However it additionally allows one to
run most its components confined in a chroot jail in its queue directory. This
is an advanced security measure to lessen possible damage in case any component
is ever compromised. However this security measure comes with its own costs.
Postfix in Debian is installed chrooted by default, which means extra actions
might be required to implement some configurations. However, there's a simple
Debian-specific sub-command for the `postfix' command, which can be used to
change Postfix mail system to run chrooted or not. It operates on services
which are known to be able to run chrooted:
postfix chroot [-n] on -- set services in master.cf to run chrooted
postfix chroot [-n] off -- set services in master.cf to run without chroot
postfix chroot [query] -- display chroot status (on|off|mixed)
When -n option is specified, the script will not perform any changes but will
show the actual command to perform the necessary changes, if any. This command
can be run manually to chroot or un-chroot all listed or some specific services.
The Postfix chroot feature is supposed to help only in cases where other
aspects of system security are already addressed. In order to do this, one
have to understand security by heart, just installing a Debian system with
default settings is not enough. Due to this, running Postfix services chrooted
is usually overkill. It is strongly recommended that you turn off chroot
feature in Postfix as shipped in Debian, if you can not solve a problem which
is related to running Postfix chrooted. For this, run:
# postfix chroot off
# postfix reload
Postfix and Systemd
~~~~~~~~~~~~~~~~~~~
Systemd is a service manager, it tracks which service is running and not,
service dependencies and so on. Postfix upstream documentation states to
run `postfix start' from command line to start postfix. However this way,
in upstream postfix, runs the mail system within user service context, it
is basically hidden from the service manager, it is completely unaware of
an instance started this way. Postfix in Debian comes with simple change
modification which redirects manual `postfix start' command to systemd
service startup, so that the service manager is aware of the service startup
and keeps track of it. So on Debian system, starting postfix using
`systemctl start postfix' or traditional `postfix start' does the same, -
both starts a service within systemd context.
Multiple Postfix instances under systemd
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Postfix supports additional, non-default, instances of the mail system.
Under Debian, the postfix postmulti(8) tool is not used to manage multiple
Postfix instances. Instead, a simpler systemd-based scheme is used.
Each instance INST should have its config directory named as /etc/postfix-INST,
and the systemd service becomes postfix@INST.service. You can use the
postmulti(8) tool to create initial subdirectories (in postmulti world, the
instance name will be postfix-INST, not INST), and manually enable
postfix@INST.service using systemctl, - this way, this instance will be started
at boot automatically.
Other config directory naming is not supported by the Debian systemd unit
files for Postfix. Additionally, instance name specified in
multi_instance_name parameter in main.cf is not used to refer to a given
instance, only the path component is. So you might have different systemd
service naming and postfix log prefix.
When you run `systemctl stop postfix' or `systemctl reload postfix', all
instances of postfix are stopped or reloaded. To control individual instance,
please refer to individual postfix@INST.service. There's no way to stop or
restart just the main instance without stopping all other instances, since
the action for main instance propagates to all instances.
Instance names specified within main.cf in the config directory (using
multi_instance_name) are not used, only path-based naming is in effect.
On previous Debian releases, this worked differently: default Postfix instance
were named postfix@-.service (which is gone in postfix 3.9.1-7), and other
non-default instances were named after multi_instance_name parameter in their
main.cf. This does not work easily with systemd, because there is no good way
to map from instance name to postfix config directory and back. This scheme
is also gone in 3.9.1-7 version of the package. Using path-based instance
naming allows to identify instance immediately instead of using guessing by
searching in multiple main.cf files, and it is easier to find for the human
too. So if you had non-default instances running with debian postfix package
before 3.9.1-7, you might want to review and rearrange your configuration.
Also, no instances besides the default one are started automatically as before,
please enable using `systemctl enable postfix@INST.service' as needed.
If your system used non-default instances with configuration directories
not having /etc/postfix- prefix, these will not be managed by the system
startup anymore and must be managed using some other means, or the config
directories has to be moved to have such prefix. The same is true if you
had non-default postfix instances within /etc/postfix/ subdirectory,
like /etc/potfix/out. This naming is on-par with the upstream recommendation,
but unlike `postfix start', which can start instance with any configuration
directory, Postfix integration with systemd in Debian does not support this.
=== older, non-reviewed, contents of README.Debian follows.
There are some significant differences between the Debian Postfix packages,
and the source from upstream:
1. The Debian install is chrooted by default.
2. When starting a postfix instance (either using system startup procedures
or direct call to postfix binary), chroot directory for each instance is
updated, synchronizing files from the root system to the chroot. This is
controlled by SYNC_CHROOT (default Y) variable in /etc/default/postfix
file if exists. This feature can be disabled by setting SYNC_CHROOT=
(empty) in /etc/default/postfix. Chroot directory is being updated only
if the instance has chrooted services.
2A. Starting with Debian Bookworm (12), user specified files can be included
in the chroot when postfix starts. The file /etc/default/postfix is
sourced into the Debian script that configures the chroot for each postfix
instance. In the 'default' file, extra files can be specified in the
chroot_extra_files variable (quoted, space separated list for multiple
files) and an additional Certificate Authority directory can be specified
in the chroot_extra_CAdir variable, for example:
chroot_extra_files=/etc/ssl/certs/local-certificate.pem
chroot_extra_CAdir=/etc/ssl/certs/local-CA
This can be used to provide certificates needed for Postfix to
make encrypted LDAP connections, e.g. tls_ca_cert_dir or tls_cert. See
ldap_table (5) or mysql_table (5) for specifics.
The files or directory must exist outside the chroot in the location
specified. They will be created or updated within the chroot each time
Postfix is started or restarted. Reload is not sufficient.
2B. In the standard Debian networking configuration, postfix is not notified
if /etc/resolv.conf is updated, so the copy in the postfix chroot may
become stale. This can be addressed one of two ways:
a. For systemd users, a .path unit is shipped disabled (since this is only
relevant for some network configurations) to watch for resolv.conf
updates. It needs to be manually enabled and started (once):
# systemctl enable postfix-resolvconf.path
# systemctl enable postfix-resolvconf.service
# systemctl start postfix-resolvconf.path
b. For users of other init systems, installation of the resolvconf package
should prevent this problem for networking configurations where it is an
issue.
3. For policy reasons:
a. SASL configuration goes in /etc/postfix/sasl. Starting in Debian Trixie
(13), the patch that previously hard coded this path is replaced by
setting cyrus_sasl_config_path = /etc/postfix/sasl in Debian's defaults.
Setting this value to a different patch is now supported.
b. myhostname=/path/to/file is supported (and used) in main.cf
4. IPV6 support is enabled: postfix listens on ipv6/ipv4 by default,
(see: inet_protocols)
5. TLS/SASL support is enabled.
6. rmail comes from sendmail, not from postfix.
7. The upstream main.cf is delivered as /usr/share/postfix/main.cf.dist,
rather than cluttering /etc/postfix/main.cf with comments.
Known caveats:
1. (note removed, not relevant. Do not chroot proxymap!)
2. Some configurations (SASL support for example) require extra configuration
(beyond what upstream indicates) to run inside the chroot.
SASL is a bit more complex, and is on the TODO list...
3. Note that the chrooted daemons open /dev/log before chrooting, so if your
syslog daemon is restarted, the daemons will be unable to reconnect to the
syslog socket, and hence being unable to log.
a. For systemd-based system it is not a problem because /dev/log is always
available even if systemd-journald is restarted.
b. For rsyslog daemon, a config snipped /etc/rsyslog.d/postfix.conf is
provided to also open a socket in /var/log/postfix/dev.
c. For sysklogd (the default in Debian versions prior to Lenny), add
SYSLOG="-a /var/spool/postfix/dev/log" to /etc/default/syslog.
d. For inetutils-syslogd, add SYSLOGD_OPTS="-a /var/spool/postfix/dev/log" to
/etc/default/inetutils-syslogd.
e. For other syslog daemons, you will have to either restart postfix after
restarting the syslog daemon, or configure the syslog daemon to open an
additional socket.
4. Map types from the dynamically loadable modules are supported for the
alias database, but it is up to the system administrator to ensure the
required package is installed before changing the postfix configuration.
After changing the map type, newaliases must be run by hand.
Upgrade notes:
milter_protocol:
Nearly all milter packages in the Debian archive use the
libmilter1.0.1 library which as of version 8.14 supports sendmail
milter protocol version 6. The postfix default, starting in version
2.6, is 'milter_protocol = 6'. If you are migrating a older postfix
configuration that specifies a lower version, it should be safe to
remove and depend on the default. If you are using milters not
provided by Debian, you may need to ensure compatibility.
For more information please see
http://www.postfix.org/MILTER_README.html
Postfix Smarthost Configuration
Postfix can be configured to relay mail to a 'smarthost' for delivery. In
practice, with real world smarthosts, considerable configuration is required to
make this work. Some of this configuration can be done via debconf
('dpkg-reconfigure postfix'), but much of it will usually need to be done
manually. This document provides instructions for such configuration.
1. Set the smarthost
This can be set via debconf. To do it manually, add a line like the following
to /etc/postfix/main.cf:
relayhost = [relayhost.example.com]:465
If the port number is omitted, the default is 25. Most smarthosts use TLS/SSL,
and accordingly generally use either 465 or 587 - see below.
2. Enable TLS/SSL
As above, most smarthosts use TLS/SSL. To configure Postfix to use TLS, add the
following lines to main.cf:
smtp_tls_security_level = verify
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
If 'encrypt' is used instead of 'verify', the second line may be omitted.
'encrypt' means that TLS will be used but Postfix will not verify the
smarthost's certificate, potentially allowing a man-in-the-middle attack and
the stealing of the smarthost authentication credentials. On the other hand,
'secure' may be used as an even stricter value than 'verify'. See the
explanation of 'smtp_tls_security_level' values in postconf(5) for details.
If SMTPS (sometimes called 'SSL', usually used in conjunction with
port 465) is desired, add the following additional line to main.cf:
smtp_tls_wrappermode = yes
For STARTTLS (usually used in conjunction with port 587), omit this line (or
use the value 'no').
As to which port number / TLS type to use: consult your smarthost's
documentation. If only one option is available, you will have to use that one.
If both are available, the question is a toss-up. For the last couple of
decades, STARTTLS on port 587 has been the official, standards compliant
method, although SMTPS on port 465 was also widely used. Recently, RFC 8314
has proposed the official recognition of TLS on port 465.
One potential weakness of STARTTLS is that as a form of opportunistic TLS, it
is subject to a man-in-the-middle downgrade attack, where the server's
advertisement of STARTTLS support is stripped out (STRIPTLS) by an attacker,
causing the connection to continue without TLS:
https://en.wikipedia.org/wiki/STARTTLS#Weaknesses_and_mitigations
This can be avoided by making TLS mandatory, via the use of an appropriate
value for 'smtp_tls_security_level' such as 'encrypt', 'verify', or 'secure'.
3. Configure authentication
Most smarthosts require authentication. To enable it, ensure that the package
'libsasl2-modules' is installed, and add the following lines to main.cf:
smtp_sasl_auth_enable = yes
smtp_sasl_security_options =
[See postconf(5) for more information about 'smtp_sasl_security_options' and
its possible values. The above version, with no options, is generally fine.]
To specify the authentication credentials, create an arbitrarily named file
(e.g., '/etc/postfix/example-passwd'), with appropriately restrictive
permissions (e.g., 600) containing a single line of the following form:
relayhost.example.com username@example.com:secret_password
Where 'relayhost.example.com' is the name of the smarthost,
'username@example.com' is the login name, and 'secret_password' is the login
password.
After creating the file, run the command:
postmap /etc/postfix/example-passwd
and add the following line to main.cf:
smtp_sasl_password_maps = hash:/etc/postfix/example-passwd
4. Address rewriting
Most smarthosts require that the sender (envelope FROM and perhaps also the
email From: header) be set to the user's correct mail address with the
smarthost. Postfix therefore needs to be configured to rewrite the sender
address accordingly. There are multiple ways to do this, including canonical
mapping and SMTP generic mapping.
4a. Canonical mapping
With sender canonical mapping, all sender addresses are rewritten upon
Postfix's receipt of the mail. Create an arbitrarily named file (e.g.,
'/etc/postfix/sender_canonical'), containing lines of the form
local-user1 username@example.com
local-user2 username@example.com
where 'local-user1' and 'local-user2' are usernames on the system that will be
sending mail via the smarthost
After creating the file, run the command:
postmap /etc/postfix/sender_canonical
and add the following line to main.cf:
sender_canonical_maps = hash:/etc/postfix/sender_canonical
To use regular expressions to match multiple users, use either 'regexp' or
'pcre' (requires the installation of 'postfix-pcre') tables. See
DATABASE_README, regexp_table(5), PCRE_README, pcre_table(5), and postmap(1).
4b. SMTP generic mapping
With SMTP generic mapping, all matching addresses are rewritten upon Postfix's
delivery of the mail via SMTP. Create an arbitrarily named file (e.g.,
'/etc/postfix/generic_mapping'), containing a line of the form:
@host.domain username@example.com
with 'host.domain' taken from '/etc/mailname'.
After creating the file, run the command:
postmap /etc/postfix/generic_mapping
and add the following line to main.cf:
smtp_generic_maps = hash:/etc/postfix/generic_mapping
One advantage to using generic over canonical mapping is that the latter will
be applied to local mail as well. If the system will be configured to send all
mail, even mail addressed to local users, via the smarthost (e.g., via
aliases), then this point is moot.
Some mail services can be quite picky about what form of the email header From:
they accept. It may be necessary to use an additional smtp_header_check rule to
rewrite the header From: (whether created by the original sender, or by Postfix
itself) into a form that the mail provider will accept. See:
https://marc.info/?l=postfix-users&m=154662599103646
https://marc.info/?l=postfix-users&m=154656149717210
See the ADDRESS_REWRITING_README for more information.
At this point, restart Postfix:
/etc/init.d/postfix restart
Test:
echo 'test' | sendmail someuser@somehost.com
5. Aliases
As configured so far, local mail will be delivered locally and not sent via the
smarthost. To redirect local mail through the smarthost, aliases can be used.
In /etc/aliases, add lines like the following:
root: someuser@somehost.com
Then run:
newaliases
6. CREDITS:
This guide was based (with considerable elaboration) on a number of other
guides on this topic (in addition to the official Postfix documentation),
including:
https://www.eanderalx.org/linux/postfix
http://emanuelesantanche.com/article/85/configuring-postfix-to-relay-email-through-zoho-mail
https://www.dnsexit.com/support/mailrelay/postfix.html
https://www.cyberciti.biz/faq/postfix-smtp-authentication-for-mail-servers/
https://blog.bravi.org/?p=1065