Problems When Setting Up WriteFreely Part 1: HTTP Strict Transport Security (HSTS)
There are two ways to set up a WriteFreely instance.
- As a standalone application & web server
- supports SSL out-of-the-box
- effortless
- 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.
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 curl
ing 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:
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.
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!