Wildcard subdomain reverse_proxy rewrite subdomain

1. The problem I’m having:

I have a small public server that I can spin up temporarily when I want to use to proxy a few things on an internal private VPN for times when I cannot connect to the internal VPN for whatever reason. I would like to setup a wildcard subdomain that reverse proxies to an edited version of the subdomain. For example:

  • foo.public.example.com should reverse proxy to foo.example.com
  • foo.bar.public.example.com should reverse proxy to foo.bar.example.com
  • abc123.public.example.com should reverse proxy to abc123.example.com

In general, I am looking to basically reverse proxy from a domain X to echo "$X" | sed 's/\(public\.\)//g' (just strip out any public.; it is safe to assume no subdomain has ‘public’ in it)

Important note: I am flexible about whether foo.bar.public.example.com (my preference) or public.foo.bar.example.com is used if one makes this easier, but basically I am looking to wildcard reverse_proxy from the public entry point to a non-public url.

2. Error messages and/or full log output:

N/A (I am looking to figure out how to do this in the caddy Config)

3. Caddy version:

v2.8.4

4. How I installed and ran Caddy:

a. System environment:

b. Command:

docker compose up -d

c. Service/unit/compose file:

services:
  caddy:
    image: "caddy"
    container_name: "caddy"
    restart: unless-stopped
    ports:
      - 443:443
    volumes:
      - ./caddy/Caddyfile:/srv/Caddyfile:Z,ro  # z probably overrides ro :/
      - ./caddy/data:/data:Z
    command: ["caddy", "run"]

d. My complete Caddy config:

(hsts) {
  header Strict-Transport-Security max-age=63072000
}

(blacklists) {
        @mainlst not remote_ip private_ranges 172.19.23.1/24
}

*.public.example.com {
        import blacklists
        handle @mainlst {
                respond "Access denied" 403 {
                        close
                }
        }
        basic_auth {
                friend $2a$14$mCe3FAKEEJsyN2R3pLlLiO.02NOWw7Mmn1K/ARB79smr0cFBfakeq
        }
        tls myemail@gmail.com
        reverse_proxy /* Remove the public. from the subdomain */
}

5. Links to relevant resources:

Cannot find any.

Easy enough, just do this:

reverse_proxy {labels.3}.example.com

This grabs the 4th segment from the right (0-indexed).

Though keep in mind, the default is to proxy over HTTP (not HTTPS). You would need this if you need to proxy over HTTPS:

reverse_proxy {labels.3}.example.com {
	header_up Host {upstream_hostport}
	transport http {
		tls
	}
}

This is not possible. Wildcard certs only match a single label. Multi-level wildcard certs are impossible.

1 Like

This works! My only struggle now is that redirect responses seem to point to foo.example.com instead of being rewritten by caddy to foo.public.example.com.

Caddy will pass the original host in X-Forwarded-Host. Your upstream apps can consult that.

2 Likes

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