Redir all domain/subdomain non-www to www

Hi all, right now my Caddyfile looks like this:

 example.com {
     redir https://www.example.com{uri}
 }

 www.example.com {
     root /site/example
     gzip
     tls example@pm.me
 }

 malachite.example.com {
     redir https://www.malachite.example.com{uri}
 }

 www.malachite.example.com {
     proxy / matomo:8888 {
         transparent
     }
 }

as you can see i’m manually redir-ing the non-www of each subdomain to www version of it. if i have 20 subdomain, this would get tiresome.

is there any way to redir all of the non-www to www at once?

With a few features from the latest release of Caddy, especially {labelN} placeholders, this gets much easier!

http://*.example.com, https://*.example.com {
  redir www.{label1}.example.com
  tls {
    ...
  }
}

# It's important that www.example.com exists
# as another site label so that it doesn't get
# redirected to www.www.example.com...
www.example.com {
  ...
}

If you’re using Automatic HTTPS, you’ll need to do something about that wildcard… If your DNS provider is supported (see the list here: GitHub - caddyserver/dnsproviders: OBSOLETE: DNS providers adapted for use in Caddy to solve the ACME DNS challenge - for Caddy v1 only. See caddy-dns for v2.), you could use Caddy’s new LetsEncrypt wildcard certificate support!

On-Demand TLS would suit equally well, and would make use of existing HTTP validation.

1 Like

It’s worth noting that http://*.example.com, https://*.example.com can be reduced to *.example.com, if you don’t mind a double-redirect in your case and if you prefer simplicity. (HTTP->HTTPS is automatic, and then the www redirect is the second one). Whitestrake’s example is optimized for just one redirect.

1 Like

Thanks a lot folks! it works well.

although i’m confused. somehow http://*.example.com, https://*.example.com { also redir the main domain example.com

shouldn’t the . be considered in this?

Caddy should never equate *.example.com with example.com - if it is, that’s unintended behaviour.

Does it do that if http://*.example.com, https://*.example.com is the only site the whole Caddyfile?

well i can’t just have those 2 as the only thing in the caddyfile.
right now it works if i have

http://*.example.com, https://*.example.com {
  redir
}

www.example.com {
  root
}

so there should be nothing that tells it to redir example.com to www.example.com but it works.

Yep, that definitely shouldn’t be happening. Can you run curl -IL http://example.com/ and post the output so we can see exactly how Caddy is responding?

1 Like

ok it give 404. seems like the redir was because of browser/network caching issues.

i have added http://example.com, https://example.com { redir https://example.com{uri} } and it works fine

1 Like

It’s always the browser cache. :slight_smile:

I’ve got new related problem. this is my current caddyfile:

 # Main domain
 http://example.com, https://example.com {
     redir www.example.com
     tls name@example.com
 }

 www.example.com {
     root /site/example
     gzip
 }

 # Subdomains
 http://*.example.com, https://*.example.com {
     redir www.{label1}.example.com
     tls name@example.com
 }

 www.sub1.example.com {
     proxy / localhost:8888 {
         transparent
     }
 }

 www.sub2.example.com {
     proxy / localhost:19999 {
         transparent
     }
 }

so currently the webserver only works if accessed through the full https://www.example.com or https://www.sub1.example.com

trying to access incomplete address will result in infinite 301 redir e.g.

curl -IL https://example.com
HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=utf-8
Location: /www.example.com
Server: Caddy
Date: Fri, 30 Mar 2018 19:47:48 GMT

looping infinitely

and

curl -IL http://sub1.example.com
HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=utf-8
Location: /www..example.com  <- notice the double dots
Server: Caddy
Date: Fri, 30 Mar 2018 21:23:59 GMT

looping infinitely

please let me know how to fix this or if you have other improvements to my caddyfile

thanks.

i’ve been doing more experiments and i think its because www.example.com triggers the *.example.com thus creating infinite loop. is this plausible?

OK, two problems here I can see.

Location: /www.example.com

That’s a relative link; it’s telling the browser, in that instance, to go to https://example.com/www.example.com. That runs into the redirect statement again, hence the infinite redirect.

Off the top of my head, I don’t think it should be assuming a leading slash… But you should be redirecting to HTTPS anyway; fix this by prepending all your redir hosts with https://, e.g. redir https://www.{label1}.example.com.

Secondly… Location: /www..example.com. Ignoring the leading slash, we’ve got an entire URL element missing. It should be filled in with the result of {label1}, e.g. sub1, but it has been given the empty result instead. It should be impossible for this to happen - {label1} should always have a valid result, because every host in a Caddyfile has at least one element.

So just to check, can you run caddy -version and make sure you’re on the latest release I mentioned in the second post, version 0.10.12? Being on version 0.10.11 or earlier would result in these placeholders being empty. If you are indeed on version 0.10.12, we might have to look further into how this happened, possibly as a bug of some kind.

1 Like

ok that actually worked, but i’ve also added if statement to the redir:

 # Main domain
 http://example.com, https://example.com {
     redir {
         if {host} not_starts_with www
         / https://www.example.com{uri}
     }
     tls {
         dns vultr
     }
 }

 www.example.com {
     root /site/example
     gzip
 }

 # Subdomains
 http://*.example.com, https://*.example.com {
     redir {
         if {host} not_starts_with www
         / https://www.{label1}.example.com{uri}
     }
     gzip
     tls {
         dns vultr
     }
 }

 www.sub1.example.com {
     proxy / matomo:80 {
         transparent
     }
 }

 www.sub2.example.com {
     basicauth / admin pass
     proxy / netdata:19999 {
         transparent
     }
 }

this has taken so much of my time the past several days, I hope this post help save some time for you all :slight_smile:

1 Like

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