title: Web Socket wss:// in AWS EKS with nginx Ingress. returns 400. ws://, http:// and https:// works perfectly
body: <p>I've been trying to run few services in AWS EKS Cluster. I followed the ingress-nginx guide to get https with AWS ACM certificate</p>
  <blockquote>
  <p><a href="https://kubernetes.github.io/ingress-nginx/deploy/#aws" rel="noreferrer">https://kubernetes.github.io/ingress-nginx/deploy/#aws</a></p>
  </blockquote>
  <p>Used tls termination at ingress controller</p>
  <p>I used 3 routes for each services as</p>
  <p><strong>adminer.xxxx.com</strong> - points to an adminer service</p>
  <p><strong>socket.xxxx.com</strong> - points to the wss service written in nodejs</p>
  <p><strong>service.xxxx.com</strong> - points to a program that returns a page which connects to socket url</p>
  <p>Without TLS Termination, in http:// everything works fine, <strong>ws://socket.xxxx.com/socket.io</strong> gets connected and responds well.</p>
  <p>When I add TLS, the request goes to <strong>wss://socket.xxxx.com/socket.io</strong> and the nginx returns 400. I Can't figure out why it happens.</p>
  <pre><code>apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    name: ingress-service
    annotations: 
      kubernetes.io/ingress.class: nginx
      nginx.ingress.kubernetes.io/proxy-body-size: 100m
      nginx.ingress.kubernetes.io/configuration-snippet: |
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $http_host;
      # nginx.ingress.kuberenetes.io/use-regex: &quot;true&quot;
  spec:
    rules:
      - host: adminer.xxxx.com
        http:
          paths:
            - path: /
              backend:
                serviceName: adminer-svc
                servicePort: 8080
      - host: socket.xxxx.com
        http:
          paths:
            - path: /
              backend:
                serviceName: nodejs-svc
                servicePort: 2020
      - host: service.xxxx.com
        http:
          paths:
            - path: /
              backend:
                serviceName: django-svc
                servicePort: 8000
  </code></pre>
  <p>I Tried with and without these configurations</p>
  <pre><code>nginx.ingress.kubernetes.io/configuration-snippet: |
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Host $http_host;
  </code></pre>
  <p>Also I've tried changing the <strong>socket.xxxx.com</strong> into <strong>service.xxxx.com</strong> and assigned to be forwarded for <em><strong>/socket.io</strong></em> path</p>
  <p>I've also put a url in nodejs with express to test if its working at all, and it responds properly in https://</p>
  <p>Only the wss:// has the issue.</p>
  <p>PS : This entire Service works when nginx is setup in a normal system  with nginx configuration</p>
  <pre><code>location / {
        proxy_pass http://localhost:2020/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection &quot;upgrade&quot;;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
  }
  </code></pre>
  <p>I tried request like this as well</p>
  <p><a href="https://node-socket.xxxx.com/socket.io/?EIO=3&amp;transport=polling" rel="noreferrer">https://node-socket.xxxx.com/socket.io/?EIO=3&amp;transport=polling</a> this works</p>
  <p><a href="https://node-socket.xxxx.comsocket.io/?EIO=3&amp;transport=websocket" rel="noreferrer">https://node-socket.xxxx.comsocket.io/?EIO=3&amp;transport=websocket</a> this doesnt.</p>
  <p>Combinations I tried</p>
  <pre><code>protocol, balancer, backendproto, transport =&gt; result
  wss://, ELB, TCP, websocket  =&gt;  400
  wss://, NLB, TCP, websocket  =&gt;  400
  wss://, ELB, HTTP, websocket  =&gt;  400
  wss://, NLB, HTTP, websocket  =&gt;  400
  ws://, ELB, TCP, websocket =&gt; 400
  ws://, ELB, HTTP, websocket =&gt; 400
  ws://, NLB, TCP, websocket =&gt; 400
  ws://, NLB, HTTP, websocket =&gt; 400
  </code></pre>
  <p>polling worked in every cases</p>