Topics covered in this section:
In Postfix 2.3, the
smtp(8) and
lmtp(8) delivery agents have been
merged into a single dual-purpose program. As a result the
lmtp(8)
delivery agent is no longer the poor cousin of the more extensively used
smtp(8). Specifically, as of Postfix 2.3, all the TLS features described
below apply equally to SMTP and LMTP, after replacing the "smtp_"
prefix of the each parameter name with "lmtp_".
The LMTP delivery agent can communicate with LMTP servers listening
on UNIX-domain sockets. When server certificate verification is enabled
and the server is listening on a UNIX-domain socket, the $
myhostname
parameter is used to set the TLS verification nexthop and
hostname. Note, opportunistic encryption of LMTP traffic over
UNIX-domain sockets is futile. TLS is only useful in this context when
it is mandatory, typically to allow at least one of the server or the
client to authenticate the other. The "null" cipher grade may be
appropriate in this context, when available on both client and server.
The "null" ciphers provide authentication without encryption.
Do not configure client certificates unless you must present
client TLS certificates to one or more servers. Client certificates are
not usually needed, and can cause problems in configurations that work
well without them. The recommended setting is to let the defaults stand:
smtp_tls_cert_file =
smtp_tls_dcert_file =
smtp_tls_key_file =
smtp_tls_dkey_file =
The best way to use the default settings is to comment out the above
parameters in
main.cf if present.
During TLS startup negotiation the Postfix SMTP client may present
a certificate to the remote SMTP server. The Netscape client is
rather clever here and lets the user select between only those
certificates that match CA certificates offered by the remote SMTP
server. As the Postfix SMTP client uses the "SSL_connect()" function
from the OpenSSL package, this is not possible and we have to choose
just one certificate. So for now the default is to use _no_
certificate and key unless one is explicitly specified here.
Both RSA and DSA certificates are supported. You can have both
at the same time, in which case the cipher used determines which
certificate is presented.
It is possible for the Postfix SMTP client to use the same
key/certificate pair as the Postfix SMTP server. If a certificate
is to be presented, it must be in "PEM" format. The private key
must not be encrypted, meaning: it must be accessible without
password. Both parts (certificate and private key) may be in the
same file.
In order for remote SMTP servers to verify the Postfix SMTP
client certificates, the CA certificate (in case of a certificate
chain, all CA certificates) must be available. You should add
these certificates to the client certificate, the client certificate
first, then the issuing CA(s).
Example: the certificate for "client.example.com" was issued by
"intermediate CA" which itself has a certificate of "root CA".
Create the client.pem file with:
% cat client_cert.pem intermediate_CA.pem > client.pem
A Postfix SMTP client certificate supplied here must be usable
as SSL client certificate and hence pass the "openssl verify -purpose
sslclient ..." test.
A server that trusts the root CA has a local copy of the root
CA certificate, so it is not necessary to include the root CA
certificate here. Leaving it out of the "client.pem" file reduces
the overhead of the TLS exchange.
If you want the Postfix SMTP client to accept remote SMTP server
certificates issued by these CAs, append the root certificate to
$
smtp_tls_CAfile or install it in the $
smtp_tls_CApath directory. When
you configure trust in a root CA, it is not necessary to explicitly trust
intermediary CAs signed by the root CA, unless $
smtp_tls_scert_verifydepth
is less than the number of CAs in the certificate chain for the servers
of interest. With a verify depth of 1 you can only verify certificates
directly signed by a trusted CA, and all trusted intermediary CAs need to
be configured explicitly. With a verify depth of 2 you can verify servers
signed by a root CA or a direct intermediary CA (so long as the server
is correctly configured to supply its intermediate CA certificate).
RSA key and certificate examples:
/etc/postfix/
main.cf:
smtp_tls_cert_file = /etc/postfix/client.pem
smtp_tls_key_file = $
smtp_tls_cert_file
Their DSA counterparts:
/etc/postfix/
main.cf:
smtp_tls_dcert_file = /etc/postfix/client-dsa.pem
smtp_tls_dkey_file = $
smtpd_tls_cert_file
To verify a remote SMTP server certificate, the Postfix SMTP
client needs to trust the certificates of the issuing certification
authorities. These certificates in "pem" format can be stored in a
single $
smtp_tls_CAfile or in multiple files, one CA per file in
the $
smtp_tls_CApath directory. If you use a directory, don't forget
to create the necessary "hash" links with:
# $OPENSSL_HOME/bin/c_rehash /path/to/directory
The $
smtp_tls_CAfile contains the CA certificates of one or more
trusted CAs. The file is opened (with root privileges) before Postfix
enters the optional chroot jail and so need not be accessible from inside the
chroot jail.
Additional trusted CAs can be specified via the $
smtp_tls_CApath
directory, in which case the certificates are read (with $
mail_owner
privileges) from the files in the directory when the information
is needed. Thus, the $
smtp_tls_CApath directory needs to be accessible
inside the optional chroot jail.
The choice between $
smtp_tls_CAfile and $
smtpd_tls_CApath is
a space/time tradeoff. If there are many trusted CAs, the cost of
preloading them all into memory may not pay off in reduced access time
when the certificate is needed.
Example:
/etc/postfix/
main.cf:
smtp_tls_CAfile = /etc/postfix/CAcert.pem
smtp_tls_CApath = /etc/postfix/certs
To get additional information about Postfix SMTP client TLS
activity you can increase the loglevel from 0..4. Each logging
level also includes the information that is logged at a lower
logging level.
0 | Disable logging of TLS activity. |
1 | Log TLS handshake and certificate information.
|
2 | Log levels during TLS negotiation. |
3 | Log hexadecimal and ASCII dump of TLS
negotiation process |
4 | Log hexadecimal and ASCII dump of complete
transmission after STARTTLS |
Example:
/etc/postfix/
main.cf:
smtp_tls_loglevel = 0
The remote SMTP server and the Postfix SMTP client negotiate a
session, which takes some computer time and network bandwidth. By
default, this session information is cached only in the
smtp(8)
process actually using this session and is lost when the process
terminates. To share the session information between multiple
smtp(8) processes, a persistent session cache can be used. You
can specify any database type that can store objects of several
kbytes and that supports the sequence operator. DBM databases are
not suitable because they can only store small objects. The cache
is maintained by the
tlsmgr(8) process, so there is no problem with
concurrent access. Session caching is highly recommended, because
the cost of repeatedly negotiating TLS session keys is high. Future
Postfix SMTP servers may limit the number of sessions that a client
is allowed to negotiate per unit time.
Example:
/etc/postfix/
main.cf:
smtp_tls_session_cache_database = btree:/etc/postfix/smtp_scache
Cached Postfix SMTP client session information expires after
a certain amount of time. Postfix/TLS does not use the OpenSSL
default of 300s, but a longer time of 3600s (=1 hour).
RFC 2246
recommends a maximum of 24 hours.
Example:
/etc/postfix/
main.cf:
smtp_tls_session_cache_timeout = 3600s
The security properties of TLS communication channels are
application specific. While the TLS protocol can provide a confidential,
tamper-resistant, mutually authenticated channel between client
and server, not all of these security features are applicable to every
communication.
For example, while mutual TLS authentication between browsers and web
servers is possible, it is not practical, or even useful, for web-servers
that serve the public to verify the identity of every potential user. In
practice, most HTTPS transactions are asymmetric: the browser verifies
the HTTPS server's identity, but the user remains anonymous. Much of
the security policy is up to the client. If the client chooses to not
verify the server's name, the server is not aware of this. There are many
interesting browser security topics, but we shall not dwell
on them here. Rather, our goal is to understand the security features
of TLS in conjunction with SMTP.
An important SMTP-specific observation is that a public MX host is
even more at the mercy of the SMTP client than is an HTTPS server. Not only
can it not enforce due care in the client's use of TLS, but it cannot even
enforce the use of TLS, because TLS support in SMTP clients is still the
exception rather than the rule. One cannot, in practice, limit access to
one's MX hosts to just TLS-enabled clients. Such a policy would result
in a vast reduction in one's ability to communicate by email with the
world at large.
One may be tempted to try enforcing TLS for mail from specific
sending organizations, but this, too, runs into obstacles. One such
obstacle is that we don't know who is (allegedly) sending mail until
we see the "MAIL FROM:" SMTP command, and at that point, if TLS
is not already in use, a potentially sensitive sender address (and
with SMTP PIPELINING one or more of the recipients) has (have) already been
leaked in the clear. Another obstacle is that mail from the sender to
the recipient may be forwarded, and the forwarding organization may not
have any security arrangements with the final destination. Bounces also
need to be protected. These can only be identified by the IP address and
HELO name of the connecting client, and it is difficult to keep track
of all the potential IP addresses or HELO names of the outbound email
servers of the sending organization.
Consequently, TLS security for mail delivery to public MX hosts is
almost entirely the client's responsibility. The server is largely a
passive enabler of TLS security, the rest is up to the client. While the
server has a greater opportunity to mandate client security policy when
it is a dedicated MSA that only handles outbound mail from trusted clients,
below we focus on the client security policy.
On the SMTP client, there are further complications. When delivering
mail to a given domain, in contrast to HTTPS, one rarely uses the domain
name directly as the target host of the SMTP session. More typically,
one uses MX lookups - these are usually unauthenticated - to obtain the domain's SMTP server
hostname(s). When, as is current practice, the client verifies the
insecurely obtained MX hostname, it is subject to a DNS man-in-the-middle
attack.
If clients instead attempted to verify the recipient domain name,
an SMTP server for multiple domains would need to
list all its email domain names in its certificate, and generate a
new certificate each time a new domain were added. At least some CAs set
fairly low limits (20 for one prominent CA) on the number of names that
server certificates can contain. This approach is not consistent with
current practice and does not scale.
It is regrettably the case that TLS secure-channels
(fully authenticated and immune to man-in-the-middle attacks) impose
constraints on the sending and receiving sites that preclude ubiquitous
deployment. One needs to manually configure this type of security for
each destination domain, and in many cases implement non-default TLS
policy table entries for additional
domains hosted at a common secured destination. With Postfix 2.3, we
make secure-channel configurations substantially easier to configure,
but they will never be the norm. For the generic domain with which you
have made no specific security arrangements, this security level is not
a good fit.
Given that strong authentication is not generally possible, and that
verifiable certificates cost time and money, many servers that implement
TLS use self-signed certificates or private CAs. This further limits
the applicability of verified TLS on the public Internet.
Historical note: while the documentation of these issues and many of the
related features are new with Postfix 2.3, the issue was well
understood before Postfix 1.0, when Lutz Jänicke was designing
the first unofficial Postfix TLS patch. See his original post https://www.imc.org/ietf-apps-tls/mail-archive/msg00304.html
and the first response https://www.imc.org/ietf-apps-tls/mail-archive/msg00305.html.
The problem is not even unique to SMTP or even TLS, similar issues exist
for secure connections via aliases for HTTPS and Kerberos. SMTP merely
uses indirect naming (via MX records) more frequently.
The TLS security levels listed below are described in more detail
in the sections that follow.
- none
-
No TLS.
- may
-
Opportunistic TLS.
- encrypt
-
Mandatory TLS encryption.
- verify
-
Mandatory server certificate verification.
- secure
-
Secure-channel TLS.
At the "none" TLS security level, TLS encryption is
disabled. This is the default security level. With Postfix 2.3 and later,
it can be configured explicitly by setting "
smtp_tls_security_level = none".
With Postfix 2.2 and earlier, or when
smtp_tls_security_level is set to
its default (backwards compatible) empty value, the appropriate configuration
settings are "
smtp_use_tls = no" and "
smtp_enforce_tls = no".
With either approach, TLS is not used even if supported by the server.
For LMTP, use the corresponding "lmtp_" parameters.
Per destination settings may override this default setting, in which case
TLS is used selectively, only with destinations explicitly configured
for TLS.
You can disable TLS for a subset of destinations, while leaving
it enabled for the rest. With the Postfix 2.3+ TLS policy table, specify the "none"
security level. With the obsolete
per-site
table, specify the "NONE" keyword.
At the "may" TLS security level, TLS encryption is opportunistic.
The SMTP transaction is encrypted if the STARTTLS ESMTP feature
is supported by the server. Otherwise, messages are sent in the clear.
With Postfix 2.3 and later, opportunistic TLS can be configured by
setting "
smtp_tls_security_level = may".
Since sending in the clear is acceptable, demanding stronger
than default TLS security merely reduces inter-operability. For
this reason, Postfix 2.3 and later ignore the
smtp_tls_mandatory_ciphers
and
smtp_tls_mandatory_protocols parameters at the "may"
security level: all protocols are allowed, and "export" grade or
better ciphers are used.
With Postfix 2.2 and earlier, or when
smtp_tls_security_level is
set to its default (backwards compatible) empty value, the appropriate
configuration settings are "
smtp_use_tls = yes" and
"
smtp_enforce_tls = no".
For LMTP use the corresponding "lmtp_" parameters.
With opportunistic TLS, mail delivery continues even if the
server certificate is untrusted or bears the wrong name. Starting
with Postfix 2.3, when the TLS handshake fails for an opportunistic
TLS session, rather than give up on mail delivery, the transaction
is retried with TLS disabled. Trying an unencrypted connection makes
it possible to deliver mail to sites with non-interoperable server
TLS implementations.
Opportunistic encryption is never used for LMTP over UNIX-domain
sockets. The communications channel is already confidential without
TLS, so the only potential benefit of TLS is authentication. Do not
configure opportunistic TLS for LMTP deliveries over UNIX-domain sockets.
Only configure TLS for LMTP over UNIX-domain sockets at the
encrypt security level or higher.
Attempts to configure opportunistic encryption of LMTP sessions will
be ignored with a warning written to the mail logs.
You can enable opportunistic TLS just for selected destinations. With
the Postfix 2.3+ TLS
policy table,
specify the "may" security level. With the obsolete per-site table, specify the "MAY" keyword.
This is the most common security level for TLS protected SMTP
sessions, stronger security is not generally available and, if needed,
is typically only configured on a per-destination basis. See the section
on TLS
limitations above.
Example:
/etc/postfix/
main.cf:
smtp_tls_security_level = may
Postfix 2.2 syntax:
/etc/postfix/
main.cf:
smtp_use_tls = yes
smtp_enforce_tls = no
At the "encrypt" TLS security level, messages are sent only
over TLS encrypted sessions. The SMTP transaction is aborted unless
the STARTTLS ESMTP feature is supported by the server. If no suitable
servers are found, the message will be deferred. With Postfix 2.3
and later, mandatory TLS encryption can be configured by setting
"
smtp_tls_security_level = encrypt". Even though TLS
encryption is always used, mail delivery continues if the server
certificate is untrusted or bears the wrong name.
At this security level and higher, the
smtp_tls_mandatory_protocols
and
smtp_tls_mandatory_ciphers configuration parameters determine
the list of sufficiently secure SSL protocol versions and the minimum
cipher strength. If the protocol or cipher requirements are not
met, the mail transaction is aborted. The documentation for these
parameters includes useful interoperability and security guidelines.
With Postfix 2.2 and earlier, or when
smtp_tls_security_level
is set to its default (backwards compatible) empty value, the
appropriate configuration settings are "
smtp_enforce_tls = yes"
and "
smtp_tls_enforce_peername = no". For LMTP use the corresponding
"lmtp_" parameters.
Despite the potential for eliminating passive eavesdropping attacks,
mandatory TLS encryption is not viable as a default security level for
mail delivery to the public Internet. Most MX hosts do not support TLS at
all, and some of those that do have broken implementations. On a host
that delivers mail to the Internet, you should not configure mandatory
TLS encryption as the default security level.
You can enable mandatory TLS encryption just for specific destinations.
With the Postfix 2.3+ TLS
policy
table, specify the "encrypt" security level. With the
obsolete
per-site table, specify the
"MUST_NOPEERMATCH" keyword. While the obsolete approach still works
with Postfix 2.3, it is strongly discouraged: users of Postfix 2.3+
should use the new TLS policy settings.
Examples:
In the example below, traffic to example.com and its sub-domains
via the corresponding MX hosts always uses TLS. The protocol version will be
"SSLv3" or "TLSv1" (the default setting of
smtp_tls_mandatory_protocols
excludes "SSLv2"). Only high or medium strength (i.e. 128 bit or
better) ciphers will be used by default for all "encrypt" security
level sessions.
/etc/postfix/
main.cf:
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
/etc/postfix/tls_policy:
example.com encrypt
.example.com encrypt
Postfix 2.2 syntax (no support for sub-domains without resorting to
regexp tables). With Postfix 2.3+, do not use the obsolete per-site table.
/etc/postfix/
main.cf:
smtp_tls_per_site = hash:/etc/postfix/tls_per_site
/etc/postfix/tls_per_site:
example.com MUST_NOPEERMATCH
In the next example, secure message submission is configured
via the MSA "[example.net]:587". TLS sessions are encrypted
without authentication, because this MSA does not possess an acceptable
certificate. This MSA is known to be capable of "TLSv1" and "high" grade
ciphers, so these are selected via the
policy
table.
Note: the policy table lookup key is the verbatim next-hop
specification from the recipient domain,
transport(5) table or
relayhost
parameter, with any enclosing square brackets and optional port. Take
care to be consistent: the suffixes ":smtp" or ":25" or no port suffix
result in different policy table lookup keys, even though they are
functionally equivalent nexthop specifications. Use at most one of these
forms for all destinations. Below, the policy table has multiple keys,
just in case the transport table entries are not specified consistently.
/etc/postfix/
main.cf:
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
/etc/services:
submission 587/tcp msa # mail message submission
/etc/postfix/tls_policy:
[example.net]:587 encrypt protocols=TLSv1 ciphers=high
[example.net]:msa encrypt protocols=TLSv1 ciphers=high
[example.net]:submission encrypt protocols=TLSv1 ciphers=high
Postfix 2.2 syntax:
Note: Avoid policy lookups with the bare hostname (for
example, "example.net"). Instead,
use the destination (for example, "[example.net]:587"), as the per-site table lookup key (a recipient domain
or MX-enabled transport nexthop with no port suffix may look like a bare
hostname, but is still a suitable destination). With Postfix 2.3+,
do not use the obsolete
per-site table;
use the new
policy table instead.
/etc/postfix/
main.cf:
smtp_tls_per_site = hash:/etc/postfix/tls_per_site
/etc/postfix/tls_per_site:
[example.net]:587 MUST_NOPEERMATCH
At the "verify" TLS security level, messages are sent only over
TLS encrypted sessions if the server certificate is valid (not
expired or revoked, and signed by a trusted certificate authority)
and if the server certificate name matches a known pattern. Mandatory
server certificate verification can be configured by setting
"
smtp_tls_security_level = verify". The
smtp_tls_verify_cert_match parameter can override the default
"hostname" certificate name matching strategy. Fine-tuning the
matching strategy is generally only appropriate for secure-channel destinations.
With Postfix 2.2 and earlier, or when
smtp_tls_security_level
is set to its default (backwards compatible) empty value, the
appropriate configuration settings are "
smtp_enforce_tls = yes" and
"
smtp_tls_enforce_peername = yes". For LMTP use the corresponding
"lmtp_" parameters.
If the server certificate chain is trusted (see
smtp_tls_CAfile
and
smtp_tls_CApath), any DNS names in the SubjectAlternativeName
certificate extension are used to verify the server name. If no
DNS names are specified, the certificate CommonName is checked.
If you want mandatory encryption without server certificate
verification, see
above.
Despite the potential for eliminating "man-in-the-middle" and other
attacks, mandatory certificate trust chain and subject name verification
is not viable as a default Internet mail delivery policy. Most MX hosts
do not support TLS at all, and a significant portion of TLS enabled
MTAs use self-signed certificates, or certificates that are signed by
a private certificate authority. On a machine that delivers mail to
the Internet, you should not configure mandatory server certificate
verification as a default policy.
Mandatory server certificate verification as a default security
level may be appropriate if you know that you will only connect to
servers that support
RFC 2487 and that present verifiable
server certificates. An example would be a client that sends all
email to a central mailhub that offers the necessary STARTTLS
support. In such cases, you can often use a secure-channel configuration instead.
You can enable mandatory server certificate verification just
for specific destinations. With the Postfix 2.3+ TLS policy table, specify the "verify"
security level. With the obsolete
per-site
table, specify the "MUST" keyword. While the obsolete approach
still works with Postfix 2.3, it is strongly discouraged: users of
Postfix 2.3+ should use the new TLS policy settings.
Example:
In this example, the client encrypts all traffic to the
example.com domain. The peer hostname is verified, but
verification is vulnerable to DNS response forgery. Mail transmission
to example.com recipients uses "high" grade ciphers.
/etc/postfix/
main.cf:
indexed = ${
default_database_type}:${
config_directory}/
smtp_tls_CAfile = ${
config_directory}/CAfile.pem
smtp_tls_policy_maps = ${indexed}tls_policy
/etc/postfix/tls_policy:
example.com verify ciphers=high
Postfix 2.2 syntax:
/etc/postfix/
main.cf:
indexed = ${
default_database_type}:${
config_directory}/
smtp_tls_CAfile = ${
config_directory}/CAfile.pem
smtp_tls_per_site = ${indexed}tls_per_site
/etc/postfix/tls_per_site:
example.com MUST
At the secure TLS security level, messages are sent only over
secure-channel TLS sessions where DNS forgery resistant server
certificate verification succeeds. If no suitable servers are found, the
message will be deferred. With Postfix 2.3 and later, secure-channels
can be configured by setting "
smtp_tls_security_level = secure".
The
smtp_tls_secure_cert_match parameter can override the default
"nexthop, dot-nexthop" certificate match strategy.
With Postfix 2.2 and earlier, or when
smtp_tls_security_level
is set to its default (backwards compatible) empty value, the
appropriate configuration settings are "
smtp_enforce_tls = yes"
and "
smtp_tls_enforce_peername = yes" with additional settings to
harden peer certificate verification
against forged DNS data. For LMTP, use the corresponding "lmtp_"
parameters.
If the server certificate chain is trusted (see
smtp_tls_CAfile and
smtp_tls_CApath), any DNS names in the SubjectAlternativeName certificate
extension are used to verify the server name. If no DNS names are
specified, the CommonName is checked. If you want mandatory encryption
without server certificate verification, see above.
Despite the potential for eliminating "man-in-the-middle" and other
attacks, mandatory secure server certificate verification is not
viable as a default Internet mail delivery policy. Most MX hosts
do not support TLS at all, and a significant portion of TLS enabled
MTAs use self-signed certificates, or certificates that are signed
by a private certificate authority. On a machine that delivers mail
to the Internet, you should not configure secure TLS verification
as a default policy.
Mandatory secure server certificate verification as a default
security level may be appropriate if you know that you will only
connect to servers that support
RFC 2487 and that present
verifiable server certificates. An example would be a client that
sends all email to a central mailhub that offers the necessary
STARTTLS support.
You can enable secure TLS verification just for specific destinations.
With the Postfix 2.3+ TLS
policy table,
specify the "secure" security level. With the obsolete
per-site table, specify the "MUST"
keyword and
harden the certificate
verification against DNS forgery. While the obsolete approach still
works with Postfix 2.3, it is strongly discouraged: users of Postfix 2.3+
should use the new TLS policy settings.
Examples:
Secure-channel TLS without
transport(5) table overrides:
The client will encrypt all traffic and verify the destination name
immune from forged DNS responses. MX lookups are still used to find
the SMTP servers for example.com, but these are not used when
checking the names in the server certificate(s). Rather, the requirement
is that the MX hosts for example.com have trusted certificates
with a subject name of example.com or a sub-domain, see the
documentation for the
smtp_tls_secure_cert_match parameter.
The related domains example.co.uk and example.co.jp are
hosted on the same MX hosts as the primary example.com domain, and
traffic to these is secured by verifying the primary example.com
domain in the server certificates. This frees the server administrator
from needing the CA to sign certificates that list all the secondary
domains. The downside is that clients that want secure channels to the
secondary domains need explicit TLS
policy
table entries.
Note, there are two ways to handle related domains. The first is to
use the default routing for each domain, but add policy table entries
to override the expected certificate subject name. The second is to
override the next-hop in the transport table, and use a single policy
table entry for the common nexthop. We choose the first approach,
because it works better when domain ownership changes. With the second
approach we securely deliver mail to the wrong destination, with the
first approach, authentication fails and mail stays in the local queue,
the first approach is more appropriate in most cases.
/etc/postfix/
main.cf:
smtp_tls_CAfile = /etc/postfix/CAfile.pem
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
/etc/postfix/transport:
/etc/postfix/tls_policy:
example.com secure
example.co.uk secure match=example.com:.example.com
example.co.jp secure match=example.com:.example.com
Secure-channel TLS with
transport(5) table overrides:
In this case traffic to example.com and its related domains
is sent to a single logical gateway (to avoid a single point of failure,
its name may resolve to one or more load-balancer addresses, or to the
combined addresses of multiple physical hosts). All the physical hosts
reachable via the gateway's IP addresses have the logical gateway name
listed in their certificates. This secure-channel configuration can also
be implemented via a
hardened variant of
the MUST policy in the obsolete
per-site
table. As stated above, this approach has the potential to mis-deliver
email if the related domains change hands.
/etc/postfix/
main.cf:
smtp_tls_CAfile = /etc/postfix/CAfile.pem
transport_maps = hash:/etc/postfix/transport
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
/etc/postfix/transport:
example.com
smtp:[tls.example.com]
example.co.uk
smtp:[tls.example.com]
example.co.jp
smtp:[tls.example.com]
/etc/postfix/tls_policy:
[tls.example.com] secure match=tls.example.com
Postfix 2.2.9+ syntax:
Note: Avoid policy lookups with the bare hostname (for
example, "tls.example.com"). Instead, use the destination (for
example, "[tls.example.com]") as the per-site table lookup key (a recipient domain
or MX-enabled transport nexthop with no port suffix may look like a bare
hostname, but is still a suitable destination). With Postfix 2.3+,
do not use the obsolete
per-site table;
use the new
policy table instead.
/etc/postfix/
main.cf:
smtp_cname_overrides_servername = no
smtp_tls_CAfile = /etc/postfix/CAfile.pem
transport_maps = hash:/etc/postfix/transport
smtp_tls_per_site = hash:/etc/postfix/tls_per_site
/etc/postfix/transport:
example.com
smtp:[tls.example.com]
example.co.uk
smtp:[tls.example.com]
example.co.jp
smtp:[tls.example.com]
/etc/postfix/tls_per_site:
[tls.example.com] MUST
Postfix 2.3 introduces a new more flexible TLS policy table. For
earlier releases, read the description of the obsolete Postfix 2.2 per-site table.
A small fraction of servers offer STARTTLS but the negotiation
consistently fails. With Postfix 2.3, so long as encryption is not
enforced, the delivery is immediately retried with TLS disabled. You no
longer need to explicitly disable TLS for the problem destinations.
As soon as their TLS software or configuration is repaired, encryption
will be used.
The new policy table is specified via the
smtp_tls_policy_maps
parameter. This lists optional lookup tables with the Postfix SMTP client
TLS security policy by next-hop destination. When $
smtp_tls_policy_maps
is not empty, the obsolete
smtp_tls_per_site parameter is ignored
(a warning is written to the logs if both parameter values are
non-empty).
The TLS policy table is indexed by the full next-hop destination,
which is either the recipient domain, or the verbatim next-hop
specified in the transport table, $
local_transport, $
virtual_transport,
$
relay_transport or $
default_transport. This includes any enclosing
square brackets and any non-default destination server port suffix. The
LMTP socket type prefix (inet: or unix:)
is not included in the lookup key.
Only the next-hop domain, or $
myhostname with LMTP over UNIX-domain
sockets, is used as the nexthop name for certificate verification. The
port and any enclosing square brackets are used in the table lookup key,
but are not used for server name verification.
When the lookup key is a domain name without enclosing square brackets
or any :port suffix (typically the recipient domain), and the full
domain is not found in the table, just as with the
transport(5) table,
the parent domain starting with a leading "." is matched recursively. This
allows one to specify a security policy for a recipient domain and all
its sub-domains.
The lookup result is a security level, followed by an optional
list of whitespace and/or comma separated name=value attributes
that override related
main.cf settings. The TLS security levels are described above. Below, we
describe the corresponding table syntax:
- none
- No TLS. No additional attributes are supported at this level.
- may
- Opportunistic TLS. No additional attributes are supported at this
level.
- encrypt
- Mandatory TLS encryption. Mail is
delivered only if remote SMTP server offers STARTTLS and the TLS
handshake succeeds. At this level and higher the optional "ciphers"
attribute overrides the
main.cf
smtp_tls_mandatory_ciphers parameter
and the optional "protocols" keyword overrides the
main.cf
smtp_tls_mandatory_protocols parameter.
- verify
- Mandatory server certificate verification.
Mail is delivered only if the TLS handshake succeeds, if the server
certificate can be validated (not expired or revoked, and signed
by a trusted certificate authority), and if the server certificate
name matches the optional "match" attribute (or the
main.cf
smtp_tls_verify_cert_match parameter value when no optional "match"
attribute is specified).
- secure
- Secure-channel TLS. Mail is delivered
only if the TLS handshake succeeds, if the server certificate can
be validated (not expired or revoked, and signed by a trusted
certificate authority), and if the server certificate name matches
the optional "match" attribute (or the
main.cf
smtp_tls_secure_cert_match
parameter value when no optional "match" attribute is specified).
Notes:
-
The "match" attribute is especially useful to verify TLS
certificates for domains that are hosted on a shared server. In
that case, specify "match" rules for the shared server's name.
While secure verification can also be achieved with manual routing
overrides in Postfix
transport(5) tables, that approach can deliver
mail to the wrong host when domains are assigned to new gateway
hosts. The "match" attribute approach avoids the problems of manual
routing overrides; mail is deferred if verification of a new MX
host fails.
-
When a policy table entry specifies multiple match patterns,
multiple match strategies, or multiple protocols, these must be
separated by colons.
Example:
/etc/postfix/
main.cf:
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
/etc/postfix/tls_policy:
example.edu none
example.mil may
example.gov encrypt protocols=SSLv3:TLSv1 ciphers=high
example.com verify
match=hostname:dot-nexthop protocols=SSLv3:TLSv1 ciphers=high
example.net secure
.example.net secure match=.example.net:example.net
[mail.example.org]:587 secure match=nexthop
Note: The "hostname" strategy if listed in a non-default setting
of
smtp_tls_secure_cert_match or in the "match" attribute in the policy
table can render the "secure" level vulnerable to DNS forgery. Do not use
the "hostname" strategy for
secure-channel
configurations in environments where DNS security is not assured.
This section describes an obsolete per-site TLS policy mechanism.
Unlike the Postfix 2.3
policy table
mechanism, this uses as a policy lookup key a potentially untrusted
server hostname, and lacks control over what names can appear in
server certificates. Because of this, the obsolete mechanism is
typically vulnerable to false DNS hostname information in MX or
CNAME records. These attacks can be eliminated only with great
difficulty. The new
policy table
makes
secure-channel configurations
easier and provides more control over the cipher and protocol selection
for sessions with mandatory encryption.
Avoid policy lookups with the bare hostname. Instead, use the
full destination nexthop (enclosed in [] with a possible ":port"
suffix) as the per-site table lookup key (a recipient domain or
MX-enabled transport nexthop with no port suffix may look like a bare
hostname, but is still a suitable destination). With Postfix 2.3+,
use of the obsolete approach documented here is strongly discouraged:
use the new
policy table instead.
Starting with Postfix 2.3, the underlying TLS enforcement levels are
common to the obsolete per-site table and the new policy table. The
main.cf
smtp_tls_mandatory_ciphers and
smtp_tls_mandatory_protocols
parameters control the TLS ciphers and protocols for mandatory
encryption regardless of which table is used. The
smtp_tls_verify_cert_match parameter determines the match strategy
for the obsolete "MUST" keyword in the same way as for the "verify"
level in the new policy.
With Postfix < 2.3, the obsolete
smtp_tls_cipherlist parameter
is also applied for opportunistic TLS sessions, and should be used with
care, or not at all. Setting cipherlist restrictions that are incompatible
with a remote SMTP server render that server unreachable, TLS handshakes
are always attempted and always fail.
When
smtp_tls_policy_maps is empty (default) and
smtp_tls_per_site
is not empty, the per-site table is searched for a policy that matches
the following information:
- remote SMTP server hostname
- This is simply the DNS
name of the server that the Postfix SMTP client connects to; this
name may be obtained from other DNS lookups, such as MX lookups or
CNAME lookups. Use of the hostname lookup key is discouraged; always
use the next-hop destination instead.
- next-hop destination
- This is normally the domain portion
of the recipient address, but it may be overridden by information from
the
transport(5) table, from the
relayhost parameter setting, or from
the
relay_transport setting. When it is not the recipient domain, the
next-hop destination can have the Postfix-specific form "[name]",
"[name]:port", "name" or "name:port". This is
the recommended lookup key for per-site policy lookups (and incidentally
for
SASL password lookups).
When both the hostname lookup and the next-hop lookup succeed,
the host policy does not automatically override the next-hop policy.
Instead, precedence is given to either the more specific or the
more secure per-site policy as described below.
The
smtp_tls_per_site table uses a simple "name whitespace
value" format. Specify host names or next-hop destinations on
the left-hand side; no wildcards are allowed. On the right hand
side specify one of the following keywords:
- NONE
- No TLS. This overrides a less specific "MAY" lookup
result from the alternate host or next-hop lookup key, and overrides
the global
smtp_use_tls,
smtp_enforce_tls, and
smtp_tls_enforce_peername
settings.
- MAY
- Opportunistic TLS. This has less precedence than
a more specific result (including "NONE") from the alternate host or
next-hop lookup key, and has less precedence than the more specific global
"
smtp_enforce_tls = yes" or "
smtp_tls_enforce_peername = yes".
- MUST_NOPEERMATCH
- Mandatory TLS encryption. This
overrides a less secure "NONE" or a less specific "MAY" lookup result
from the alternate host or next-hop lookup key, and overrides the global
smtp_use_tls,
smtp_enforce_tls and
smtp_tls_enforce_peername settings.
- MUST
- Mandatory server certificate verification.
This overrides a less secure "NONE" and "MUST_NOPEERMATCH" or a
less specific "MAY" lookup result from the alternate host or next-hop
lookup key, and overrides the global
smtp_use_tls,
smtp_enforce_tls
and
smtp_tls_enforce_peername settings.
The precedences between global (
main.cf) and per-site TLS
policies can be summarized as follows:
-
When neither the remote SMTP server hostname nor the
next-hop destination are found in the
smtp_tls_per_site table, the
policy is based on
smtp_use_tls,
smtp_enforce_tls and
smtp_tls_enforce_peername. Note: "
smtp_enforce_tls = yes" and
"
smtp_tls_enforce_peername = yes" imply "
smtp_use_tls = yes".
-
When both hostname and next-hop destination lookups produce
a result, the more specific per-site policy (NONE, MUST, etc)
overrides the less specific one (MAY), and the more secure per-site
policy (MUST, etc) overrides the less secure one (NONE).
-
After the per-site policy lookups are combined, the result
generally overrides the global policy. The exception is the less
specific "MAY" per-site policy, which is overruled by the more
specific global "
smtp_enforce_tls = yes" with server certificate
verification as specified with the
smtp_tls_enforce_peername
parameter.
For a general discussion of TLS security for SMTP see TLS limitations above. What follows applies
only to Postfix 2.2.9 and subsequent Postfix 2.2 patch levels. Do
not use this approach with Postfix 2.3+; instead see the instructions under secure server certificate verification.
As long as no secure DNS lookup mechanism is available, false
hostnames in MX or CNAME responses can change Postfix's notion of the
server hostname that is used for TLS policy lookup and server certificate
verification. Even with a perfect match between the server hostname and
the server certificate, there is no guarantee that Postfix is connected
to the right server. To avoid this loophole, take all of the following
steps:
-
Use a dedicated message delivery transport (for example,
"securetls") as illustrated below.
-
Eliminate MX lookups. Specify local
transport(5) table
entries for sensitive domains with explicit securetls:[mailhost]
or securetls:[mailhost]:port destinations (you can
assure security of this table unlike DNS). This prevents false
hostname information in DNS MX records from changing Postfix's
notion of the server hostname that is used for TLS policy lookup
and server certificate verification. The "securetls" transport is
configured to enforce TLS with peername verification, and to disable
the SMTP connection cache which could interfere with enforcement
of
smtp_tls_per_site policies.
-
Disallow CNAME hostname overrides. In
main.cf, specify
"
smtp_cname_overrides_servername = no". This prevents false hostname
information in DNS CNAME records from changing the server hostname
that Postfix uses for TLS policy lookup and server certificate
verification. This feature requires Postfix 2.2.9 or later. The
default value is "no" starting with Postfix 2.3.
Example:
We give the
non-default
"securetls" transport an explicit
master.cf process limit, so that we
don't raise its process limit when raising $
default_process_limit. The
total process limit for *all* transports should stay somewhat under 1024
(the typical select() file descriptor limit); otherwise transports may
be throttled under steady high load, compounding congestion. It is not
uncommon at high volume sites to set the default process limit to 500
or more.
We also default the "securetls" transport TLS security level to
MUST, obviating the need for per-site table entries for secure-channel
destinations.
/etc/postfix/
main.cf:
transport_maps = hash:/etc/postfix/transport
/etc/postfix/transport:
example.com securetls:[tls.example.com]
/etc/postfix/
master.cf:
securetls unix - - n - 100 smtp
-o
smtp_enforce_tls=yes
-o
smtp_tls_enforce_peername=yes
As we decide on a "per site" basis whether or not to use TLS,
it would be good to have a list of sites that offered "STARTTLS".
We can collect it ourselves with this option.
If the
smtp_tls_note_starttls_offer feature is enabled and a
server offers STARTTLS while TLS is not already enabled for that
server, the Postfix SMTP client logs a line as follows:
postfix/smtp[pid]: Host offered STARTTLS: [hostname.example.com]
Example:
/etc/postfix/
main.cf:
smtp_tls_note_starttls_offer = yes
When verifying a remote SMTP server certificate, a verification
depth of 1 is sufficient if the certificate is directly issued by
a CA specified with
smtp_tls_CAfile or
smtp_tls_CApath. The default
value of 5 should also suffice for longer chains (where the root CA issues
a special CA certificate which then issues the actual certificate).
Example:
/etc/postfix/
main.cf:
smtp_tls_scert_verifydepth = 5
The Postfix SMTP client supports 5 distinct cipher security levels
as specified by the
smtp_tls_mandatory_ciphers configuration
parameter. This setting controls the minimum acceptable SMTP client
TLS cipher grade for use with mandatory TLS encryption. The default
value "medium" is suitable for most destinations with which you may
want to enforce TLS, and is beyond the reach of today's crypt-analytic
methods. See
smtp_tls_policy_maps for information on how to configure
ciphers on a per-destination basis.
By default anonymous ciphers are allowed, and automatically
disabled when server certificates are verified. If you want to
disable anonymous ciphers even at the "encrypt" security level, set
"
smtp_tls_mandatory_exclude_ciphers = aNULL"; and to
disable anonymous ciphers even with opportunistic TLS, set
"
smtp_tls_exclude_ciphers = aNULL". There is generally
no need to take these measures. Anonymous ciphers save bandwidth
and TLS session cache space, if certificates are ignored, there is
little point in requesting them.
Example:
/etc/postfix/
main.cf:
smtp_tls_mandatory_ciphers = medium
smtp_tls_mandatory_exclude_ciphers = RC4, MD5
smtp_tls_exclude_ciphers = aNULL
The
smtp_starttls_timeout parameter limits the time of Postfix
SMTP client write and read operations during TLS startup and shutdown
handshake procedures. In case of problems the Postfix SMTP client
tries the next network address on the mail exchanger list, and
defers delivery if no alternative server is available.
Example:
/etc/postfix/
main.cf:
smtp_starttls_timeout = 300s