KiwiFarms is a harassment website, sort of like a terrorism-only variation on the *chan sites. It specializes in harassing trans people. It doxxes them, SWATs them and their families, and does its best to drive its victims off the internet. It also has a bodycount. They are a troll farm.
Kiwifarms gets to do this and stay on the internet because they’re being protected by Cloudflare. Cloudflare has a long history of protecting incredibly vile content: they were recently infamous for hosting Daily Stormer.
Cloudflare is exceptional in its position. From the Time article:
“We find anecdotally that sites prefer Cloudflare because of its lax acceptable use policies and its free DDoS protection services that help protect against vigilante attacks,” the researchers write. They note that AmmoLand, a popular guns rights blog, has praised the company “for its self-described ‘content-neutral’ stance.”
Cloudflare takes a freezepeach position on free speech: they do not acknowledge the reality that in order to protect the free speech of the many, we cannot tolerate the abusive behavior of the few. Cloudflare protects the abusers instead.
Liz Fong-Jones has been leading the current pressure campaign against Cloudflare most effectively.
Why this matters to me
When I set up my blog, I hosted it in an S3 bucket behind Cloudflare, using their free plan because I have very simple needs for it. I do not want to lend them even that little support, so today I moved my blog to Fastly.
I moved my last two employers to Cloudflare from other CDNs. I won’t be repeating that mistake until they shape up and start removing Nazis and troll sites without needing pressure campaigns to move them. I treasure my friends and it is unacceptable to me that some of them go through their lives afraid for their personal safety because of sites like Kiwifarms.
You might decide that freeloading off of Cloudflare is fine, because you’re siphoning resources from them. You might also be unable to pay for another CDN. Only you know your circumstances. I have the disposable income to spend a little more than I spend now on my AWS hosting bill on a CDN provider who doesn’t have to be pressured over and over again to boot sites like Daily Stormer and KiwiFarms.
This is how I did it, very short version:
Steps were:
- set everything up in fastly
- tell fastly about my certs
- verify that their test url worked
- duplicate all my dns setup in route53
- cut over name servers with my registrar to route 53
The rest of this blog post goes into what I did in more detail, in the hope that I can reassure you it’s very do-able.
By hand, in more detail
- Create a Fastly account. (Set up 2FA!)
- Scan through Fastly’s getting started guide. The concepts here are different from Cloudflare’s concepts. Fastly is (oversimplifying a bit) a nice front end to Varnish & VCL plus a lot of POPs around the world to reduce latency to your users. VCL can do a lot. You end up with a lot more control over how things get routed, but the cost is more complexity to cope with.
- Give Fastly a credit card so you can enable TLS.
Now let’s do the switch:
- Find a new home for all of your DNS records. I used AWS’s Route 53 as my name server because I am very comfortable with it. Your domain registrar might provide name service; all the major cloud providers also do.
- Duplicate all of the DNS you’ve set up in Cloudflare over in your new DNS provider. Your goal is to avoid downtime when you cut over from Cloudflare to your new nameservers.
- Now set up a delivery service in Fastly. This is a backend – the place the data comes from – plus a domain that is the face of the service – the hostname people type into their browsers. You’re setting up a mapping from domain to data source. For me, the back end is the AWS S3 bucket that holds my blog assets, and the domain name is what you see in your browser right now.
- Make the service active. Fastly now gives you a test domain name, like
blog.ceejbot.com.global.prod.fastly.net
, to verify that your content is available as you expect.
Now the slowest part: do something about your TLS certs. Because I am old-fashioned and I haven’t automated all this yet, I buy certs from my name registrar. You can also use AWS ACM, which automates things pretty well. Fastly will help you set up Let’s Encrypt, which is probably the best option for most people.
Once Fastly is aware of your cert material somehow, you are ready to cut over. You can do this in two phases. The first phase is a double-CDN phase:
- Update your domain in Cloudflare to point to the Fastly TLS domain they gave you when you set up TLS.
- Turn off proxying in Cloudflare. Make the orange cloud gray.
Now your content should be served by Fastly instead of Cloudflare. You should see the headers change to something like this:
$ http HEAD https://blog.ceejbot.com
HTTP/1.1 200 OK
Accept-Ranges: bytes
Age: 518
Connection: keep-alive
Content-Length: 7149
Content-Type: text/html
Date: Sat, 27 Aug 2022 23:22:43 GMT
ETag: "464e0930f8616e07530366dfa7ba0567"
Last-Modified: Sat, 23 Jul 2022 20:01:40 GMT
Server: AmazonS3
Via: 1.1 varnish
X-Cache: HIT
X-Cache-Hits: 1
X-Served-By: cache-pao17472-PAO
X-Timer: S1661642564.606369,VS0,VE35
x-amz-id-2: E2eXc0YfBq4rX2rGhwOWZMbU26NYxzGcaAzlQ7+E/zHhcp19RIpct8WwFIaDQEy6TWuhluNf1ng=
x-amz-meta-md5chksum: 464e0930f8616e07530366dfa7ba0567
x-amz-request-id: 9V54SNWKBG95XYY3
Varnish is serving my content! It’s working! Now you can safely take the last step: switch your domain’s name servers over to something other than Cloudflare. It might take a day or so for the global cache of caches that is DNS to update itself. If all went well, you switched without downtime!
Automation
I did not use the websites to do this: I used Terraform because I automate all of my personal infrastructure. It’s good practice, I tell myself. To use terraform you need to make an API key on the Fastly dashboard. Save it in your favorite password manager, then export it in the environment variable FASTLY_API_KEY
.
Set up the official terraform provider. Here’s my providers.tf
file:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
fastly = {
source = "fastly/fastly"
version = ">= 2.2.1"
}
}
}
Here’s the important part of my blog service in Terraform:
resource "fastly_service_vcl" "blog" {
name = "blog.ceejbot.com"
activate = true
domain {
name = "blog.ceejbot.com"
comment = "the blog"
}
backend {
address = "blog.ceejbot.com.s3-website-us-west-2.amazonaws.com"
name = "the s3 bucket"
port = 80
shield = "pdx-or-us"
}
}
This terraform fragment sets up DNS so Fastly handles requests to my content:
resource "aws_route53_zone" "ceejbot-com" {
name = "ceejbot.com"
}
resource "aws_route53_record" "blog" {
zone_id = aws_route53_zone.ceejbot-com.zone_id
name = "blog.ceejbot.com"
type = "CNAME"
records = [
"n.sni.global.fastly.net",
]
ttl = 3600
}
This isn’t all of the terraform in my setup. I also have a policy on the S3 bucket restricting access to it to Fastly’s public IP list. That’s a reasonable practice to prevent an accidental gigantic AWS egress cost.
You can do a lot more with VCL and Varnish if you feel inclined. For a while through the mid teens, all of NPM’s registry traffic was proxied through Fastly, with a carefully maintained custom varnish file routing things as much as possible at the edge. Most of us won’t need that power, but it’s available if you do.