Redirect users to HTTPS only if HTTP v2 or higher is detected on plaintext HTTP

To deal with a situation where some very old browsers are being used on one of my site for unfortunate legitimate reasons, I would like to try to use an opportunistic model for HTTPS where possible.

If HTTP v2 or higher is being used, I would like to make it so that Cloudflare redirects the user to HTTPS. I have already pre-configured HSTS, but that does nothing if the user were to visit the vanilla HTTP site first.

I’ve tried to use the opportunistic options in the Cloudflare settings, but, when testing this using vanilla netcat, it hasn’t sent a location header to use HTTPS instead in such circumstances.

HTTP 2 typically always is on SSL. So you wouldn’t need to redirect in the first place.

You probably should simply set “Always use HTTPS” and you are good to go.

HTTP 2 typically always is on SSL.

If it was, then it wouldn’t be ignoring the Strict-Transport-Security header and the browser would be ensuring all links are HTTPS.

You probably should simply set “Always use HTTPS” and you are good to go.

Well, no, because that will lock out the particulaly old browsers unfortunately.

What is “particularly old”? Which browser would not support HTTPS?

Are you saying HTTP 2 is served via an http:// link? Can you provide an example link?

What is “particularly old”? Which browser would not support HTTPS?

This is involving late 90s, early 2000s browsers on vintage hardware. While they support a form of HTTPS, it is definately not compatible.

Can you provide an example link?

<snip … no longer necessary>

Even these browsers should support HTTPS, however they probably only support SSL and no TLS. On Cloudflare this might be an issue.

So what is it you want to achieve? You want to serve these old browsers without an obligatory HTTPS redirect, but still want to redirect “modern” browsers to HTTPS? Preloaded HSTS should be your best bet in this case.

HSTS on HTTP will always be ignored, this is not HTTP 2 specific

Note: The Strict-Transport-Security header is ignored by the browser when your site is accessed using HTTP; this is because an attacker may intercept HTTP connections and inject the header or remove it. When your site is accessed over HTTPS with no certificate errors, the browser knows your site is HTTPS capable and will honor the Strict-Transport-Security header.

Even these browsers should support HTTPS, however they probably only support SSL and no TLS. On Cloudflare this might be an issue.

Aye, precisely.

So what is it you want to achieve? You want to serve these old browsers without an obligatory HTTPS redirect, but still want to redirect “modern” browsers to HTTPS?

That’s pretty much it in a nutshell!

Preloaded HSTS should be your best bet in this case.

I will give it a whirl; will need to wait for that prepopulation though.

HSTS on HTTP will always be ignored, this is not HTTP 2 specific

Sure, but that was in response to "HTTP 2 typically always is on SSL. ", although right now I’m sending it manually over vanilla HTTP for testing purposes with HTTP/2 requests over HTTP.

HTTP 2 does support an unencrypted mode but essentially all browser vendors ignore that and only support an encrypted version of it

Fair enough. Preloaded HSTS really seems to be the most straightforward approach in your case as that should guarantee that all recent browsers will follow that instruction, while older browsers can still connect via HTTP.

Are you talking here about browsers that do not even support TLS v1.0?

These cannot be in the wild, so I assume these are internal users that you have strict control over. In which case, you could override their DNS, and point to them something like a local Nginx that will proxy all requests for HTTP (or maybe even SSL) from the clients to HTTPS (TLS) on the Cloudflare servers. I have done this in the past for a particularly bad application that the developer refused to fix.

HSTS Preload will get you some of the way there, if you can leave a redirect from the root of the naked domain in place long enough to get added to the preload list.

These cannot be in the wild

It involves vintage computer collectors, computer museums, not really Cloudflare’s use case, I know. :slight_smile:

Are you talking here about browsers that do not even support TLS v1.0?

Some won’t.

assume these are internal users that you have strict control over.

Out of my control. I have considered setting up an alternative subdomain; but I’d really just prefer if people keyed in a site and it ‘automatically’ figured out what to do.

HSTS Preload will get you some of the way there, if you can leave a redirect from the root of the naked domain in place long enough to get added to the preload list.

I setup a rule to rewrite requests from the “Go-http-client” user agent, which the HSTS preload uses to check for redirects and seems happy enough, since it “is pending submission to the preload list” now.

You could also do the redirect in a Worker, where you maintain a list of the old user agents, and don’t redirect them, but redirect everything else.

I’d still say HSTS would be the most elegant approach, but alternatively you could

  • redirect server-side to HTTPS based on the user-agent
  • set up a Worker script which redirects to HTTPS based on the protocol version used to connect to Cloudflare. I believe you should have that information within a Worker.

But again, HSTS often is a good idea anyhow and would solve your issue “dynamically” without having to set up anything else.

How many of these User Agents will support SNI? Will they even be able to get to a Cloudflare site with HTTP 1.0 only? I have not tested this, but you will almost certainly need a paid plan to get the kind of connection support you are looking for.

At least you will not have to do any of the modern stuff, like js or css!

I’d still say HSTS would be the most elegant approach

Which I am trying out to see how it goes; very likely it will be fine.

redirect server-side to HTTPS based on the user-agent

Unfortunately, vintage users tend to fake user-agents sometimes since websites like to bawk on them, I had originally looked at filtering based on modernish IE/Edge/Firefox/Chrome/Safari.

set up a Worker script which redirects to HTTPS based on the protocol version used to connect to Cloudflare. I believe you should have that information within a Worker.

That’s a pretty cool idea actually!

How many of these User Agents will support SNI?

Very few, probably none. I’m honestly not too hopeful in having anything below TLS 1.3 on HTTPS (it’s either really old or really new stuff). Even the older browsers that support TLS 1.0 don’t support aspects about the certificates regardless with hash sizes etc.

I am just moving into the direction, if you’re on HTTP, you’re insecure; supporting broken/outdated TLS/SSL is not secure, so I don’t really care to give a false sense of security. I’ll be adding clearer messaging between HTTP vs HTTPS sites.

I have not tested this, but you will almost certainly need a paid plan to get the kind of connection support you are looking for.

I’m not looking for legacy TLS/SSL support, so, that shouldn’t be an issue!

Edit: Also, it seems in our experience, every OS that had a browser that does HTTP/1.0, has a browser that does HTTP/1.1 too.

The protocol is available to a Worker, however only on the Business plan.

I would assume user-agents should be all right and can’t really imagine them faking their user-agent. Most of them probably would not even offer that option and wouldn’t work with current sites either, even if they fake the user-agent.

If you talk about vintage browser you must be referring to Mosaic and alike. Even Chrome 1 supports TLS 1, as does Firefox 1. The early versions of IE do not support TLS.

There certainly are other options like checking server-side or in a Worker, but overall I’d really go the HSTS route. Browsers not supporting HSTS will never get an HTTPS redirect and always work with HTTPS, whereas more recent versions will switch to HTTPS either because of HSTS or because of Alt-Svc which points them to HTTPS.

I would assume user-agents should be all right and can’t really imagine them faking their user-agent

Actually, not that uncommon, to give an example of some ‘used’ ones on my other site that I am replacing with a new site behind CF. it’s a standard feature of aweb, icab, IBrowse and Dillo (older versions on Irix).

There certainly are other options like checking server-side or in a Worker, but overall I’d really go the HSTS route. Browsers not supporting HSTS will never get an HTTPS redirect and always work with HTTPS, whereas more recent versions will switch to HTTPS either because of HSTS or because of Alt-Svc which points them to HTTPS.

I’m trying this as we speak. Hopefully the redirect detection isn’t too smart, as the preload site wants vanilla HTTP to redirect to HTTPS. I only have it redirecting on the Go-http-client user agent they used to probe the site initially. Hopefully this works~

Fair enough.

Try the user-agent restriction now for a test, but in production I’d use a combination of user-agent and network.

This topic was automatically closed after 30 days. New replies are no longer allowed.