To understand why this is happening, you should understand what Cloudflare’s main features are and how they work.
In “orange-cloud” mode, Cloudflare acts as a transparent proxy between your clients and your server. It does this by directing DNS queries for your website to itself, and when a client connects, Cloudflare queries your server on the client’s behalf. In this mode they can provide caching, DDOS mitigation, and TLS termination in front of your server.
In the Cloudflare account panel, under the Crypto settings for your site, you’ll find an SSL setting. The default mode is Flexible, which provides the above-mentioned TLS termination. To quote their site:
Flexible SSL: You cannot configure HTTPS support on your origin, even with a certificate that is not valid for your site. Visitors will be able to access your site over HTTPS, but connections to your origin will be made over HTTP. Note: You may encounter a redirect loop with some origin configurations.
From this we can infer (and the linked article explicitly explains) that when your client connects via HTTPS, Cloudflare connects to your server via HTTP, and your server tells Cloudflare to upgrade to HTTPS, and Cloudflare then passes that back to the client (which will just confuse them, as they connected via HTTPS in the first place - a redirect loop).
There’s a few ways to go about Caddy and Cloudflare co-existing.
If you want to use Cloudflare’s additional features
- With valid certificates from LetsEncrypt:
- HTTP / TLS-SNI validation is tricky with Cloudflare in the way, so DNS validation is highly recommended to simplify things. Cloudflare is a supported provider for this, see the docs for more info: Automatic HTTPS — Caddy Documentation
- Swap the SSL mode in the Cloudflare Crypto settings to Full SSL (Strict) to indicate that Cloudflare should connect via HTTPS and validate the LE certificate.
- With an Origin Certificate signed by Cloudflare:
- On the Crypto settings page, scroll down to Origin Certificates create a certificate.
Feel free to set a long expiration, use wildcard hosts, etc - this certificate won’t be used for the general public, but for Cloudflare itself to authenticate your origin server. - Download they key and certificate and save them to the server you run Caddy on.
- Specify the key and cert locations in your Caddyfile with
tls cert key
. - Providing your own cert and key will break Automatic HTTPS, so be sure to set your site labels to specify scheme (prefix them with
http://
andhttps://
) or port (suffix with:80
and:443
), and set up HTTP->S redirection as required. - Set the SSL mode in Crypto settings to Full SSL (Strict).
- On the Crypto settings page, scroll down to Origin Certificates create a certificate.
- With a self-signed certificate from Caddy:
Note: without certificate validation, if an attacker takes control of your IP address, they could fool Cloudflare and any connecting clients.- Use
tls self-signed
in your Caddyfile. - Swap SSL mode in Cloudflare Crypto settings to Full SSL to indicate that Cloudflare should connect via HTTPS, but should not validate the certificate provided.
- Use
- With HTTPS disabled in Caddy:
Note: this method has the same vulnerability as self-signed certificates, and in addition, transport between Cloudflare and your server is totally unencrypted.- Prefix your site labels with
http://
in your Caddyfile to disable Automatic HTTPS and serve your sites directly on port 80. - Leave SSL mode in Cloudflare Crypto settings as Flexible.
- Prefix your site labels with
If you don’t want to use Cloudflare’s additional features
- “Grey-cloud” your A / CNAME records to disable the Cloudflare reverse proxy.
- Use Caddy normally - Cloudflare now only provides DNS services, so clients connect directly to your server and regular certificate validation should be unimpeded.