I have a part of my application which is designed to handle websocket connection from my React frontend using socket.io
Issue
I've set everything up and now I have an issue where HTTP handshake attempt from socket.io-client gets status 400 as response, and if I try to use directly WebSocket transport I see only repeating Finished status in Network Tab
Setup
My backend setup: Docker > NestJS (socket.io)
My AWS setup: CloudFront > NLB > ECS Fargate
My frontend setup: React + socket.io
Additional Info
NestJS logs in CloudWatch are pure, the last one: NestJS successfully started Expected last: Connected: user id after reaching endpoint in my frontend
I've tested connection of NestJS container by navigating in browser to / root path using CloudFront domain name, and it works well - returns Hello World page as it should, so the NestJS server is running
Also locally tested my NestJS with and without container - everything works as expected, so the issue is somewhere in AWS Infrastructure
Starting from the bottom, my configs:
NestJS
NestJS runs at port 80
WebSocket Gateway inherits port 80, no namespace defined
Docker
Docker exposes port 80
ECS
ECS Task Definition port mapping - 80:80 TCP
ECS Service (NestJS container) Security Group: Allowed All TCP:0-65535 traffic from NLB
NLB
NLB Security Group 1: IPv4 HTTPS TCP:443. from 0.0.0.0/0 (just in case)
NLB Security Group 2: IPv4 HTTP TCP:80. from 0.0.0.0/0
NLB Listener set up as TCP:80 to Target Group which contains service which runs NestJS container
CloudFront
CloudFront Security Policy: TLSv1.2_2021
CloudFront Supported HTTP versions: HTTP/2, HTTP/1.1, HTTP/1.0
CloudFront terminates TSL and routes traffic to NLB using TCP:80 although by itself accepts 443 (HTTP only to > NLB)
CloudFront strategy: Redirect HTTP to HTTPS (incoming)
IMPORTANT UPDATE: Connected to NLB avoiding CloudFront - works. Issue is somewhere in CloudFront
Solved!
I should've attach Cache Policy which allows to preserve headers (Origin, Host, Authorization in my case) and connection has been established successfully.
CloudFront, select Policies at the left menu
Under "Custom Policies" click "Create cache policy"
Under the "Cache key settings" select "Include the following headers" and include headers you need Also I've added query strings: All
Then attach Policy at the "Origins" tab inside the "Origin Settings"