Please enable JavaScript to view the comments powered by Disqus.

Problems When Setting Up WriteFreely Part 1: HTTP Strict Transport Security (HSTS)

There are two ways to set up a WriteFreely instance.

  1. As a standalone application & web server
    • supports SSL out-of-the-box
    • effortless
  2. Behind a reverse proxy (apache2, nginx, etc)
    • requires manual configuration of SSL
    • more effort

Months ago, I already tried the standalone approach. This time, I wanted to try the reverse proxy one.

So, I configured writefreely to run behind nginx. To keep it simple, I ignored setting up SSL. All I wanted initially was to see my blog on http://teddyh.dev.

And... that failed.

Connection timeout for teddyh.dev

I was surprised to see https instead of http in the address. I kept changing it to http, but my browser insisted on https. In retrospect, it was foolish to keep trying the same thing but expecting a different outcome.


It is debug o'clock

It took me a while, but I finally figured it out.

I first tried curling http://teddyh.dev to check whether this issue is related to my browser or my setup. The request went through. I could see the HTML document in the response. That confirmed my setup was fine. So, this must be a browser-related issue.

Why couldn't I access http://teddyh.dev from my browser, then? I tried Chrome, Firefox, and iOS Safari. All of them failed to display my blog.

I pulled up the dev tools to inspect. This is what I saw: Image

A 307 Internal Redirect and HSTS?

HSTS rang a bell... I vaguely recall having read something about HSTS (HTTP Strict Transport Security) on Hackernews. I read about HSTS again to refresh my memory. Apparently, when a modern web browser attempts to load a site whose domain name is in the HSTS preloaded list, it will strictly use https.

So, is teddyh.dev on the HSTS preloaded list?

Apparently! In fact, anything that ends with .dev is HSTS preloaded.

.dev in hsts preloaded list

That means my browser switched from http to https when it tries to load teddyh.dev. Of course, I couldn't access my blog. I configured nginx to only listen to port 80 (http). There was nothing for port 443 (https).

FYI, this redirection from http to https is done by the browser itself. No http packet was sent to the server — only https.

So, to circumvent this issue, I ran WriteFreely on standalone mode. The standalone mode comes with a convenient automatic SSL support. I still want to introduce nginx and certbot, but that comes later.

By the way, in the first screenshot above, notice that the error was a connection timeout. That is the prequel to the next part in this series. Stay tuned!