使用Cloudflare Workers託管MTA-STS.txt檔案

MTA-STS縮寫為Mail Transfer Agent-Strict Transport Security,目的是強化SMTP的連線安全性,可以參考Google文件〈關於MTA-STS和傳輸層安全標準(TLS)報告〉的說明。因為我自己是用iCloud自訂電子郵件網域,需自行設定才能支援MTA-STS。

MTA-STS的詳細設定請參考〈How to Set Up MTA-STS and TLS Reporting to Identify and Fix Email Security Issues〉,其中MTA-STS.txt通常是放在自己的主機,但有些網友則是將MTA-STS.txt託管在Cloudflare Workers。

步驟很簡單,到Cloudflare Workers開一個新的應用程式,程式碼參考〈MTA-STS Cloudflare worker〉,只有前面幾行的網域和MX名稱要改:

// This worker is designed to be able to neatly handle MTA-STS policies for multiple domains.

// Make a new worker with this script and add your domains to the stsPolicies dict like the example.
// Add a DNS AAAA record for mta-sts.yourdomain.com pointing to 100:: and set to proxied,
// then add a workers route for mta-sts.yourdomain.com/* pointing to this worker.

// You'll still need to manually add the appropriate _mta-sts.yourdomain.com TXT record to enable the policy, 
// and the _smtp._tls.yourdomain.com TXT record for reporting.

const stsPolicies = {
  "mynet.tw":
`version: STSv1
mode: enforce
mx: mx01.mail.icloud.com
mx: mx02.mail.icloud.com
max_age: 86400`
}


const respHeaders = {
  "Content-Type": "text/plain;charset=UTF-8",
  "X-Clacks-Overhead": "GNU Terry Pratchett, Jon Postel, Alan Turing, Dan Kaminsky"
}

addEventListener("fetch", event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const reqUrl = new URL(request.url)

  if (!reqUrl.hostname.startsWith("mta-sts.")) {
    return new Response(`Incorrect worker route. mta-sts policies must be served on the mta-sts subdomain\n`, {status: 500, headers: respHeaders})
  }

  const policyHost = reqUrl.hostname.slice(8)

  if (!stsPolicies.hasOwnProperty(policyHost)) {
    return new Response(`${policyHost} is not defined in the mta-sts worker\n`, {status: 500, headers: respHeaders})
  }

  if (reqUrl.protocol !== "https:" || reqUrl.pathname !== "/.well-known/mta-sts.txt") {
    reqUrl.protocol = "https:"
    reqUrl.pathname = "/.well-known/mta-sts.txt"
    return Response.redirect(reqUrl, 301)
  }

  return new Response(stsPolicies[policyHost] + "\n", {status: 200, headers: respHeaders})
}

將該Worker新增一個子網域:

mta-sts.mynet.tw

DNS再新增一個TXT紀錄(id可以隨便取,1~32個英文字母和數字):

_mta-sts.mynet.tw IN TXT "v=STSv1; id=12345678"

最後用Mailhardener MTA-STS validator測試設定是否正確。