The MTA-STS policy (MTA Strict Transport Security) is to prevent Man-In-The-Middle attacks by publishing authorized mail servers and prevent TLS downgrade attacks (Opportunistic TLS), when both parties support MTA-STS. MTA-STS is easier to implement over DANE with DNSSEC, which is expected to get inbound support in Exchange Online next year. Since I am using WordPress to host this blog, I was looking for ways to host the policy file for MTA-STS at the required location, as hosted WordPress does not offer this possibility.
There is documentation describing how to accomplish this using, for example, Azure Static Web Sites, but this requires an Azure subscription. There are also 3rd parties offering hosted MTA-STS, which are usually not free.
Then I stumbled upon the possibility of using a custom domain with GitHub pages, which can be used for this. So, here is a quick write-up on how to host your MTA-STS policy file on GitHub using GitHub Pages. This process could also be used when needed for hosting other files on GitHub.
Hosting MTA-STS Policy using GitHub Pages
Start by creating a new repository in GitHub. You can name it anything you want, but for the sake of the example, I called it mta-sts. Make sure it is public.
Next, we must create an empty file called .nojekyll in the repository. This file will instruct GitHub not to build pages, and just serve your files. So, Add file > Create new file, enter .nojekyll as Name your file and Commit changes.
Now, create the policy file that needs to be named mta-sts.txt in the .well-known folder file, select Add file > Create new file and enter .well-known/mta-sts.txt as the name of your file. This will also create the required folder. In the contents field, paste your policy. For example, the MTA-STS policy file when using only Exchange Online for receiving e-mail could look something like this:
version: STSv1
mode: testing
mx: *.mail.protection.outlook.com
max_age: 604800
When done, commit your changes to store the policy file on GitHub. For more information on the MTA-STS policy file definition, click here.
Next, we need to enable GitHub Pages for this repository. Go to Settings, and select the Pages tab. Under Branch, select the branch you want to publish, eg. main, and press Save. Note that GitHub Pages are served using a valid 3rd party certificate, which satisfies one of the requirements for MTA-STS.
New options should now appear on the GitHub Pages settings, one of which is Custom domain. If you decided to use a custom domain in the previous step, enter it here, eg. mta-sts.contoso.com, and click Save.
GitHub will start to check DNS for the presence of this domain. Time to head over to your ISP portal, and create the required records in DNS.
First, if you used a custom domain for hosting the MTA-STS policy, create a CNAME mta-sts record for your domain pointing to <user>.github.io or <org>.github.io, e.g.
mta-sts.contoso.com CNAME 3600 user.github.io
Next, create the DNS TXT _mta-sts record to indicate MTA-STS support, e.g.
_mta-sts.eightwone.com TXT 3600 v=STSv1; id=202310041637
Note that you need to update ‘id,’ usually with timestamp yyyymmddhhmm, whenever you make changes to the policy. This indicates to MTA-STS supporting hosts there has been a change on your end.
You are now set. After DNS some time for DNS to propagate changes, you can start verifying your configuration by browsing https://mta-sts.contoso.com/.well-known/mta-sts.txt, which should return your policy file without any certificate prompts. You can verify DNS and policy access using websites like MxToolbox or PowerDMARC. The example below was generated using EasyDMARC:
TLS Reporting
In addition to setting up MTA-STS, you can configure TLS Reporting (TLS-RPT). This will instruct supporting servers to report on TLS usage and mention certificate issues, for example. Note that these are reports on inbound messages, whereas Exchange Online offers information on outbound TLS usage. To set up TLS-RPT, configure a DNS TXT record _smtp._tls and specify a recipient for these reports, e.g.
_smtp._tls.contoso.com TXT 3600 v=TLSRPTv1; rua=mailto:tlsreports@contoso.com
The rua field contains the e-mail address where reports should be sent. You can process these reports in JSON format yourself or have one of the 3rd parties offering this service do this for you. The example below is generated by Dmarcian.