Я пытаюсь заставить websockets (socket.io) работать через 2 proxy_pass и 2 разных сервера (один - сервер балансировки нагрузки, другой - реальный сервер). Я получаю 400, когда socket.io пытается
В этом случае у меня есть два сервера, 1 имя_домена:
имя_домена: dev-socket.domain.com -> cname to lb.domain.com
Сервер 1: lb.domain.com
- обработка всех сертификатов
- обрабатывая все наши запросы {subdomain} .domain.com, proxy_pass их на правильные серверы
- все отлично работает, кроме веб-сокетов
Сервер 2: dev.domain.com
- разместить фактический API, обрабатывающий все websockets
- nginx proxyPass на право: порт приложения
Что должно работать, а что нет:
dev-socket.domain.com (имя_домена) -> lb.domain.com (Server1, ssl) -> dev.domain.com (server2) -> nodeJsApp
Это 400.
ЧТО РАБОТАЕТ: это работает, если я обхожу lb.domain.com и напрямую делаю это:
dev-socket.domain.com (имя_домена) -> dev.domain.com (server2, ssl) -> nodeJsApp
сервер 1: lb.domain.com:
map $http_connection $upgrade_requested {
default upgrade;
'' close;
}
server {
listen 80;
listen 443 ssl http2;
server_name dev-socket.domain.com;
access_log /var/log/nginx/dev-socket.domain.com-access.log;
error_log /var/log/nginx/dev-socket.domain.com-error.log error;
client_max_body_size 256M;
ssl_certificate /etc/letsencrypt/live/dev-
socket.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dev-
socket.domain.com/privkey.pem;
includeSubDomains; preload";
location /socket/live {
proxy_read_timeout 120;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://91.121.117.17/socket/live;
}
location / {
proxy_pass http://server_dev;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
location ~ ^/.well-known/acme-challenge/ {
allow all;
default_type "text/plain";
root /usr/share/nginx/html/;
}
}
сервер 2: dev.domain.com
map $http_connection $upgrade_requested {
default upgrade;
'' close;
}
server {
listen *:443;
server_name dev-socket.domain.com;
#ssl_certificate /etc/letsencrypt/live/dev-socket.domain.com/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/live/dev-socket.domain.com/privkey.pem;
#ssl on;
client_max_body_size 5M;
access_log /var/log/nginx/dev-socket.domain.com;
error_log /var/log/nginx/dev-socket.error;
location /socket/live {
proxy_pass http://localhost:3000;
proxy_read_timeout 120;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen *:80;
server_name dev-socket.domain.com;
if ($http_x_forwarded_proto != "https") {
return 301 https://$server_name$request_uri;
}
access_log /var/log/nginx/dev-socket.domain.com;
error_log /var/log/nginx/dev-socket.error;
location / {
proxy_pass http://localhost:3000;
}
}
вышеупомянутая конфигурация получает простую ошибку 400 во время рукопожатия вместо успеха.
WebSocket connection to 'wss://dev-socket.domain.com/socket/live/?Auth=e02b7a2ab5c158d7f46c18d36f45955bf3769716&sessionId=5a38e191fc6bf8602001b237&EIO=3&transport=websocket&sid=Fu6M2b1I9sh9stLFAANX' failed: Error during WebSocket handshake: Unexpected response code: 400
Я могу подтвердить, проверив журналы активности обоих nginx (server1, server2), что запрос поступает на server2. Так что на данный момент я предполагаю что-то о искаженном заголовке ..
Как уже говорилось, если я обхожу lb.domain.com и активирую ssl в директиве dev.domain.com, он работает