Reserve proxy website behind ISP Router redirect loop

1. Caddy version (caddy version):

v2.4.5 h1:P1mRs6V2cMcagSPn+NWpD+OEYUYLIf6ecOa48cFGeUg=

2. How I run Caddy:

docker-compose caddy

caddy run --config /etc/caddy/Caddyfile --adapter caddyfile

a. System environment:

Debian 10.10 Container on a proxmox server with Docker 18.09.1, build 4c52b90

b. Command:

caddy run --config /etc/caddy/Caddyfile --adapter caddyfile

c. Service/unit/compose file:

FROM caddy:2.4.5-builder AS builder

RUN xcaddy build --with github.com/caddy-dns/cloudflare

FROM caddy:2.4.5

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

d. My complete Caddyfile or JSON config:

rpi.domaincom {
          reverse_proxy http://192.168.137.5:8080
}

3. The problem I’m having:

I have a rpi4 running kodi with the webinterface active, i would like to access it through https://rpi.domaincom which loads fine but the websocket fails with:
WebSocket connection to ‘wss://rpi.domaincom:9090/jsonrpc?kodi’ failed

when attempting to access it directly from the browser i get the following error message:
ERR_DISALLOWED_URL_SCHEME

However, the websocket seems to work fine if i access it from http://192.168.137.5:8080

5. What I already tried:

I tried specifying the IP address in the webinterface settings to bypass the reverse proxy but i believe it detects the interface loading from https and redirects the websocket requests to wss (secure).

I tried the following configs:

rpi.domaincom:9090 {
        reverse_proxy ws://192.168.137.5:9090 {
                transport http {
                        tls_insecure_skip_verify
                }
        }

}

No errors from this one.

tried:

rpi.domaincom {
  reverse_proxy /jsonrpc ws://192.168.137.5:9090
  reverse_proxy http://192.168.137.5:8080
}

This generates the following errors:
2021/10/04 15:01:06.318 ERROR http.handlers.reverse_proxy aborting with incomplete response {"error": "context canceled"}

I’ve only recently started working with Caddy and i’m also not familiar with websockets, is it possible to attach a certificate to the websocket since it’s being called from the js within the https connection, i suspect the SSL would prevent any security policies enforced by the browser much like http elements being called in a https page url.

I’m confused, your config does not listen on port 9090, but your request URL uses port 9090.

If configuring Caddy with just a hostname for the site address, then Caddy will be listening on port 443 for HTTPS requests, and port 80 for HTTP requests (and redirect HTTP to HTTPS).

ws:// is not a valid scheme for reverse_proxy – under the hood, websockets is actually an initial HTTP request which expects a 101 Switching Protocols response, which turns the connection into a duplex TCP pipe. So using http:// is fine.

Is your upstream websocket app listening for HTTPS requests, or for HTTP? If it’s just HTTP, then remove this chunk.

So is your upstream’s HTTP and Websockets running on different ports? If so, then this config is probably the closest to getting what you need, but you should change it to http:// instead of ws:// (or just omit the scheme, because http:// is implicit), and you might want to use a matcher like this to avoid depending on the request path for determining if it’s a websocket request:

@websockets {
	header Connection *Upgrade*
	header Upgrade websocket
}
reverse_proxy @websockets 192.168.137.5:9090

reverse_proxy 192.168.137.5:8080

Thanks for the help!

kodi interface runs on port 8080 but because caddy serves it on https:// the javascript responsible for the websocket attempts to create a wss:// connection instead of ws://. which i don’t believe the backend serves, it only seems to work on ws://.

rpi.domaincom:9090 {
        @websockets {
                header Connection *Upgrade*
                header Upgrade websocket
        }
        reverse_proxy @websockets 192.168.137.5:9090
}

I’m guessing you were referring to something like this? But it doesn’t seem to work as well, i get connection refused and nothing on caddy logs. I think the browser policy might be blocking it’s access and the web interface service is also crashing on rpi side. I’ll leave it until i have time do work on this as well.

I appreciate your help and i hope you are having a good day!

wss:// is simply ws:// over HTTPS (rather than HTTP). So if you have Caddy in front of it terminating TLS, then you should use wss://.

Are you able to configure the endpoint your app uses to connect to websockets? If possible, avoid using port 9090, and use port 443 (the default for wss:// and https://. In other words, make sure the browser tries to connect to wss://rpi.domaincom/jsonrpc.

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