Redirect using wildcard match

1. The problem I’m having:

I’m trying to redirect https to http for local domains. I want to make a catch-all but wildcards only work with the matcher, not the content of the directive.

https://*.example.co {
  redir http://......example.co
}

I’d like to be able to do something like

https://(*).example.co {
  redir http://$1.example.co
}

and now https://test.example.co will redirect to http://test.example.co

2. Error messages and/or full log output:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

3. Caddy version:

4. How I installed and ran Caddy:

a. System environment:

b. Command:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

c. Service/unit/compose file:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

d. My complete Caddy config:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

5. Links to relevant resources:

I’m confused. Why would you want to redirect from HTTPS to HTTP? The only way to serve a redirect from HTTPS is if you have a valid certificate which can allow you to establish a TLS connection, so why would you knowingly try to downgrade security after it’s already been established? That sounds so backwards.

Please completely fill out the help topic template.

I’m using a local domain that I don’t own, but browsers tend to automatically address the non https variants when written without http://

I’ve completed the questions below:

2. Error messages and/or full log output:

n/a

3. Caddy version:

v2.7.6 h1:w0NymbG2m9PcvK...

4. How I installed and ran Caddy:

I’m using GitHub - lucaslorentz/caddy-docker-proxy: Caddy as a reverse proxy for Docker

a. System environment:

b. Command:

c. Service/unit/compose file:

services:
  docker-proxy-caddy:
    image: lucaslorentz/caddy-docker-proxy:ci-alpine
    ports:
      - 80:80
      - 443:443
    environment:
      - CADDY_INGRESS_NETWORKS=proxynetwork
    networks:
      - proxynetwork
    labels:
      caddy_0: "ubl-mesh-tool.<private>.nl"
      caddy_0.root: "* /data/static/ubl-mesh-tool"
      caddy_0.file_server: ""
      # I'm trying to get a non-docker container to be proxied from that address. 
      # Still figuring out the syntax, but this is besides the current topic
      caddy_1: "http://klipper.local.co"
      caddy_1.reverse_proxy: ""
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /mnt/user/appdata/caddy-docker-proxy:/data
      - /mnt/user/appdata/caddy-docker-proxy:/static
    restart: unless-stopped

networks:
  proxynetwork:
    external: true

d. My complete Caddy config:

Caddyfile.autosave

<private>.<private>.nu, http://change.local.co, http://changedetection.local.co {
	reverse_proxy 172.18.0.7:5000
}
http://bind.local.co {
	reverse_proxy 192.168.1.4:10000
}
http://chrome.local.co {
	reverse_proxy 172.18.0.20:3000
}
http://flaresolverr.local.co {
	reverse_proxy 172.18.0.18:8191
}
http://jellyfin.local.co {
	reverse_proxy http://192.168.1.3:8096
}
http://krusader.local.co {
	reverse_proxy 172.18.0.9:6080
}
http://netdata.local.co {
	reverse_proxy 172.18.0.12:19999
}
http://orca.local.co {
	reverse_proxy 172.18.0.3:3000
}
http://photos.local.co {
	reverse_proxy 172.18.0.6:2342
}
http://portainer.local.co {
	reverse_proxy 172.18.0.19:9000
}
http://speedtest.local.co {
	reverse_proxy 172.18.0.11:80
}
http://speedtracker.local.co {
	reverse_proxy 172.18.0.10:8082
}
http://zb.local.co {
	reverse_proxy 172.18.0.16:8099
}
<private>.<private>.nu, http://password.local.co {
	reverse_proxy 172.18.0.17:80
}
www.<private>.nl, <private>.nl, http://<private>.local.co, http://<private>.local {
	reverse_proxy 172.18.0.21:3000
}

autosave.json

{
  "admin": { "listen": "tcp/localhost:2019" },
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [":443"],
          "routes": [
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.21:3000" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [
                { "host": ["www.<private>.nl", "<private>.nl"] }
              ],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.17:80" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["<private>.nu"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.7:5000" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["<private>.<private>.nu"] }],
              "terminal": true
            }
          ]
        },
        "srv1": {
          "listen": [":80"],
          "routes": [
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.7:5000" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [
                { "host": ["change.local.co", "changedetection.local.co"] }
              ],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.18:8191" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["flaresolverr.local.co"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.10:8082" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["speedtracker.local.co"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.19:9000" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["portainer.local.co"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.11:80" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["speedtest.local.co"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "192.168.1.3:8096" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["jellyfin.local.co"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.9:6080" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["krusader.local.co"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.12:19999" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["netdata.local.co"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.20:3000" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["chrome.local.co"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.6:2342" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["photos.local.co"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.21:3000" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["<private>.local.co", "<private>.local"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "192.168.1.4:10000" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["bind.local.co"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.3:3000" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["orca.local.co"] }],
              "terminal": true
            },
            {
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [{ "dial": "172.18.0.16:8099" }]
                        }
                      ]
                    }
                  ]
                }
              ],
              "match": [{ "host": ["zb.local.co"] }],
              "terminal": true
            }
          ]
        }
      }
    }
  }
}

5. Links to relevant resources:

Which browser? As far as I know, if you have “Automatic HTTPS” in your browser turned on (the feature name depends on the browser) they should still fall back to HTTP if the connection isn’t successful.

Either way, best if you use an actual domain you own or can control, e.g. something like DuckDNS. Then actually use HTTPS.

IMO what you’re trying to do doesn’t make sense at all. It’s impossible to redirect from HTTPS to HTTP unless you can successfully establish an HTTPS connection, which can only happen if you have a valid & trusted TLS certificate, so there’s no point in redirecting to HTTP at that point, because you’ve already done the steps to set up HTTPS.

1 Like

@francislavoie Thanks for your input.

I’ve realized that HTTPS redirection only works if the connection to HTTPS is successful. Based on this, I’ve switched to using HTTPS by default, something I also deduced from other forums.

Currently, I’ve configured tls internal for most of my domains. The next step involved adding the local authority certificate to all my machines with caddy trust --address=my-docker-host:2019.

However, I’m facing an issue with changing the admin hostname. It’s currently limited to tcp/localhost:2019, but I need it to listen on tcp\0.0.0.0:2019. This adjustment doesn’t seem to work in the docker image I am using (see issue here: Expose caddy admin 2019 · Issue #624 · lucaslorentz/caddy-docker-proxy · GitHub).

I’m considering rebuilding the image with the CADDY_ADMIN variable set to 0.0.0.0. Does anyone have insights or a similar experience with this setup?

If you’re using CDP, then it’s not possible to change the admin endpoint address (for now anyway) because CDP needs controlled access to the admin endpoint so it can perform config changes of its own.

You can copy the root CA cert from Caddy’s storage by hand (it’s in /data/caddy/pki/authorities/local/root.crt) and then install that by hand on the relevant machines/browsers.

1 Like

@francislavoie That’s unfortunate.

Good to know there’s an alternative. From what I understand from the docs is that the caddy trust command doesn’t install the certificate when it’s coming from a downloaded file. Is there another way to do this automated?

Currently caddy trust doesn’t support a workflow that doesn’t connect to the admin endpoint, so you’ll need to do it manually. But it’s not difficult, just follow the instructions for each platform/browser you plan to use it with.

2 Likes

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