Reverse proxy for Unifi network controller for Caddy >= 2.11

I’m sharing this in case it helps others.

I have been running the Unifi Network Application using the LinuxServer.io Docker images. I also use Caddy for SSL reverse proxy. Today I discovered that Caddy 2.11 broke my configuration; the root cause was the change in behavior to header_up Host.

Here is my updated Caddyfile that fixes this issue in Caddy 2.11:

{$DOMAIN} {
  reverse_proxy https://unifi-network-application:8443 {
    header_up Host {host}
    transport http {
      tls_insecure_skip_verify
    }
  }
}
3 Likes

Hi Greg,

Could you please clarify the working reverse proxy configuration or post a diff? Is the only change the addition of header_up Host {host} ? Can you also clarify what the broken behaviour was? Was it a blank/empty response but with HTTP 200 OK status code?

We’ve just upgraded our core ingress router to caddy 2.11 and to roll back to 2.10 as each of our reverse proxies to HTTPS backend using the tls_insecure_skip_verify config were broken; and annoyingly the result was an empty body with HTTP 200 OK, meaning our external and internal monitors relaying on status code response did not pick up the error.

I was about to raise this as an issue on https://github.com/caddyserver/caddy/issues but I saw this topic here and thought I would tag along.

1 Like

Oh noooo, why are you disabling security??


But yes, in 2.11 we made this change because the previous default, although consistent with that of HTTP upstreams (which I much enjoyed), made it easy to have misconfigurations in some common cases that could lead to security vulnerabilities (though it was not a security bug in and of itself).

Is Caddy your proxy or your backend?

I’m not sure about the OP, but we use this internally in the following configuration:

Client app stack(s) in docker → Caddy (caddy-docker-proxy) as the ‘ingress router’ for the docker host→ Caddy (standard caddy) as the ‘global router’ at our network edge (this instance routes requests to many different customer environments) → Cloudflare

In this configuration, we use tls_insecure_skip_verify for connections from our ‘global router’ reverse proxy to the caddy ‘ingress router’ for the client’s environment. As this connection is all within our internal environment (internal on-prem network), we’ve currently opted to skip verify. Long term the plan is broader trusted PKI, but we have not implemented this.

For some of the domains we are proxying we can utilise HTTP or DNS challenges effectively, and have to rely on tls internal , as the domain is external to us (customer owned), and the “public facing” TLS is manged by Cloudflare.

Yes.

Can you also clarify what the broken behaviour was? Was it a blank/empty response but with HTTP 200 OK status code?

The homepage would load, but when you tried to login, you get a password error. I used developer tools in the web browser to debug the issue, and I saw the web service that processes logins was failing. I resolved the issue when I reverted to Caddy 2.10, so I read the release notes and figured this was an issue with reverse proxying. I changed header_up in my Caddyfile, upgraded back to Caddy 2.11, and the issue was resolved.

mattMatt Holt

Oh noooo, why are you disabling security??

Ha! Because the UniFi Network Application (the upstream server) creates its own self-signed SSL certificate. That runs in its own Docker container on the same Docker server and Docker network as Caddy. And if the UniFi Network Application is compromised, SSL is the least of my worries…

(There exists a way to replace that self-signed certificate, but it’s extremely tedious and not something that could be easily automated. And I suspect it would break other critical functions for that server.).

@gglockner, thank you for posting this. I was having an issue with my DMSE where it would let me log in but then was stuck loading the dashboard (or any other part of the interface for that matter). That one little line fixed it right up.

1 Like