NGINX для обратного прокси-веб-сокетов и включения SSL (wss: //)?

Я так потерян и новичок в создании NGINX самостоятельно, но я хочу иметь возможность включать безопасные веб-сокеты без дополнительного уровня.

Я не хочу включать SSL на самом сервере websocket, но вместо этого я хочу использовать NGINX для добавления уровня SSL ко всему этому.

На каждой веб-странице написано, что я не могу этого сделать, но я знаю, что могу! Спасибо тому, кто (я) может показать мне, как!


person crockpotveggies    schedule 24.08.2012    source источник


Ответы (8)


Стоит отметить, что nginx теперь поддерживает веб-сокеты в версии 1.3.13. Пример использования:

location /websocket/ {

    proxy_pass ​http://backend_host;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 86400;

}

Вы также можете проверить журнал изменений nginx и документация по проксированию через WebSocket.

person Tarantula    schedule 19.02.2013
comment
У него такие же проблемы с тайм-аутом, как указано выше;) - person 3rdEden; 04.04.2013
comment
@ 3rdEden: По вопросам тайм-аута proxy_read_timeout работает, я отредактировал ответ. - person Steve Kehlet; 30.04.2013
comment
Куда мне поместить эту конфигурацию и что такое backend_host? - person Aysennoussi; 22.05.2014
comment
@Sekai: директива location помещается в server или другую директиву location (см. расположение документы). backend_host - это upstream (см. исходные документы) - одна или группа серверов, к которым вы будете подключаться. - person Radko Dinev; 13.08.2014
comment
@RadkoDinev - необходим ли апстрим, или, если у меня только один сервер, я могу просто использовать его в директиве proxy_pass? - person jlee; 23.08.2016
comment
@jlee Как указано в документации директивы proxy_pass, это значение равно URL в целом. Имея один сервер, вы можете просто использовать его DNS-имя или IP-адрес в качестве значения. upstream обычно используется для нескольких серверов и / или когда вы хотите указать дополнительные параметры (например, _ 3_). - person Radko Dinev; 23.08.2016
comment
Что насчет этой проблемы с тайм-аутом? Неужели мы действительно должны установить очень большое число, чтобы этого избежать? Нет ли сейчас более элегантного решения? - person Mohammed Noureldin; 05.01.2018
comment
Вы придумали решение? Поскольку мне также пришлось столкнуться с аналогичной проблемой, stackoverflow.com/q/53411060/7713811 - person Nɪsʜᴀɴᴛʜ ॐ; 22.11.2018
comment
Работал у меня. Я столкнулся с этой проблемой при развертывании приложения Blazor Server в экземплярах контейнеров Azure после выполнения этого документа: docs.microsoft.com/en-us/azure/container-instances/ - person Neurion; 18.01.2020
comment
Если мы используем https, почему мы пишем "proxy_http_version" и "proxy_set_header Upgrade $http_upgrade"? - person Normajean; 05.06.2021

Не бойтесь, потому что отважная группа программистов Ops разрешила ситуацию, выпустив новый nginx_tcp_proxy_module

Написано в августе 2012 года, поэтому, если вы из будущего, сделайте домашнее задание.

Предпосылки

Предполагается, что вы используете CentOS:

Создайте свой новый NGINX

Опять же, предполагает CentOS:

  • cd /usr/local/
  • wget 'http://nginx.org/download/nginx-1.2.1.tar.gz'
  • tar -xzvf nginx-1.2.1.tar.gz
  • cd nginx-1.2.1/
  • patch -p1 < /path/to/nginx_tcp_proxy_module/tcp.patch
  • ./configure --add-module=/path/to/nginx_tcp_proxy_module --with-http_ssl_module (вы можете добавить дополнительные модули, если они вам нужны)
  • make
  • make install

По желанию:

  • sudo /sbin/chkconfig nginx on

Настроить Nginx

Не забудьте сначала скопировать старые файлы конфигурации, если вы хотите использовать их повторно.

Важно: вам нужно будет создать директиву tcp {} на самом высоком уровне в вашей конфигурации. Убедитесь, что это не входит в вашу http {} директиву.

В приведенном ниже примере конфигурации показан один восходящий сервер websocket и два прокси для SSL и без SSL.

tcp {
    upstream websockets {
        ## webbit websocket server in background
        server 127.0.0.1:5501;
        
        ## server 127.0.0.1:5502; ## add another server if you like!

        check interval=3000 rise=2 fall=5 timeout=1000;
    }   

    server {
        server_name _;
        listen 7070;

        timeout 43200000;
        websocket_connect_timeout 43200000;
        proxy_connect_timeout 43200000;

        so_keepalive on;
        tcp_nodelay on;

        websocket_pass websockets;
        websocket_buffer 1k;
    }

    server {
        server_name _;
        listen 7080;

        ssl on;
        ssl_certificate      /path/to/cert.pem;
        ssl_certificate_key  /path/to/key.key;

        timeout 43200000;
        websocket_connect_timeout 43200000;
        proxy_connect_timeout 43200000;

        so_keepalive on;
        tcp_nodelay on;

        websocket_pass websockets;
        websocket_buffer 1k;
    }
}
person crockpotveggies    schedule 24.08.2012
comment
Это было очень полезно, но я все еще получал таймауты в 60 секунд. Мне удалось это исправить, установив следующее: timeout 43200000; websocket_connect_timeout 43200000; websocket_read_timeout 43200000; websocket_send_timeout 43200000; proxy_connect_timeout 43200000; proxy_read_timeout 43200000; proxy_send_timeout 43200000; - person jbg; 02.09.2012
comment
Я хотел обслуживать веб-сокеты через один и тот же http-порт и только после аутентификации браузера. Похоже, это не может обрабатывать веб-сокеты на том же порту. Как люди с этим справляются? - person uroc; 15.11.2012
comment
Для обнаружения входящего протокола потребуется некоторая модификация программного обеспечения. Поскольку веб-сокеты фактически запускаются как рукопожатие HTTP (более высокий уровень программного обеспечения, чем TCP), вам необходимо настроить свое приложение для обработки трафика TCP и HTTP. Я пока не могу порекомендовать способ сделать это. - person crockpotveggies; 16.11.2012
comment
Если сюда приедут другие ребята из 2018, эти директивы больше не работают. Чтобы узнать, как последние инструкции или см. ответ Харлана Т Вуда ниже. - person GaryO; 26.06.2018

Это сработало для меня:

location / {
    # redirect all HTTP traffic to localhost:8080
    proxy_pass http://localhost:8080;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # WebSocket support
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

- заимствовано из: https://github.com/nicokaiser/nginx-websocket-proxy/blob/df67cd92f71bfcb513b343beaa89cb33ab09fb05/simple-wss.conf

person Harlan T Wood    schedule 30.08.2016
comment
У меня возникли проблемы с тем, чтобы веб-сокеты TeamCity работали за моим обратным прокси. Ваш # WebSocket support нож сделал это за меня. Раньше я пробовал перенаправить порт 400, однако wss работает и над 443. К вашему сведению, будущие читатели :) - person Mario Tacke; 16.09.2016
comment
Вы придумали решение? Поскольку мне также пришлось столкнуться с аналогичной проблемой, stackoverflow.com/q/53411060/7713811 - person Nɪsʜᴀɴᴛʜ ॐ; 22.11.2018
comment
Мне больше всего нравится этот ответ, так как многие люди (как и вы) используют / как для веб-сокетов, так и для обычного HTTP2. - person mikemaccana; 27.03.2019
comment
@Anyone, что будет за вызывающий Javascript? - person Andrew Simpson; 08.08.2019
comment
Это сработало для меня и ShinobiCCTV через негарантированный и обратный прокси. Я видел, как блокируются веб-сокеты. - person kcabrams; 27.12.2020

для .net core 2.0 Nginx с SSL

location / {
    # redirect all HTTP traffic to localhost:8080
    proxy_pass http://localhost:8080;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # WebSocket support
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
}

Это сработало для меня

person Altair CA    schedule 10.10.2017
comment
что такое код C #. В настоящее время у меня есть это для windows / iis _server = new WebSocketServer (wss: //0.0.0.0: 8200 / MessageRelayer) {Certificate = new X509Certificate2 (PfxFileName, SslPassword), RestartAfterListenError = true}; - person Andrew Simpson; 18.01.2020
comment
Я использую SignalR - person Altair CA; 22.02.2020

Для меня все сводилось к настройке местоположения proxy_pass. Мне нужно было перейти на использование протокола HTTPS и настроить действующий сертификат SSL на стороне сервера узла. Таким образом, когда я представляю внешний сервер узла, мне нужно только изменить IP, а все остальное остается в той же конфигурации.

Надеюсь, это кому-то поможет ... Я все время смотрел на проблему ... вздох ...

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}
upstream nodeserver {
        server 127.0.0.1:8080;
}
server {
        listen 443 default_server ssl http2;
        listen [::]:443 default_server ssl http2 ipv6only=on;
        server_name mysite.com;
        ssl_certificate ssl/site.crt;
        ssl_certificate_key ssl/site.key;
        location /websocket { #replace /websocket with the path required by your application
                proxy_pass https://nodeserver;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;
                proxy_http_version 1.1;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_intercept_errors on;
                proxy_redirect off;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-NginX-Proxy true;
                proxy_ssl_session_reuse off;
            }
}
person CyberDigital    schedule 02.08.2017
comment
Я пробовал localtion /horizon, но не работает. Работает только localtion / или location /websockify. Не знаю почему ... - person njuguoyi; 27.10.2018

В хорошей краткой статье Панкаджа Малхотры обсуждается, как это сделать с помощью NGINX, и она доступна по адресу здесь.

Базовая конфигурация NGINX воспроизводится ниже:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

upstream appserver {
    server 192.168.100.10:9222; # appserver_ip:ws_port
}

server {
    listen 8888; // client_wss_port

    ssl on;
    ssl_certificate /path/to/crt;
    ssl_certificate_key /path/to/key;


    location / {
        proxy_pass http://appserver;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}
person btiernay    schedule 06.11.2015
comment
Решают ли современные версии NGINX проблемы с тайм-аутом? - person crockpotveggies; 07.11.2015

Использование nginx / 1.14.0

У меня есть веб-сервер, работающий на порту 8097, и пользователи подключаются к wss на порту 8098, nginx просто расшифровывает контент и перенаправляет его на сервер веб-сокета

Итак, у меня есть этот файл конфигурации (в моем случае /etc/nginx/conf.d/default.conf)

server {
    listen   8098;
        ssl on;
        ssl_certificate      /etc/ssl/certs/domain.crt;
        ssl_certificate_key  /root/domain.key;
    location / {

        proxy_pass http://hostname:8097;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;

    }
}
person john Smith    schedule 06.10.2018

Если вы хотите добавить SSL в свою тестовую среду, вы можете использовать mkcert. Ниже я упомянул URL-адрес GitHub.
https://github.com/FiloSottile/mkcert
А также ниже я упомянул пример конфигурации nginx для обратного прокси.

server {
        listen 80;
        server_name test.local;
        return 301 https://test.local$request_uri;
}
server {
  listen 443 ssl;
  server_name test.local;
  ssl_certificate /etc/nginx/ssl/test.local.pem;
  ssl_certificate_key /etc/nginx/ssl/test.local-key.pem;

   location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $remote_addr;
      proxy_set_header X-Client-Verify SUCCESS;
      proxy_set_header Host $http_host;
      proxy_set_header X-NginX-Proxy true;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_pass http://localhost:3000;
      proxy_redirect off;
      proxy_buffering off;
    }
}
person Nipuna Akalana Perera    schedule 18.02.2021