Socket.io problem on HTTPS proxied server

  • My Caddy version ( v1.0.4 )
  • Debian GNU/Linux 10 (buster) / Linux 4.19.0-6-amd64

Hi all. Loving Caddy! But I am very new to Linux and Caddy; hope somebody can help with my problem. Thanks!

The Project
I have an open source media player running on a Raspberry pi. I am wanting to access it via an HTTPS connection, so I have a domain name pointed at my home router. Port forwarding pointing to a separate server running Caddy. I have a very basic Caddyfile config which seems bona fide and it is sending SSL requests to my media server.

The Error

When I navigate to my https address for the media server, I can load the page and I can see the UI for the media player - BUT it is covered by a “grey-out” screen and has a never ending spinning wheel. So it’s not fully loading.

When I go to the Google Developer Console in Chrome, I get these hints/symptoms…

The media server; under normal conditions is meant to be accessed via HTTP on a local network. There are a bunch of healthy connections that look like this:

http://192.168.1.7/socket.io/?EIO=3&tran ...

However, on an HTTPS connection I get lots of “red” entries. Like this:

GET http://127.0.0.1:3000/socket.io/?EIO=3&transport=polling&t=M_HFcoc net::ERR_CONNECTION_REFUSED

So on HTTPS my requests are going to 127.0.0.1; when they should be going to 192.168.1.7. This seems to be a websocket / socket.io problem.

My Caddyfile

my-domain.com  {
	proxy / 192.168.1.7 {
		transparent
		websocket
	}
}

Question

So, why does my server when proxied on port 80 work? Then fails when I try on HTTPS? Socket.io connections are fine on an HTTP connection.

Extra info

Just wanted to add that whilst I have access to the Linux system that the media server runs on - I don’t think I can attempt any changes to what it does. Reboots seem to restore any system alterations (I’d have to investigate that further). So I want to stress that I have almost no control over what my proxied server dishes out. I hope my solution can be done purely on the Caddy server side of this setup.

Thanks all!
Milster

1 Like

When using websockets, typically you use ws:// as the scheme for websockets using HTTP, and wss:// for websockets using HTTPS. Might it be that you didn’t use wss:// on your client?

Hi @francislavoie - thanks for your interest!
When you say in “your client” do you mean Caddy acting as the client to the proxied server?
If so, how might I integrate that into my Caddyfile?
Something like this perhaps…?

my-domain.com  {
	proxy / 192.168.1.7 {
		transparent
		websocket
	}
	proxy /socket.io/  ws://192.168.1.7/socket.io/ {    # or wss://192.168.1.7/socket.io/ {
		websocket
	}
}

Or if you mean the client browser visiting the site, again, I’m not sure how to integrate ws:// or wss://.

So you know; when I described the bad websocket connections in my original post - that is when a browser visits https://my-domain.com. Whereas the healthly websocket connections were achieved when going to http://192.168.1.7 from within my network.

I meant from the browser (i.e. the client). Could you share which media player app you’re running? You might need to do some additional configuration to get it working.

Here’s what I think should happen: browser loads https://my-domain.com, which probably loads the /js/app.js or equivalent of the app, which includes the socket.io frontend code, which should probably attempt to connect to wss://my-domain.com.

Also I don’t remember exactly how Caddy behaves in this situation, but you may need to specify the port number when using the proxy directive here. I’m not sure whether Caddy will default to using 80 if you don’t specify a scheme, or whether it’ll try to use 443 if the connection to Caddy was over https. You could try this:

my-domain.com {
	proxy / 192.168.1.7:80 {
		transparent
		websocket
	}
}

Also, I’m not too sure I understand the network topology here. So if I’m understanding correctly, 192.168.1.7 is your Raspberry Pi, and you have ports 80 and 443 on your router forwarded to some other PC, let’s just say 192.168.1.10 for example?

Also, it would probably help to enable logging on Caddy to see what requests it sees and whether any errors are happening. Add these directives to your Caddyfile: https://caddyserver.com/v1/docs/log and https://caddyserver.com/v1/docs/errors

The media player is Volumio

  • Caddy server is on 192.168.1.11
  • Volumio is on 192.168.1.7
  • Router is on 192.168.1.1
    Port 80 is open and pointing to 192.168.1.11
    Port 443 is open and pointing to 192.168.1.11

I just tried…

my-domain.com  {
        proxy / 192.168.1.7:80 {
                transparent
                websocket
        }
}

and got this worrying message in Google Developer Console.

Mixed Content: The page at 'https://my-domain.com/playback' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://my-domain.com/api/host'. This request has been blocked; the content must be served over HTTPS.

Also, I added these two lines to Caddyfile - nothing happening there.

log /etc/caddy access.log
errors /etc/caddy/error.log

So, it looks like Volumio has the smarts to detect that their is a mixed request coming in and it does not like it. Any ideas?

That mixed content warning is coming from Chrome, not from Volumio.

I did some digging, it seems that because Volumio is also a paid product, they don’t put much priority on fixing issues that prevent some users from being able to enable HTTPS. See this issue where they reject a request from someone to avoid hard-coding http:// in their code, which means the app always attempts to connect to websockets over http.

2 Likes

Yes, Volumio itself is free to load on a pi and run on your local network - but the developers added a bonus feature called “MyVolumio” where you can pay for a bunch of enhancements. One of which is access via HTTPS. I only want the HTTPS feature, so I am having trouble justifying the expense for such a small home use scenario.

Thanks for your help on this!! I have a rough idea of what you are saying. So where does that leave me? Is it a lost cause?

https://github.com/volumio/Volumio2-UI/issues/258

Here’s some more examples of the devs refusing to make the simple changes to allow it to run behind a reverse proxy.

I’m sorry to say that you’re kinda stuck. I don’t think we’ll be able to help you here, you might need to try to convince them to fix their code for it to work.

2 Likes

Well you can understand that them fixing their code would “un-fix” their business model to earn money from MyVolumio subscriptions. I don’t like my/our chances.

What a shame. However, I did enjoy learning so much about reverse-proxies and linux etc. Just wish it had ended with a win.

Finally, thanks for helping me along the way!!! Much appreciated!

Some success!

Firstly 3 cheers to @francislavoie who did some great hunting on github and provided some links that led me to a solution. Thank you very much mate!

If you find yourself in my position, you need to activate SSH on your Volumio, then navigate to this file…
/volumio/http/www/app/local-config.json

It only contains one line of code…

{"localhost": "http://127.0.0.1:3000"}

Edit this to match your HTTPS address, for example…

{"localhost": "https://my-domain.com"}

Voila! No more never-ending wheel - a connection has been fully made.

PS. In an earlier post I stated I had no control over edits on Volumio. I had earlier been making some changes in folders inside of /var. They were being lost on reboot so I made the assumption it was system-wide behaviour. Not so. The above edit, so far has outlasted subsequest reboots.

3 Likes

Nice! Glad you found a solution!

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