The instance list assigns a security rating to your instance based in part on your instance’s score on the Mozilla Observatory, which itself is a composite of a bunch of different site security tests. (The score also uses another set of tests located on tls.imirhil.fr, but that site appears to be down right now.)
This means that in order to climb in the mastodon server ranks, you need to implement Mozilla’s recommendations. This is a good thing—everything the Observatory checks for is good, and if you’re striving for a high score, you’re doing yourself and the Internet a favor by becoming more secure.
At least for now, the max score you can get on the Mozilla Observatory is 135:
Hitting that score requires properly implementing a whole mess of different security measures. Some of them, like X-XSS protection, are extremely easy—just a quick header to add and you’re done. Others like HSTS and HPKP can actually knock your site offline if implemented incorrectly.
Cookies - The highest score possible is 0. You don’t have to do anything with this setting, as Mastodon handles its cookies satisfactorily by default.
Cross-origin Resource Sharing - The highest score possible is 0. You shouldn’t have to do anything with this line item by default—it refers to your site’s
Access-Control-Allow-Originheader and Mastodon sets it correctly by default.
Referrer Policy - The highest score possible is 5. This line item refers to the Referrer-Policy HTTP header, which controls among other things whether or not your site’s images can be hotlinked (it controls a lot more than that—the header is used by remote browsers to understand when they are and aren’t allowed to load any content from your site).
Set this header to either
strict-origin-when-cross-originfor the +5 score. Be mindful that there are security implications to these choices and you should pick the option that fits your needs.
Subresource Integrity - The highest score possible is 5. This is another item you don’t have to do anything with, as SRI is implemented natively in Mastodon as of version 1.2.
X-Content-Type-Options - The highest score possible is 0. This header tells the browser not to MIME sniff and instead to use the site’s declared content types. This header can only be set one way:
X-XSS-Protection - The highest score possible is 0. This header tells visiting browsers how to use their built-in cross-site scripting filters. Per security researcher Scott Helme, you want this set to
X-XSS-Protection = "1; mode=block".
Content Security Policy - The highest possible score is 10. CSP tells visitors’ browsers what kinds of content can be loaded, and under what context. This is an extremely flexible setting and you can control your site’s resources with a high level of granularity; it’s also a pain in the butt to get right.
Content-Security-Policystring that appears to work best with Mastodon (for now) is as follows. Obviously, replace the example URL with your own.
"frame-ancestors 'none'; default-src 'none'; script-src 'self'; object-src 'self'; style-src 'self' https://fonts.googleapis.com/ 'sha256-deDIoPlRijnpfbTDYsK+8JmDfUBmpwpnb0L/SUV8NeU=' 'sha256-dsU/1vqKDGkqSAJVJCzaxo3alnWrTU/iQqFREt5QB+g='; img-src * data:; media-src 'self' data:; frame-src 'none'; font-src 'self' data: https://fonts.gstatic.com/; connect-src 'self' wss://mastodon.example.com";
X-Frame-Options - The highest possible score is 5. If you’re using the CSP header from the previous step, you’re also taking care of this line item at the same time, with the
HTTP Strict Transport Security - The highest possible score is 5. HTTP Strict Transport Security, or “HSTS,” is a header that tells visitors’ browsers that your site should only be loaded over HTTPS, for a configurable period of time (usually set to a long duration, like a year).
There are lots of excellent blog posts on how to set up HSTS (here’s one!), but obviously doing so requires you have SSL/TLS certificates for your server. This is easiest accomplished right now by using LetsEncrypt.
Once you’ve got HTTPS working, you can implement HSTS. Start with a low duration and verify it works properly before increasing the duration. Be extremely careful—improper HSTS configuration might cause your site to become unreachable (at least until the
max-agetime period expires).
Redirection - The highest possible score is 0. Properly implementing HSTS will also take care of this line item.
HTTP Public Key Pinning - The highest possible score is 5. HTTP Public Key Pinning (HPKP) is a header that forces visiting browsers to check the fingerprint of your site’s HTTPS certificate against one of the fingerprints you provide in the header. If the fingerprints don’t match, the browser won’t load the site.
As with HSTS, there are LOTS of blog posts on how to implement HPKP (here’s one!). Getting HPKP working with LetsEncrypt can be complicated, but it’s not hard (I’m using a method similar to the one described in this post. If you’re using Cloudflare or another CDN, your pinning setup will be complicated and you will likely have to pin at the root instead of the leaf.
Getting HPKP working in a vacuum isn’t hard; getting HPKP working properly in production can be extremely difficult. And again, as with HSTS, making a mistake with HPKP can make your site unreachable, even by you.
There are plenty of other things to do to ensure you’re scoring as highly as possible on the list:
- Enable IPv6, if possible.
- Use an up-to-date cipher string for your SSL/TLS configuration—one that uses modern ciphers with perfect forward secrecy. If you don’t expect any legacy clients (i.e., folks on Android 3.x or Windows XP), disable SSLv3, TLS 1.0, and TLS 1.1 entirely and use only TLS 1.2 ciphers with perfect forward secrecy (the cipher string that works for me is:
- Keep Mastodon up to date—I use releaser to send me an email when a new tagged release appears on github.
- Keep your Mastodon instance up! Uptime is a factor in the ratings.
- Observatory includes this test, but it’s worth running the SSL Labs HTTPS scanner on your site so that you can view the full results rather than the Observatory’s summary. You should attempt to address, as soon as possible, any issues the scanner identifies.
That’s all I’ve got. Happy to answer questions, but a lot of “how do I?” type questions will depend very greatly on your specific setup. I can talk pretty intelligently about non-docker Mastodon with Nginx, Varnish Cache, and HAProxy (for SSL termination), but I don’t know a lot about implementation specifics on other platforms.
Edit - I apologize in advance for any errors in this post—it’s been a long day. Happy to correct anything that needs correcting.