Generic www redirect with dynamic HTTPS

Hello!

We’re running a virtual host and want to ensure TLS for all our domains. This is our current configuration, and it works flawlessly (still amazed at how simple this was):

   * {
        gzip

        proxy / { 
            transparent
            upstream http://server_live:{$PORT}
        }

        tls contact@redacted.net {
            ask http://server_live/validate-domain
        }
    }

The problem: We aren’t able to redirect www.* traffic to the root domain in a generic way (e.g. a request to www.example.com should go to go example.com, so we don’t have to maintain two certificates per domain).

What we have tried (roughly):

   www.* {
        redir https://{root}{uri} # this clearly won't work, just including to illustrate thought process
   }

   * {
        gzip

        proxy / { 
            transparent
            upstream http://server_live:{$PORT}
        }

        tls contact@redacted.net {
            ask http://server_live/validate-domain
        }
    }

I don’t expect this configuration to work for several reasons, but I hope it illustrates what we’re trying to do, and that someone knows how to achieve the behaviour we want

Thanks for reading

Hi @Lasse_Emil_Jacobsen! Welcome to the Caddy community.

The limiting factor here is that there’s no method available via Caddyfile to take an arbitrary detail of the request and transform it for use in a later function like a redirect.

If you are redirecting away from one host and to another, you will need to know the full destination or be able to build it out of placeholders.


There’s a heavily work-in-progress PR over at the Github page for Caddyfile-wide “if” statements which might possibly one day support arbitrarily extracting this information via regex.

https://github.com/mholt/caddy/pull/1948

Hey - thanks!

All right, that sucks for us ;(

I see two potential ways we can proceed:

  1. Have a certificate for both www.* and the root domain
  2. Wildcard certificates

The first option seems a little excessive and would double our issuance, bringing us closer to the rate limit (which we’re already slightly concerned about).

The second option seems more appropriate to me (if it works like I understand it); do you know if a wildcard certificate would cover both “example.com” and “www.example.com”?

Any input is very appreciated

The wildcards Caddy will requisition won’t, I don’t think, cover both *.example.com and example.com.

If the registered domains you’re getting certificates for are distinct, I don’t think you’re likely to run into the rate limits… The biggest one is 20/week for the same registered domain (and 5 duplicates/week).

Ah, probably not worth messing with wildcards for this purpose then (although we will add subdomains eventually)

Concerning rate limit we were mostly concerned with:

After 10 certificates are successfully obtained, new certificate challenges will not happen until 10 minutes after the last successful challenge.

We could potentially run into scenarios where a lot of new domains (or subdomains) require new certificates at the same time, clogging us up for a bit. Probably not likely to happen in the near term, but I like sleeping easy :wink:

Anyway, thanks a ton for the help - we should be able to work something out by ourselves from here

Huh? Where’s that rate limit? Oh, it’s On-Demand TLS, Caddy-side.

You can get around that by using an Ask endpoint.

1 Like

You’re fast!

edit: oh, well then we’re set on that end, as we already use the ask to check the domain against our database

1 Like

Actually, I might be wrong about that. Docs don’t actually say that’s the case (in fact, they specify that the ask endpoint works in addition to the rate limits), but I’m pretty sure I recall it got around it… Another thread recently somewhere was talking about it, I’ll see if I can find it.

1 Like

Confirmed in code:

https://github.com/mholt/caddy/blob/accaa378f0908d85d2eb010374edba14b995def4/caddytls/handshake.go#L267-L279

The process uses checkURLForObtainingNewCerts if an ask endpoint is specified, rather than checkLimitsForObtainingNewCerts.

The ten minute timer is not checked in the ask endpoint code, so there’s no Caddy-side throttling - you’re taking that responsibility on for yourself.

When you say that we take on the responsibility of throttling ourselves, does that concern rate limits imposed by Lets Encrypt?

Nah, LetsEncrypt’s still apply. The ten minute thing is a fairness kind of deal, so you’re taking the responsibility to be fair about it upon yourself :slight_smile:

1 Like

Ah - gotcha :wink:

Thanks man, top notch assistance

1 Like

Happy to help!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.