Как правильно сделать проксирование трафика на вебсокете в конфиге nginx? http://nginx.org/ru/docs/http/websocket.html
Допустим если сайт у нас расположен на 80 порте, а вебсокет по адресу ws://site.ru:2000
Как правильно сделать проксирование трафика на вебсокете в конфиге nginx? http://nginx.org/ru/docs/http/websocket.html
Допустим если сайт у нас расположен на 80 порте, а вебсокет по адресу ws://site.ru:2000
Вопрос решался просто:
в http{} дописываем
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server ваш_ип:2000;
}
в server{} дописываем
location /websocket {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
в nginx.conf дописываем
keepalive_timeout 604800;
proxy_connect_timeout 604800;
proxy_send_timeout 604800;
proxy_read_timeout 604800;
вебсокет открываем таким образом
var socket = new WebSocket("ws://ваш_ип_или_домен/websocket");
Не работает такой конфиг. Выдается ошибка в консоли браузера:
WebSocket connection to ws://site.com/ws failed: Error during WebSocket handshake: Unexpected response code: 200
По этой ошибке очень-очень много вопросов по всем форумам, но ни одного ответа. Такое ощущение, что не умеет реально nginx ws проксировать. Проблема лечится легко, просто надо в js коде соединение с ws устанавливать с явным указанием порта
var socket = new WebSocket("ws://ваш_ип_или_домен:9999");
В этом случае сразу все работает.
Отсюда вопрос: зачем вообще проксировать ws через nginx?
Проверить Origin (хост с которого подключаются к ws) легко может сам ws сервер. На ум приходит только одно: проксировать надо, чтобы избежать а-ля ddos атак на порт ws, чтобы обращения сначала фильтровал nginx а потом уже ws сервер. Потому что теоретически ws сервер завалится гораздо быстрее nginx.
Есть ли в этом смысл - защищать таким образом ws сервер? Кто может обосновать?
wss, не 443. См. RFC6455. Как обычно, в документации всё есть, просто глубже, чем ожидается.
–
Apr 28 '16 at 21:18
proxy_set_header Connection "Upgrade";нужно заменить наproxy_set_header Connection $connection_upgrade;, иначе объявлениеmapвыше не имеет смысла. Весь смысл этогоmapкак раз в том, чтобы один и тот же upstream использовать как для websocket-соединений, так и для обычных http-соединений. Принцип работы в итоге такой: если в исходном запросе присутствует непустой заголовокUpgrade, то передать в upstream заголовокConnectionсо значениемupgrade, иначе передать в upstream заголовокConnectionсо значениемclose. – Ruslan Stelmachenko Jul 08 '17 at 04:35