Search code examples
kubernetessignalrsignalr.clientazure-aks

SignalR behind k8s nginx ingress disconnects immediately upon connection


Here's what I have for the nginx ingress:

 nginx.ingress.kubernetes.io/proxy-set-headers:       xyz/proxy-headers
  nginx.ingress.kubernetes.io/read-timeout:            3600
  nginx.ingress.kubernetes.io/session-cookie-expires:  14400
  nginx.ingress.kubernetes.io/ssl-protocols:           TLSv1.3 TLSv1.2
  cert-manager.io/cluster-issuer:                      letsencrypt
  nginx.ingress.kubernetes.io/affinity:                cookie
  nginx.ingress.kubernetes.io/configuration-snippet:   if ($host = 'example.com' ) {
rewrite ^ https://www.example
.com$request_uri permanent;
}

  nginx.ingress.kubernetes.io/proxy-buffer-size:       16k
  nginx.ingress.kubernetes.io/force-ssl-redirect:      true
  nginx.ingress.kubernetes.io/proxy-body-size:         8m
  nginx.ingress.kubernetes.io/proxy-send-timeout:      3600
  nginx.ingress.kubernetes.io/server-alias:            example.com
  nginx.ingress.kubernetes.io/session-cookie-max-age:  14400
  nginx.ingress.kubernetes.io/session-cookie-name:     affinity

...
}

Here's the proxy headers:

apiVersion: v1
kind: ConfigMap
metadata:
  name: proxy-headers
  namespace: xyz
data:
  X-Content-Type-Options: "nosniff"
  X-XSS-Protection: "1; mode=block"
  Referrer-Policy: "no-referrer-when-downgrade"
  Feature-Policy: "notifications 'self'; usemedia *;gyroscope: 'none'"

When connected directly, the websocket is fine. When it's behind nginx I get the following:

main.5f9ab0903b48ce06734b.js:6 [2020-04-20T18:54:39.190Z] Information: Connection disconnected.
main.5f9ab0903b48ce06734b.js:6 Could not connect Error: Cannot send data if the connection is not in the 'Connected' State.
main.5f9ab0903b48ce06734b.js:6 ERROR Error: Uncaught (in promise): [object Undefined]
    at _ (polyfills.d1de8a43b27b04443379.js:1)
    at t.handshakeRejecter (polyfills.d1de8a43b27b04443379.js:1)
    at t.connectionClosed (main.5f9ab0903b48ce06734b.js:6)
    at t.connection.onclose (main.5f9ab0903b48ce06734b.js:6)
    at t.stopConnection (main.5f9ab0903b48ce06734b.js:6)
    at t.Y.transport.onclose (main.5f9ab0903b48ce06734b.js:6)
    at t.close (main.5f9ab0903b48ce06734b.js:6)
    at t.stop (main.5f9ab0903b48ce06734b.js:6)
    at t.<anonymous> (main.5f9ab0903b48ce06734b.js:6)
    at main.5f9ab0903b48ce06734b.js:6

I can't find anything that would cause it to do what it's doing and I can't get any deeper insight into what's causing it. Ideas?


Solution

  • Here's what I ultimately came up with:

    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/x-forwarded-proto: https
    nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
    nginx.ingress.kubernetes.io/read-timeout: "3600"
    nginx.ingress.kubernetes.io/send-timeout: "3600"
    nginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.3 TLSv1.2"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.ingress.kubernetes.io/session-cookie-name: "affinity"
    nginx.ingress.kubernetes.io/session-cookie-expires: "14400"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "14400"
    nginx.ingress.kubernetes.io/affinity: cookie
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: 16m
    nginx.ingress.kubernetes.io/add-headers: "yournamespace/add-headers"
    

    And then the following in the add-headers config map:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: add-headers
      namespace: yournamespace
    data:
      X-Content-Type-Options: "nosniff"
      X-XSS-Protection: "1; mode=block"
      Referrer-Policy: "no-referrer-when-downgrade"
      Feature-Policy: "notifications 'self'; usemedia *;gyroscope: 'none'"
      kind: ConfigMap
    

    This enables SignalR to work properly behind the proxy, handles affinity (which apparently was the original issue) and gives you full HSTS encryption and an A+ rating on crypto tests.