Redir with different domain, keeping subdomain

1. Caddy version (caddy version):

v2.1.1

2. How I run Caddy:

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:

example.com,
example.org,
*.example.com,
*.example.org,
app.customer-domain.com {
  import rails
}

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:

*.example.org {
	redir https://{labels.2}.example.com{uri} permanent
}

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).

1 Like

You can use {http.request.host.labels.*} to get a specific part of the hostname, […]

Oh, I somehow missed that.

Are you asking to redirect any *.example.org to *.example.com?

Exactly.

You could do that like this:

*.example.org {
	redir https://{labels.2}.example.com{uri} permanent
}

This looks promising. I will try that next week monday, when I’ve got access to the server again :slight_smile:

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:

  1. 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]
  2. I’m one of the maintainers of Lego (partly because of the former point :-))

[^1]: I’ve actually built a slimmed-down version of the Lego binary, containing only the required ACME solvers and modeled more after the now unmaintained acmetool.

[^2]: the plugin add support for all providers, we only need RFC2136 (and Cloudflare for one project).

Why not write a caddy-dns port of the RFC2136 plugin then? :slightly_smiling_face: 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)

I haven’t found the time to do it, honestly.

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.).

Are you aware of xcaddy? Very simple to build Caddy with plugins.

Caddy can do that too :sweat_smile:

But fair enough :stuck_out_tongue:

1 Like

@francislavoie, just to let you know: redir https://{labels.2}.example.com{uri} permanent works like a charm.

Thank you for your help!

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.