Skip to content

Instantly share code, notes, and snippets.

@Tugzrida
Last active March 31, 2024 12:52
Show Gist options
  • Save Tugzrida/61235545dfc122262c69b0ab50265582 to your computer and use it in GitHub Desktop.
Save Tugzrida/61235545dfc122262c69b0ab50265582 to your computer and use it in GitHub Desktop.
MTA-STS Cloudflare worker
// 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 = {
"yourdomain.com":
`version: STSv1
mode: enforce
mx: mail.yourdomain.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})
}
@W4JEW
Copy link

W4JEW commented Jan 29, 2024

Hello! Take a look at this post:

Hosting MTA-STS .txt file on CloudFlare Workers

@BourbonCrow
Copy link

BourbonCrow commented Jan 29, 2024

Hello! Take a look at this post:

Hosting MTA-STS .txt file on CloudFlare Workers

Thanks for quick reply. But i also manged to figure it out my self.
This one you posted works really well if all domains uses same mx records, dont even need to edit the code, i might use this one cause thats the case for me

@W4JEW
Copy link

W4JEW commented Jan 29, 2024

Excellent - was it the same method as described on the page I provided the link for?

@BourbonCrow
Copy link

BourbonCrow commented Jan 29, 2024

Excellent - was it the same method as described on the page I provided the link for?

yes i used it exactly like it was on that page and it works GREAT! its this one below here. and its a global one.. setting same MX records for all domains you use this worker for

const stsPolicies =
`version: STSv1
mode: enforce
mx: mail.protonmail.ch
mx: mailsec.protonmail.ch
max_age: 86400`

async function handleRequest(request) {
  return new Response(stsPolicies, {
    headers: {
      "content-type": "text/plain;charset=UTF-8",
    },
  })
}

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

This code below here is a modified version of original code to have global MX records if you use for example proton mail where all personal domains have the exact same MX records

const stsPolicies =
`version: STSv1
mode: enforce
mx: mail.protonmail.ch
mx: mailsec.protonmail.ch
max_age: 86400`

const respHeaders = {
  "Content-Type": "text/plain;charset=UTF-8"
}

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})
  }

  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 + "\n", {status: 200, headers: respHeaders})
}

and in original code if ppl are JS illiterates like me this is how you add more then 1 domain incase your different domains require different settings

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`
}

@W4JEW
Copy link

W4JEW commented Feb 7, 2024

Could you share the contents of your Worker all in one code block instead of splitting it up across three? It's difficult to follow what the complete Worker should look like.

I've tried to emulate what's in the Gist, as well as based on your example, and whenever I go to verify the MTA-STS configuration, I get an error that the version (STSv1) cannot be detected.

Thank you!

FYI - mine currently looks like this:

const stsPolicies = {
  "domain1.com":
`version: STSv1
mode: testing
mx: aspmx.l.google.com
mx: alt1.aspmx.l.google.com
mx: alt2.aspmx.l.google.com
mx: aspmx2.googlemail.com
mx: aspmx3.googlemail.com
max_age: 604800`,
  "domain2.com":
`version: STSv1
mode: testing
mx: aspmx.l.google.com
mx: alt1.aspmx.l.google.com
mx: alt2.aspmx.l.google.com
mx: aspmx2.googlemail.com
mx: aspmx3.googlemail.com
max_age: 604800`,
  "domain3.com":
`version: STSv1
mode: testing
mx: aspmx.l.google.com
mx: alt1.aspmx.l.google.com
mx: alt2.aspmx.l.google.com
mx: aspmx2.googlemail.com
mx: aspmx3.googlemail.com
max_age: 604800`
}

const respHeaders = {
  "Content-Type": "text/plain;charset=UTF-8"
}

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})
  }

  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 + "\n", {status: 200, headers: respHeaders})
}

@BourbonCrow
Copy link

BourbonCrow commented Feb 7, 2024

@W4JEW no no you missunderstood me.. that is 2 different methods to do it.. the top 2 the first one is the one you sent me from the site.. the 2nd one is a modified version of original code. the bottom one is just explaining how to add more then 1 domain to the original code. my 2 are non domain specefic for example if all your MX records are the same for each domain you can use my code without having to add MX records for each domain individually

@W4JEW
Copy link

W4JEW commented Feb 7, 2024

I have unique MX records for several of my domains - so I have to explicitly define each domain.

So, out of your three code blocks, you're saying you can use either #1 or #2, then add multiple domains based on the example in #3?

@BourbonCrow
Copy link

BourbonCrow commented Feb 7, 2024

@W4JEW ok so if you have unique MX records for each domain .. you do it like this. if you need any help setting it up on cloudflare just ask and ill explain it

// 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 = {
  "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`,
  "yourdomain3.com":
`version: STSv1
mode: enforce
mx: mail.yourdomain3.com
mx: mailsec.yourdomain3.com
max_age: 86400`
}


const respHeaders = {
  "Content-Type": "text/plain;charset=UTF-8"
}

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})
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment