WSS config in traefik

I have https working with certificates for my domain, services are LAN only. I have a Shelly smart relay that has a web admin interface at its ip address. I am trying to create a local DNS record for it so I can use SSL for when I access it. I set it up like my other local DNS records, but the interface never loads because it has this error in the web development console:

SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.

I think this is because traefik is not redirecting ws to wss. In searching for a solution I couldn't find anything other than that traefik should handle ws like http, and that no additional configuration should be required.

My traefik.yml entry points:

entryPoints:
  http:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: https
          scheme: https
  https:
    address: ":443"

and my routes and services:

http:
 #region routers
  routers:
    shelly-garage-pro2:
      entryPoints:
        - "https"
      rule: "Host(`garage-pro2-shelly.home.mydomain.top`)"
      middlewares:
        - default-headers
        - https-redirectscheme
      tls: {}
      service: shelly-garage-pro2
  services:
    shelly-garage-pro2:
      loadBalancer:
        servers:
          - url: "http://10.0.2.230"
        passHostHeader: true

and middleware:

  middlewares:
    https-redirectscheme:
      redirectScheme:
        scheme: https
        permanent: true
    default-headers:
      headers:
        frameDeny: true
        browserXssFilter: true
        contentTypeNosniff: true
        forceSTSHeader: true
        stsIncludeSubdomains: true
        stsPreload: true
        stsSeconds: 15552000
        customFrameOptionsValue: SAMEORIGIN
        customRequestHeaders:
          X-Forwarded-Proto: https

Do I need to add ws and wss entries as well?

is automatically set by Traefik for incoming requests via https.

"https-redirectscheme" middlewares is only needed for http, but you already have a redirect declared on entrypoint, so it's useless.

That is probably true, because the browser will not even try to load a WS link when the original page was loaded via https. Not sure if "Shelly smart relay" is smart enough to understand X-Forwarded-Proto and include a WSS link. Have you checked the page source and browser developer tools network tab to see what URLs are used?

It is using this URL:

Mixed Content: The page at 'https://garage-pro2-shelly.home.mydomain.top/settings' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://garage-pro2-shelly.home.mydomain.top/rpc'. This request has been blocked; this endpoint must be available over WSS.

I edited my middleware to add wss to the end of X-Forwarded-Proto based on this post: Websocket does not upgrade ws to wss
and also added Upgrade and Connection lines.

customRequestHeaders:
          X-Forwarded-Proto: https,wss
          Upgrade: WebSocket
          Connection: Upgrade

But those don't work.

You need to figure out why Shelly is not recognizing the https header and is not using WSS for the inline links.

The browser will not even load the unsecured link that’s included in the initial https html page, so Traefik can’t help here.

I would check in a dedicated Shelly forum if X-Forwarded-Proto is supported. If not, create a feature request with the company.

2 Likes