Generating certificates behind CDNs

If you have a proxy or a CDN sitting in front of your Fly App, you may have hit some difficulty when you were first configuring your certificate. To improve apps behind CDNs, we have now completed our ACME trifecta by adding support for automatic HTTP-01 challenges.

For some background: Our preferred way to generate a certificate is the TLS challenge, which involves a secret handshake with Let’s Encrypt. If you put your app behind a CDN, we no longer get to do that handshake, and your CDN does it wrong (by design!).

Our second option for validating your domain has been a DNS challenge, but this isn’t something we can do for you. You have to add the record yourself (and maintain it). We also see contention with this record; If your provider wants to prove they own the domain, they might bowl over our validation with theirs.

Our new third option is the HTTP challenge, where Let’s Encrypt requests a file and expects a specific response. As long as your CDN passes through these challenges to our network, we can respond to them correctly and generate a certificate. This isn’t something you need to decide on either — we’ll detect whether the TLS or HTTP flow is more appropriate during the process.

Important note: For this flow to work correctly (and securely), we require that you configure your proxy or CDN to point exclusively to your app’s IPv6 address.

Example: Cloudflare

If you have Cloudflare sitting in front of your Fly app, you should create an AAAA record to your app’s IPv6 address, and nothing else. No A record, no CNAME.

That’s it! Your app will get a certificate automatically, and you don’t need to disable Cloudflare’s “Always Use HTTPS” setting, or the “Full (strict)” encryption mode.

(This is only needed if you use Cloudflare’s proxying feature (orange cloud). If you’re just using Cloudflare for DNS, you should set A & AAAA (or CNAME) as you normally would).

10 Likes

I’ve noticed Let’s Encrypt’s 90-day validity and rate limits might push me to look at other options with your HTTP-01 IPv6 approach. I’m thinking ZeroSSL could work with its free tier and ACME support, while SSL.com offers a 1-year free DV upgrade. Both might handle IPv6 setups, but I’d probably need to tweak them manually. I’m eager to dig into which suits my setup best, any tips on integrating these?

@Sairam just a heads up, the CA/Browser Forum has made a decision that starting in 2026 all new certificates will have reducing validity periods until it’s only 47 days starting in 2029. That means no Certificate Authority that provides certificates for websites as part of Web PKI will be allowed to issue certificates that are valid for more than 47 days.

1 Like

Yep as @charsleysa says, everything is trending shorter.

To clarify, this new support is only relevant for certificates that we generate on behalf of your app. Fly.io (currently) exclusively integrates with Let’s Encrypt for the automatic certificates we provision. With these, you don’t have to think about the validity periods or the rate limits. We renew certificates well in advance, and we’re careful with how much we hit Let’s Encrypt per hostname.

With regards to ZeroSSL or SSL.com, we don’t offer a way to plug your own ACME provider into our provisioning. But, if you pass through TCP to your Fly app you can terminate your own TLS and do your own ACME HTTP challenges (the Fly Proxy won’t interfere with these). This was true even before this release, and there’s also no IPv6 requirement if you’re handling it on your own.

Either path works, but my advice would be to use our TLS handler with Fly.io generated certificates (especially as the validity periods start to reduce).