Disable auto HTTPS on LAN

1. Caddy version (caddy version):

v2.3.0 h1:fnrqJLa3G5vfxcxmOH/+kJOcunPLhSBnjgIvjXV/QTA=

2. How I run Caddy:

Serve files over HTTP/HTTPS
Reverse proxy for Home Assistant

a. System environment:

Ubuntu 20.10, not using systemd (yet) or Docker

b. Command:

caddy run

c. Service/unit/compose file:

N/A

d. My complete Caddyfile or JSON config:

localhost, 192.168.1.34, server.theundarkpixel.com {
        root * /home/caddy/root/
        handle_path /hass/* {
                rewrite * {path}
                reverse_proxy localhost:8123
        }
        file_server
}

hass.server.theundarkpixel.com {
        reverse_proxy * localhost:8123
}

3. The problem I’m having:

I’m trying to disable automatic HTTPS on LAN addresses so that I can access my hosted files without going over the internet.

4. Error messages and/or full log output:

This site can’t provide a secure connection192.168.1.34 sent an invalid response.
Try running Windows Network Diagnostics.
ERR_SSL_PROTOCOL_ERROR

5. What I already tried:

localhost, 192.168.1.34:80, server.theundarkpixel.com {
...
localhost, http://192.168.1.34, server.theundarkpixel.com {
...
localhost, http://192.168.1.34:80, server.theundarkpixel.com {
...
localhost, 192.168.1.34, server.theundarkpixel.com {
        192.168.1.34 {
                auto_https disable_redirects
        }
...

6. Links to relevant resources:

N/A

Using http:// is correct. Also do that on localhost.

Also,

This is a no-op, this rewrite will do nothing. You can safely remove this line.

I also recommend putting your root and file_server inside a handle block, below your handle_path, for clarity.

1 Like

Oh oops, I’d meant to remove the handle_path. My new Caddyfile is this but the errors persist:

http://localhost, http://192.168.1.34, server.theundarkpixel.com {
        root * /home/caddy/root/
        php_fastcgi /tt-rss/* unix//run/php/php7.4-fpm.sock
        file_server
}

hass.server.theundarkpixel.com {
        reverse_proxy localhost:8123
}

Edit: Oh wait, it works in incognito mode… Why would Chrome redirect me? I Thought I used the HTTPS Everywhere Chrome extension but it seems to be disabled…

For posterity, this is how I fixed it: https://superuser.com/a/881431/153280

And here’s my final Caddyfile

http://localhost, http://192.168.1.34, server.theundarkpixel.com {
    root * /usr/share/caddy

    @php path /tt-rss/* /launcher-update/*
    php_fastcgi @php unix//run/php/php7.4-fpm.sock

    file_server
}

hass.server.theundarkpixel.com {
    reverse_proxy localhost:8123 {
        header_up Host {http.request.host}
        header_up X-Real-IP {http.request.remote}
        header_up X-Forwarded-For {http.request.remote}
        header_up X-Forwarded-Port {http.request.port}
        header_up X-Forwarded-Proto {http.request.scheme}
    }
}

plex.server.theundarkpixel.com {
    reverse_proxy localhost:32400 {
        header_up Host {http.request.host}
        header_up X-Real-IP {http.request.remote}
        header_up X-Forwarded-For {http.request.remote}
        header_up X-Forwarded-Port {http.request.port}
        header_up X-Forwarded-Proto {http.request.scheme}
    }
}
1 Like

Thanks for following up with the solution!

Why all the header_up lines? Most of those are set automatically.

Yeah - you shouldn’t need any of those header_up lines.

We don’t actually set the X-Real-IP header or X-Forwarded-Port header automatically, because these are seldom used. I would be surprised if this particular application requires all of those headers though. It’d be worth simplifying as much as possible because for some reason people keep adding redundant config lines in and I can’t understand where they come from or why.

(Side note that does not apply in this situation: technically the Host header going upstream is set to {http.request.hostport} by default, not {http.request.host} – the difference being the port, but that usually only applies when sites are served on non-standard ports. In this case, the sites are on the standard :443 port, so clients don’t include the port in their Host header to Caddy. If your site was on a non-standard port, like :1234, then the incoming Host header might be example.com:1234 and if you wanted only example.com going to the backend, then that line as written would be the right way to strip the port. But again, that’s not necessary here.)

We should probably output lint warnings when we see these kinds of config lines that are likely irrelevant/redundant.

@matt @francislavoie I found something somewhere saying you needed transparent in Caddy v1 to proxy to Home Assistant and then I found another thing saying these directives were Caddy v2’s equivalent of transparent. Before I added them the hosted home assistant site couldn’t make a WebSocket connection back to the server; the upgrade always failed.

Where did you find that? It’s subtly wrong.

Maybe your backend requires one of those headers? But websockets “just work” without any changes. Please try removing them, then add them one-by-one until it works. I guarantee if all of them are needed, then it’s a bad backend; it might just need one of them, but it’s still not conventional in that case.

I found it here: V2: reverse-proxy transparent - #11 by Troy

Ah… that was very early in Caddy 2’s beta period, before it was even released. A lot has changed since then.

Oh, kk. I haven’t had time for trial-and-error yet, what subset do you think Home Assistant might need to establish a WebSocket connection?

Based on the nginx config described here: Reverse proxy using NGINX - Community Guides - Home Assistant Community, I suppose a vanilla reverse_proxy would work, unless it’s sensitive to the Host header. First try a plain reverse_proxy, then if it doesn’t connect, add header_up Host {host} – the linked guide shows that it might require the original request’s host name without the port. I dunno why. Anyway that’s what that line does. But start simple, then try different things until it works.

You’re right, that seems to work! And I was able to remove everything for Plex.

1 Like