How I am handling http to https upgrades these day.
Hithertofore I have caught all port 80 requests to my web sites and helpfully redirected them to https on port 443. But not everyone wants to have an SSL capable browser, and SSL on a tiny embedded device which you expect to run for more than 10 years without a firmware replacement is a mess.
Enter Upgrade-Insecure-Requests
Some modern browsers will send a Upgrade-Insecure-Requests: 1
header when they request a non-SSL resource. This instructs the server that the browser would be happy to use SSL if only the server could redirect it to an appropriate URL.
I'm using nginx
for all my web servers these days. (I tried caddy
and was largely liking it, but got tripped up on X-Accel-Redirect
support which is required by this blog software among other things.) So, here is a sketch of my nginx configuration file for a simple web site.
server {
server_name yourserver.example.com;
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443;
… A bunch of site configuration which is not germane …
# Concatenating two values to get cheap logic: "on1" "on" "1" "" are possible here.
set $do_http_upgrade "$https$http_upgrade_insecure_requests";
location / {
if ($do_http_upgrade = "1") {
add_header Vary Upgrade-Insecure-Requests;
return 307 https://$host$request_uri;
}
index index.html;
}
}
The important takeaways here are:
-
I'm doing all my
listen
in the same server block -
That
$do_http_upgrade
variable is making a cheapand
function by concatenating two values so when I check for"1"
I am testing not https and upgrade_insecure_requests present. -
Down in the
location
I do the redirect if requested and needed. -
That
vary
header comes from an MDN example. Maybe it will keep some forsaken middleware box from inappropriately caching the upgrade, but I'm sure there are ones where it won't. Their problem. Not mine. You might also try a never cache header to try to keep the middleware boxes from breaking your site.