July 1, 2018

To the Cloud: Web Edition

Replacing my web server with managed services.

Background

As I described in To the Cloud: DNS Edition I had recently replaced a bunch of DNS servers with Cloudflare. This made me look around for other things to shove into the cloud. The sights soon turned to my web server, where this blog is the most public asset.

The new stack

In my Initial Post I detailed the setup I used to host this blog, one of the things living on my web server. This has now changed considerably, and instead looks like this:

Basically I have moved from running my own web server to utilizing two different managed services: S3 and Cloudflare. You might wonder why I opted to go for Cloudflare over Amazon CloudFront and this is simply because Cloudflare (like initially mentioned in my DNS article above) has the great advantage of offering a free Basic plan with no additional cost based on bandwidth or query volume.

That means that even if this site would (for some unlikely reason) get a huge amount of unexpected traffic most of that would be served by Cloudflare for free, generating a minimum amount of cost on the S3 bucket. Awesome!

The setup

While I had never used the CDN parts of Cloudflare or any AWS services before it was still fairly straight forward to get going.

S3 static website

There exists pretty good documentation on how you go about Hosting a Static Website on Amazon S3. The main thing I did differently was that I did not make the bucket publicly available, but instead added an S3 Bucket Policy only giving read access to the objects in the bucket to Cloudflare IP ranges. This was to ensure visitors would not accidentally find their way directly to the bucket.

Cloudflare CDN

Since I was already using Cloudflare for authoritative DNS all that had to be done at this point was to create a CNAME pointing to the S3 bucket and enabling "DNS and HTTP proxy (CDN)" for that record. This made the Cloudflare DNS servers replace the CNAME record with A/AAAA records pointing to their proxy service instead.

To make the proxy service cache as much as possible I also needed to create a Cloudflare Page rule that contained Cache Level: Cache Everything. I also enabled HTTP-to-HTTPS rewrites utilizing Cloudflare Universal SSL.

Areas of improvement

HTTPS all the way

An S3 bucket only supports HTTP connections and to make this work I have configured my Cloudflare site to use Flexible SSL meaning that a client uses HTTPS connections to the proxy service, but the backend requests to S3 uses ordinary HTTP. Now, I wouldn't trust content on this blog even with HTTPS all the way, but it is still a nice thing to aim for.

Improved S3 bucket protection

Using an S3 bucket policy to only allow requests from Cloudflare seems like a decent way to protect against cost generated by people accidentally finding the site directly on S3. For a malicious user it is still possible to generate cost by performing denied queries to the bucket, because as can be seen here and here you are still charged for the requests causing 403 Forbidden errors.