I do a fair amount of support for webserver configuration and setup, usually dealing with static file hosting, PHP FastCGI proxying, HTTP proxying, DNS and SSL setup.
For the last while, I have seen time and time again that people are using CloudFlare with their webserver, and this usually is no problem – Their proxy and DNS services are super quick and work really well in my experience, even this blog is going through them, however there is one option which I find to be an absolute letdown, Flexible SSL/TLS Mode, and I’d even go as far as to call it dangerous. Heres why:
Flexible SSL/TLS mode is the default proxying mode for CloudFlare when you add a domain to the service. When you have the proxy enabled on a domain or subdomain (by selecting the orange cloud icon rather than the DNS only grey cloud icon on a record) the connection will go from your browser, to CloudFlare’s proxy servers, then from their proxy servers to your webserver. This essentially puts them in the middle of all requests to your webserver allowing them to intercept traffic – in a good way, as they let normal traffic through and block unwanted traffic from a DoS or DDoS.
The trouble with Flexible SSL/TLS mode however is that it seems to want to make the connection between the CloudFlare proxy servers and your webserver insecurely, that is, over port 80 HTTP. This leads to the two major problems:
- You server has to expect connections over port 80 HTTP to serve your site
- Configurations designed to redirect clients to port 443 HTTPS can really mess things up
Expecting Port 80 HTTP Connections
Lets first talk about the expectation of connections over 80 HTTP, which is the part I find dangerous. If you have a website which requires your clients to log in using their username and password, you should use port 443 HTTPS to handle that communication as it prevents their credentials from flying across the internet in plain text for anyone to read. That’s pretty reasonable, right? Well, when Flexible SSL/TLS mode is used, that connection between CloudFlare’s proxy servers and your webserver is port 80 HTTP which is not secure, it’s plain text, meaning those credentials are visible to anyone watching your traffic as it goes across the internet!
But what about the lock icon, you say? Oh… well there’s the dangerous part. Those people who are new to or are inexperienced with CloudFlare’s proxy service might see the SSL/TLS lock icon in their URL bar and assume “Everything is secure, its going over encrypted SSL/TLS!” which whilst is not wrong, is only half the story. The connection between your clients and the CloudFlare proxy servers are perfectly secure using port 443 HTTPS which is SSL/TLS, hence the lock icon appearing, however that last hop to your webserver is still over port 80 HTTP which is insecure, making that initial jump between your client and CloudFlare’s proxy servers absolutely pointless! There is no warning or indication that this second hop is occuring over port 80 HTTP in plain text, it just happens, you’d only notice if you have your webserver configured to not serve secure content over port 80 HTTP, and even then the client connecting to your webserver hasn’t the faintest idea what happened. Pretty dangerous if you’re sending sensitive information over the internet and don’t have a ton of experience and don’t notice this issue.
Configurations Messing You Up
So, its pretty clear why Flexible should be avoided already, however if you are still not convinced or maybe you’re seeing issues with your webserver prior to switching away from Flexible mode, theres something else you should be aware of too.
It is very common for a webserver to be configured to automatically redirect you to port 443 HTTPS to force clients into using a secure connection. This has become standard practice and is provided by pretty much every mainstream webserver or hosting service in one way or another.
The way this redirect works is by only providing a redirect on port 80 HTTP, nothing else, so any connection to port 80 HTTP automatically gets redirected with a 301 response code to the port 443 HTTPS version of the requested page, making clients automatically switch over to port 443 HTTPS before a user can even see any content and then proceed to do a secure action such as log in. Sounds like a good idea, right? Well, Flexible SSL/TLS mode strikes again!
Because Flexible SSL/TLS mode uses port 80 HTTP to connect to your webserver, if you have a redirect configured, the only response you will get is a 301 redirect to the port 443 HTTPS version of the requested page, even though the client is connected to CloudFlare’s proxy server over port 443 HTTPS. The webserver cannot see that the client’s initial connection is port 443 HTTPS, it can only see the port 80 HTTP connection between itself and CloudFlare’s proxy server and responds accordingly.
This is where the problem lies. The CloudFlare proxy dutifully forwards the 301 redirect response from the webserver back to the client, however because the client is already connected using port 443 HTTPS, the 301 redirect to port 443 HTTPS essentially just reloads the current connection, sending the client spiralling into a request response loop of 301s where the server constantly thinks the client is using port 80 HTTPS and telling the client to redirect, and the client actually using port 443 HTTPS on the other side and just resending the same request again.
What’s worse, is that a 301 redirect is actually called 301 Moved Permanently, and what the browser will do is remember that the server requested a redirect and assume thats what it should do, essentially locking the client into a redirect loop even after you fix the issue on your webserver and CloudFlare. Depending on how long the server tells the client to remember requests (CloudFlare’s default is 4 hours) clients may get stuck in a loop long after the issue has been resolved, and only tech savvy users may know to clear their cache or use CTRL + F5 for a cacheless refresh.
The Correct Method
The correct way to fix this problem is set CloudFlare to Full or Full (strict) SSL/TLS modes and to have proper SSL set up on your webserver, and to have your port 80 HTTP redirects in place to direct insecure clients to port 443 HTTPS.
Often, people use LetsEncrypt Free SSL certificates on the webserver alongside CloudFlare. This is fine, albeit inconvenient if you don’t have the automated renewal configured, and also requires special configuration if you want a wildcard certificate for all subdomains, otherwise you have to begin issuing separate certificates for each subdomain. It also complicates the configuration of the webserver as you have to account for Certbot or other tools needing to serve content to verify the domain.
The easy way to resolve this is to get a 15 year wildcard certificate from CloudFlare. This is completely free, however is only valid for the communication between your webserver and CloudFlare’s proxy servers. CloudFlare will handle the SSL certificate between their proxy servers and your clients, so you don’t need to worry about that, you just need to keep in mind that the certificate will not be valid if you decide to turn off the CloudFlare proxy.