WebSocket fails when running behind Authelia & Caddy
Apparently after (relatively) recent updates Metube fails to work correctly while running behind Authelia and a reverse proxy.
This is how the page looks, showing "Connection to server" message.
Network tab shows the following.
docker-compose.yml:
metube:
container_name: metube
image: alexta69/metube:latest
volumes:
- *******:/downloads
restart: unless-stopped
Authelia logs show this repeatedly:
time="2024-06-21T00:07:51Z" level=info msg="Access to https://metube.example.com/socket.io/?EIO=4&transport=polling&t=P0u7k_t (method GET) is not authorized to user <anonymous>, responding with status code 302 with location redirect to https://auth.example.com/?rd=https%3A%2F%2Fmetube.example.com%2Fsocket.io%2F%3FEIO%3D4%26transport%3Dpolling%26t%3DP0u7k_t&rm=GET" method=GET path=/api/authz/forward-auth remote_ip=192.168.0.1
Caddyfile configuration:
metube.example.com {
forward_auth authelia:9091 {
uri /api/authz/forward-auth
copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
}
reverse_proxy metube:8081
}
I understand this is likely an issue with misconfigured Caddy instance. However if someone could possibly help me with this it would be great.
can you try it without https to see if it's ssl's issue?
After some google, I think this is a problem with Caddy proxying the wss protocol. Maybe changing the Authelia authentication method from http headers to cookies will help. Or open the wss protocol in Authelia (no authentication required)
can you try it without https to see if it's ssl's issue?
Authelia does not allow HTTP traffic: Target URL 'http://metube.example.com/' has an insecure scheme 'http', only the 'https' and 'wss' schemes are supported so session cookies can be transmitted securely.
After some google, I think this is a problem with Caddy proxying the wss protocol.
Caddy's official documentation states:
example.com {
@websockets {
header Connection *Upgrade*
header Upgrade websocket
}
reverse_proxy @websockets localhost:6001
reverse_proxy localhost:8080
}
Meaning that WSS is supported by Caddy. This header configuration correlates with other reverse proxies configurations.
Weirdly enough, even without these directives and proper matchers in Caddyfile, the issue has been corrected after deleting browser cookies, but only temporarily:
In a couple minutes I restarted Authelia without changing anything else and once again requests to /socket.io are dropped. So relogging to Authelia solves this, but only for a short time.
This is happening with Traefik (image hash id 9ff754a4bfc1) as proxy. Metube docker image hash id eeb35e1aa58f.
Based on discussion here and issue #478 Authelia's maintainer provided a clue as to why this happens. Apparently Metube does not honor 302 Found responses.
https://github.com/authelia/authelia/discussions/7834 This might be of help.
I'm seeing the same behavior with traefik and authentik.
Apparently Metube does not honor 302 Found responses.
Metube probably can't handle the redirect to Authelia due to CORS policy. Try adding CORS with Authelia allowed on the Traefik side:
- "traefik.http.middlewares.metube-auth-cors.headers.customresponseheaders.Access-Control-Allow-Origin=https://auth.example.com"
Update: My solution above will not work
What caused this issue? - Browsers caching the Metube frontend and displaying it even when we are logged out from Authelia. This cached frontend tries to call the backend via socket.io getting 302 redirect to authelia and encounters a CORS error.
By using the fix above, we're addressing this CORS error, but the browser is still not redirected since Blink-based browsers (Chrome, Brave, etc.) do not honor redirects coming from subrequests.
As a solution, we likely need to disable caching for the index.html. This will make it possible to get the Authelia redirect immediately on the first request.
@alexta69 , what do you think about including this in the index.html?
<meta http-equiv="Cache-control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
This should prevent caching for the index file without any downsides because all other assets will still be cached.
Also, most likely, this commit was intended to fix the same issue with basic auth. This is the wrong solution, as it accepts forwarding basic auth credentials to third-party hosts(named as crossorigins), which potentially opens up a security issue and should be removed.
Thank you all, and sorry if I'm wrong about anything
Update: Cache should be handled on the service worker side, headers probably won't fix the bug
@mazzz1y not sure if that's what you mean in the update, but any reason you're seeing not to add the Cache-Control header on the server side, as opposed to meta tags in the HTML?
but any reason you're seeing not to add the Cache-Control header on the server side, as opposed to meta tags in the HTML?
We can do it on the server side, of course. But please see the update in the post. I've figured out that the caching problem is on the Service Worker side and should probably be handled there.
I'm not familiar with the frontend side, so I'm sorry for the confusion.
Fixed in #548