An MTA-STS (Mail Transfer Agent Strict Transport Security) policy is essential for securing your emails with both encryption and authentication. This helps prevent potential and malicious MITM (man-in-the-middle) attacks which involve interception and tampering during transit through SMTP (Simple Mail Transfer Protocol) used by mail providers. MTA-STS is a fairly new standard which makes email communication much more secure, and has been adopted by Google only a few years ago and Microsoft as of last year. If you have and use your own domain for email, you will need to create, configure and publish your own MTA-STS policy.
Creating a policy Link to heading
My MTA-STS policy is published and can be accessed at
https://mta-sts.agha.dev/.well-known/mta-sts.txt. For your domain, this similarly requires defining and configuring your policy in an
mta-sts.txt file under a
.well-known directory at the root of an
mta-sts subdomain. In a Hugo repository, for
.well-known to be at the root of your site, it should go under the
/static directory at the root of your repository. The
mta-sts.txt file should have the following contents:
version: STSv1 mode: enforce mx: mail.protonmail.ch mx: mailsec.protonmail.ch max_age: 604800
versioncurrently adopted is
modecan be either
nonedisables the policy.
testingonly evaluates the policy without enforcing it and requests reports via TLS-RPT.
enforceactively enforces the policy and connection security.
mxvalues depend on the MX (mail exchange) servers of your mail provider. I use Proton Mail which uses
mailsec.protonmail.chas MX servers.
max_agevalue is how long (in seconds) the policy is cached, which is set to a recommended
My site repository is hosted on GitHub and I came across this excellent article on Hosting your MTA-STS policy using GitHub Pages and used it for hosting my policy. However, later on I felt that having or maintaining a separate repository (or even branch) just for my MTA-STS policy was not the most efficient approach, and I wanted to keep things as minimal as possible and have everything related to my website in one single repository.
This can be easily done by creating a different branch (
mta-sts) within my site repository, but having a different branch just to serve one file was also not the most efficient or minimal approach, especially when I already have a
.well-known directory in my main branch where other files are served under my base domain (such as those needed for my Mastodon alias).
mta-sts.txt policy configuration file under the
.well-known directory in my main branch was the best approach, but there was one problem. This would serve it from my base domain
agha.dev rather than the
Redirects and rewrites Link to heading
This is where Netlify redirects and rewrites, as ever, come in handy. To solve this, defining some redirects and rewrites in my
netlify.toml file was needed as follows:
[[redirects]] from = "https://mta-sts.agha.dev/.well-known/mta-sts.txt" to = "https://agha.dev/.well-known/mta-sts.txt" status = 200 [[redirects]] from = "https://mta-sts.agha.dev/*" to = "https://mta-sts.agha.dev/.well-known/mta-sts.txt" status = 302 force = true
The first redirect rule uses the HTTP 200 code and essentially does a rewrite by making use of rewrites and proxying. This means that when
https://mta-sts.agha.dev/.well-known/mta-sts.txt is visited, the server responds with
https://agha.dev/.well-known/mta-sts.txt without changing the URL in the address bar of the browser.
The second redirect rule is a simple HTTP 302 redirect and uses a
* wildcard. which makes it so that visiting the
https://mta-sts.agha.dev subdomain always redirects to my MTA-STS policy configuration in
mta-sts.txt, no matter what’s typed after the URL. This is important because this subdomain is not going to be used for serving anything else other than my MTA-STS policy, and due to how the DNS records are configured in Netlify, not having this redirect would instead make the URL serve my website rather than the policy.
If we visit
https://mta-sts.agha.dev/.well-known/mta-sts.txt, we can see that my policy is successfully returned and served from the correct URL. For short, it can also be accessed at
https://mta-sts.agha.dev, but the full URL is what mail servers need and look for when checking for an MTA-STS policy.
DNS records Link to heading
Lastly, in order to enable MTA-STS and signal that my domain supports it, a DNS record should be defined as follows:
id is set as the current time in epoch (UNIX) time (the amount of seconds since 1 January 1970).
1666328180 refers to October 21, 2022, which is the time I created and published my policy. It needs to be unique and updated every time any changes or updates are made to the policy. An epoch converter is useful.
To add and enable TLS-RPT (SMTP TLS Reporting) reports for statistics such as successes and failures, I use Report URI to collect the reports and have the following DNS record added:
This sends reports to
email@example.com, which allows the reports and statistics to be displayed in my Report URI dashboard. It can be substituted for one of my emails, but using a service like Report URI collects and aggregates the reports and displays them to be visualized in a nicer way through graphs.
After setting up MTA-STS and TLS-RPT, Hardenize shows that my domain is properly hardened and secured for email.