Search code examples
caddycaddyfile

Redirect all undefined subdomains using Caddy


Let's say my Caddyfile defines two sites: a.example.com and b.example.com.

What should I do so that any subdomain other than these two is redirected to a.example.com? For example, going to c.example.com or xyz.example.com should redirect to a.example.com

In other words, I want something like a 404 rule but for non-existent subdomains rather than non-existent files.


Solution

  • Point your DNS A/AAAA records for *.example.com to your server.

    a.example.com {
        # handle here
    }
    b.example.com {
        # handle here
    }
    *.example.com {
        redir https://a.example.com
    }
    

    You handle the a.example.com and b.example.com domains as you normally would, and set up a redir for *.example.com to https://a.example.com. Note that Caddy will automatically setup a redirect from http to https so that isn't needed.

    Because you are using a wildcard domain in your Caddyfile, you can either use Caddy's on-demand TLS (which will fetch a certificate for that subdomain whenever such a request is received) or use a wildcard certificate (which requires the DNS challenge).

    On-demand TLS

    *.example.com {
        tls {
            on_demand
        }
    }
    

    There are some pitfalls to this approach which make wildcard certificates more attractive:

    • Clients can abuse the setup to get as many certificates as they want, resulting in disk / memory exhaustion.
    • Rate limiting by certificate authorities

    Wildcard certificates

    *.example.com {
        tls {
            dns cloudflare {env.CLOUDFLARE_AUTH_TOKEN}
        }
    }
    

    To use the DNS challenge, you need to

    1. Use a nameserver that supports programmatic access
    2. Build Caddy with a provider for that nameserver configured. For example, for Cloudflare you could build with https://github.com/caddy-dns/cloudflare (xcaddy build master --with github.com/caddy-dns/cloudflare) and save the token in the environment variable CLOUDFLARE_AUTH_TOKEN.