Using the default systemd unit, i.e. caddy run --environ --config /etc/caddy/Caddyfile
a. System environment:
Standard Ubuntu 20.04 server.
b. Command:
systemctl start caddy
(I actually don’t type that, because that’s systemd’s job).
c. Service/unit/compose file:
The default one, see above.
d. My complete Caddyfile or JSON config:
(rails) {
# some reverse_proxy configuration for a Rails app
}
# main application
example.com {
import rails
}
# customer domains
app.customer-domain.com,
*.example.com {
import rails
}
# similar sounding domains
example.org,
*.example.org {
redir https://example.com{uri} permanent
}
3. The problem I’m having:
As you can see from the Caddyfile, I’m redirecting example.org (and *.example.org) to example.com.
On example.com I have a service where users can register subdomains for themselves, e.g. foo.example.com. I would like to redirect foo.example.org to foo.example.com.
Is this possible on the Caddy layer, or do I need to change my config to something like:
and handle the redirection logic in my Rails app? I would like to avoid this, as the Rails routing logic already is quite complex and slow (comparatively).
4. Error messages and/or full log output:
Irrelevant.
5. What I already tried:
See above.
6. Links to relevant resources:
matcher docs don’t mention subdomains, only the host header and no way to extract any domain label
http placeholders seem also not to be helpful in this case (yes, I can access {host}/{http.request.host} – but then what?)
You can use {http.request.host.labels.*} to get a specific part of the hostname, i.e. {http.request.host.labels.2} to get foo from foo.example.com. In the Caddyfile, this can be shortened to {labels.2}.
There’s a bunch of ways you can do this; I’m not sure I completely understand the goal. Are you asking to redirect any *.example.org to *.example.com? You could do that like this:
Follow-up, are you using On-Demand TLS, or wildcard certs here? I ask because On-Demand TLS will cause any first request to the .org domain to issue a certificate for it (unless rejected by the ask option), even though it will only ever redirect. A wildcard cert would be less heavy here, if that’s viable for you (need to use a DNS plugin).
This looks promising. I will try that next week monday, when I’ve got access to the server again
Follow-up, are you using On-Demand TLS, or wildcard certs here?
I’m using wildcard certificates, but I’m not using Caddy to obtain/renew the certificates. I’m relying on Lego to do that job[1], mostly for two reasons:
At work, we operate our own DNS infrastructure, and the only standardized way to perform DNS updates required for ACME challenges is, well, DNS Update (RFC2136). Caddy does not support that ACME solver out-of-the box, and the legacy Lego plugin add too much bloat[2]
I’m one of the maintainers of Lego (partly because of the former point :-))
Why not write a caddy-dns port of the RFC2136 plugin then? That would surely be useful to others as well. I might even use it myself at some point (we have a usecase where it could be useful at my day job)
But, even if the RFC2136 solver would find its way to become a plugin, I don’t think we would use it ourselves:
For one it complicates the Caddy installation, as we’d need to build and host it (in contrast, grabbing the .deb from the Github release page is very convenient).
We also use our tool to generate certificates for other services (we still have a few Apache installations, Postifx and Dovecot want a certificate, etc.).