174

我对自己构建 NGINX 感到迷茫和陌生,但我希望能够在没有额外层的情况下启用安全的 websocket。

我不想在 websocket 服务器本身上启用 SSL,而是想使用 NGINX 为整个事物添加 SSL 层。

那里的每个网页都说我做不到,但我知道我可以!感谢任何人(我自己)可以告诉我如何!

4

8 回答 8

250

请注意,nginx 现在在 1.3.13 版本中支持 Websockets。使用示例:

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 代理文档。

于 2013-02-19T23:58:37.797 回答
59

不要害怕,因为一群勇敢的 Ops 程序员已经用全新的nginx_tcp_proxy_module解决了这个问题

写于 2012 年 8 月,所以如果你来自未来,你应该做好功课。

先决条件

假设您使用的是 CentOS:

  • 删除当前的 NGINX 实例(建议为此使用开发服务器)
  • 如果可能,请保存您的旧 NGINX 配置文件,以便您可以重新使用它们(包括您的init.d/nginx脚本)
  • yum install pcre pcre-devel openssl openssl-devel以及用于构建 NGINX 的任何其他必要库
  • 在这里https://github.com/yaoweibin/nginx_tcp_proxy_module从 GitHub获取nginx_tcp_proxy_module并记住放置它的文件夹(确保它没有被压缩)

构建你的新 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 {}conf.xml 的最高级别创建一个指令。确保它不在您的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;
    }
}
于 2012-08-24T01:23:38.310 回答
59

这对我有用:

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

于 2016-08-30T00:07:13.780 回答
25

用于带有 SSL 的 .net core 2.0 Nginx

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;
}

这对我有用

于 2017-10-10T20:26:45.337 回答
11

对我来说,它归结为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;
            }
}
于 2017-08-02T09:11:22.330 回答
8

一篇由 Pankaj Malhotra 撰写的简洁的好文章讨论了如何使用 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;
    }
}
于 2015-11-06T22:02:02.210 回答
6

使用 nginx/1.14.0

我有一个在 8097 端口上运行的 websocket 服务器,用户从 8098 端口连接到 wss,nginx 只是解密内容并将其转发到 websocket 服务器

所以我有这个配置文件(在我的情况下/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;

    }
}
于 2018-10-06T14:31:04.043 回答
3

如果要在测试环境中添加 SSL,则可以使用mkcert. 下面我提到了 GitHub URL。
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;
    }
}
于 2021-02-18T20:07:58.853 回答