使用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 should probably also create a Cloudflare configuration rule disabling Browser Integrity Check for the mta-sts subdomain // to ensure MTAs aren't blocked from retrieving your policy. // 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}) }
上面的程式碼,支援多網域,前面幾行可以這樣改:
const stsPolicies = { "yourdomain1.com": `version: STSv1 mode: enforce mx: mail.yourdomain1.com mx: mailsec.yourdomain1.com max_age: 86400`, "yourdomain2.com": `version: STSv1 mode: enforce mx: mail.yourdomain2.com max_age: 86400` }DNS新增AAAA紀錄,要開Proxy:
mta-sts.mynet.tw IN AAAA 100::在該網域新增一個Workers路由,內容如下:
路由 mta-sts.mynet.tw/* Worker your-mta-sts-workers.yourname.workers.dev在該網域的WAF新增一個規則:
完整URI 等於 https://mta-sts.mynet.tw/.well-known/mta-sts.txt運算式預覽如下:
(http.request.full_uri eq "https://mta-sts.mynet.tw/.well-known/mta-sts.txt")再來是採取動作選擇
跳過,要跳過的WAF元件選擇瀏覽器完整性檢查,最後點儲存。DNS新增MTA-STS TXT紀錄,id可以隨便取,1~32個英文字母和數字:
_mta-sts.mynet.tw IN TXT "v=STSv1; id=12345678"DNS新增TLS-RPT(SMTP TLS Reporting) TXT紀錄,rua是接收報告的信箱:
_smtp._tls.mynet.tw IN TXT "v=TLSRPTv1; rua=mailto:tlsrpt@mynet.tw"
最後用MTA-STS Validator驗證設定是否生效。