MTA-STS for Postfix
- Tutorial
MTA-STS is the proposed RFC8461 standard that has gone out of draft status and officially published on September 26, 2018. This standard offers a mechanism for detecting the possibility of using full TLS between mail servers, with data encryption and server authentication. That is, this standard almost completely protects against interference with mail traffic between servers.
Simplified, the essence of the standard is as follows:
There are good articles ( for example ) that talk about the standard itself and why it is needed, comparing MTA-STS with other similar initiatives, and even showing how to write and publish a policy. But finding how to go beyond the first step was not so simple.
Before implementing MTA-STS, you need to tidy up the mail server certificates. Otherwise, mail servers that take into account your STS policy will reject the connection to your server. The following conditions must be met:
You can verify the configured server with the certificate with the following command:
where MX.EXAMPLE.COM is the domain name of your MX server. For full compliance with the standard, it is advisable to verify that the desired domain name is present not only in the Common Name of the certificate, but at least in the Subject Alternative Name.
In order to designate your domain as supporting a secure connection with it, you need to publish the MTA-STS policy. To do this, perform the following simple steps in the specified order (examples are given for the domain example.com).
1. Place at
text file of the form:
The file must be given with Content-Type: text / plain. Redirects are not allowed. Line feeds must be either LF or CRLF. Empty lines are not allowed. The last line may end with a line feed, or it may not end with it - both options are allowed. Empty space before the colon and at the beginning of the line is not allowed. The empty space after the colon is allowed in any quantity. White space (spaces, tabs, etc.) at the end of each line is ignored.
Field Values:
version : format version. It should always be equal to "STSv1".
mode: policy mode. Possible options: none, testing, enforce. Enforce mode corresponds to the normal functioning of the standard - to require the correct certificate and a stable TLS connection when connecting to the server. The testing mode requires you to try to use a secure connection, but in case of an error send mail in any case with administrator notification through the TLSRPT mechanism. None mode corresponds to the situation as if the policy was not published at all. This mode is useful for properly disabling a policy.
mx : one or more fields containing the names of all allowed MX domain servers. As you can see from the example, templates are allowed, but only as a lower-level domain.
max_age: The time in seconds that a policy can be cached and during which senders can continue to use it if the policy is no longer available. Due to this feature of the standard, disabling STS is faster by publishing a new policy with none mode.
2. Create a TXT record _mta-sts.example.com with the contents of the form:
Whitespace around a semicolon can be arbitrarily arranged in any quantity. In other places, whitespace is not allowed. The last semicolon can be either present or absent.
Field Values:
v : format version. It must always be the first field, it must always be equal to STSv1.
id : unique identifier of the published policy. It can be a string with a length of 1-32 characters, consisting of letters of both registers and numbers. Changing the id value is a signal to senders that the policy has been updated. Therefore, you need to update the policy by first publishing a new policy file, and then changing the id in the TXT record.
From now on, mail servers that support MTA-STS will only send mail to your domain through a secure certificate-authenticated connection. That’s where most of the manuals end, but the most interesting part ahead is to get the MTA-STS policy from your own server when sending mail.
The main difficulty is that this standard is not supported by mail servers, including Postfix. However, this unpleasant trifle should not stop us.
Finding a solution led me to the postfix-users mailing list archive discussing the timing of this standard. In one post, Witsa Venema, author of Postfix, points out the preferred direction for implementing this functionality - to use an external server to search for TLS policies. It is proposed to use a configuration directive of the form
I implemented such a server to get the MTA-STS policy.
→ Source code
→ A package in PyPI The
application lacks some of the functions that RFC8461 prescribes, such as: proactive policy retrieval, reports, and limiting the frequency of policy requests. However, the main function — detecting the TLS policy and caching it — it performs.
The app requires Python 3.5.3+. Installing and configuring this daemon can be done using the following steps.
It is enough to run the command:
Alternative installation methods are written here .
If you are satisfied with the default settings, then the command is enough
Otherwise, the configuration can be taken from the example and tailored to fit your needs.
The most important parameter, in my opinion, is the strict_testing parameter. If it is set to true (false by default), the application will return a secure policy even for domains with a policy in testing mode. This behavior is against the standard, but it is advisable for practical reasons: if the domain owner has published the STS policy even in test mode, then he is probably ready for it. That is, then today gmail.com mail will be sent over a reliable connection.
In the case of systemd, it is enough to place a simple unit-file in /etc/systemd/system/mta-sts-daemon.service
After that, it remains to re-read the systemd configuration, enable the daemon to start and start it:
Assuming that the default port is used, the command
should bring
Add a line to main.cf:
Restart Postfix:
If everything is done correctly, then for STS connections in the /var/log/mail.info log instead
records start to appear
If you get to this place, it most likely means:
Simplified, the essence of the standard is as follows:
- Supporting mail services publish a policy (1 TXT record and 1 HTTPS resource for each domain).
- Mail services when sending mail to other domains detect the recipient domain policy.
- Mail services connect to the mail server of the recipient domain, applying the TLS restrictions set by the detected policy, if any.
There are good articles ( for example ) that talk about the standard itself and why it is needed, comparing MTA-STS with other similar initiatives, and even showing how to write and publish a policy. But finding how to go beyond the first step was not so simple.
Start over
Before implementing MTA-STS, you need to tidy up the mail server certificates. Otherwise, mail servers that take into account your STS policy will reject the connection to your server. The following conditions must be met:
- The server certificate is issued by a recognized certification authority (Let's Encrypt is good).
- The certificate chain sent by the server includes all the necessary certificates of intermediate certification authorities.
- The certificate has a Subject Alternative Name field with the DNS name of your MX server.
You can verify the configured server with the certificate with the following command:
[ "$(LANG=C openssl s_client -connect MX.EXAMPLE.COM:25 -starttls smtp -verify_hostname MX.EXAMPLE.COM < /dev/null 2>&1 | fgrep 'error')" = "" ] && echo OK || echo FAIL
where MX.EXAMPLE.COM is the domain name of your MX server. For full compliance with the standard, it is advisable to verify that the desired domain name is present not only in the Common Name of the certificate, but at least in the Subject Alternative Name.
Policy posting
In order to designate your domain as supporting a secure connection with it, you need to publish the MTA-STS policy. To do this, perform the following simple steps in the specified order (examples are given for the domain example.com).
1. Place at
https://mta-sts.example.com/.well-known/mta-sts.txt
text file of the form:
version: STSv1 mode: enforce mx: mail.example.com mx: * .example.net mx: backupmx.example.com max_age: 604800
The file must be given with Content-Type: text / plain. Redirects are not allowed. Line feeds must be either LF or CRLF. Empty lines are not allowed. The last line may end with a line feed, or it may not end with it - both options are allowed. Empty space before the colon and at the beginning of the line is not allowed. The empty space after the colon is allowed in any quantity. White space (spaces, tabs, etc.) at the end of each line is ignored.
Field Values:
version : format version. It should always be equal to "STSv1".
mode: policy mode. Possible options: none, testing, enforce. Enforce mode corresponds to the normal functioning of the standard - to require the correct certificate and a stable TLS connection when connecting to the server. The testing mode requires you to try to use a secure connection, but in case of an error send mail in any case with administrator notification through the TLSRPT mechanism. None mode corresponds to the situation as if the policy was not published at all. This mode is useful for properly disabling a policy.
mx : one or more fields containing the names of all allowed MX domain servers. As you can see from the example, templates are allowed, but only as a lower-level domain.
max_age: The time in seconds that a policy can be cached and during which senders can continue to use it if the policy is no longer available. Due to this feature of the standard, disabling STS is faster by publishing a new policy with none mode.
2. Create a TXT record _mta-sts.example.com with the contents of the form:
v = STSv1; id = 20160831085700Z;
Whitespace around a semicolon can be arbitrarily arranged in any quantity. In other places, whitespace is not allowed. The last semicolon can be either present or absent.
Field Values:
v : format version. It must always be the first field, it must always be equal to STSv1.
id : unique identifier of the published policy. It can be a string with a length of 1-32 characters, consisting of letters of both registers and numbers. Changing the id value is a signal to senders that the policy has been updated. Therefore, you need to update the policy by first publishing a new policy file, and then changing the id in the TXT record.
From now on, mail servers that support MTA-STS will only send mail to your domain through a secure certificate-authenticated connection. That’s where most of the manuals end, but the most interesting part ahead is to get the MTA-STS policy from your own server when sending mail.
The most interesting
The main difficulty is that this standard is not supported by mail servers, including Postfix. However, this unpleasant trifle should not stop us.
Finding a solution led me to the postfix-users mailing list archive discussing the timing of this standard. In one post, Witsa Venema, author of Postfix, points out the preferred direction for implementing this functionality - to use an external server to search for TLS policies. It is proposed to use a configuration directive of the form
smtp_policy_maps = socketmap: inet: host: port: name
I implemented such a server to get the MTA-STS policy.
→ Source code
→ A package in PyPI The
application lacks some of the functions that RFC8461 prescribes, such as: proactive policy retrieval, reports, and limiting the frequency of policy requests. However, the main function — detecting the TLS policy and caching it — it performs.
The app requires Python 3.5.3+. Installing and configuring this daemon can be done using the following steps.
Package installation
It is enough to run the command:
pip3 install postfix-mta-sts-resolver
Alternative installation methods are written here .
Creating a configuration file
If you are satisfied with the default settings, then the command is enough
touch /etc/postfix/mta-sts-daemon.yml
Otherwise, the configuration can be taken from the example and tailored to fit your needs.
The most important parameter, in my opinion, is the strict_testing parameter. If it is set to true (false by default), the application will return a secure policy even for domains with a policy in testing mode. This behavior is against the standard, but it is advisable for practical reasons: if the domain owner has published the STS policy even in test mode, then he is probably ready for it. That is, then today gmail.com mail will be sent over a reliable connection.
Startup Organization
In the case of systemd, it is enough to place a simple unit-file in /etc/systemd/system/mta-sts-daemon.service
After that, it remains to re-read the systemd configuration, enable the daemon to start and start it:
systemctl daemon-reload
systemctl enable mta-sts-daemon.service
systemctl start mta-sts-daemon.service
Health Check
Assuming that the default port is used, the command
/usr/sbin/postmap -q dismail.de socketmap:inet:127.0.0.1:8461:postfix
should bring
secure match = mx1.dismail.de
Connect to Postfix
Add a line to main.cf:
smtp_policy_maps = socketmap:inet:127.0.0.1:8461:postfix
Restart Postfix:
systemctl reload postfix.service
If everything is done correctly, then for STS connections in the /var/log/mail.info log instead
Trusted TLS connection established
records start to appear
Verified TLS connection established
Conclusion
If you get to this place, it most likely means:
- You read the article without a single image.
- From day to day, the probability of interception of mail in your domain will fall, as other mail services implement the new standard.