NGINX反向代理websockets并启用SSL(wss://)?

cro*_*ies 120 ssl proxy tcp nginx mod-proxy

我很遗憾和我自己建立NGINX的新手,但我希望能够启用安全的websockets,而无需额外的层.

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

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

Tar*_*ula 166

请注意,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;

}
Run Code Online (Sandbox Code Playgroud)

您还可以检查nginx更改日志WebSocket代理文档.

  • @ 3rdEden:对于超时问题,`proxy_read_timeout`有效,我编辑了答案. (4认同)
  • @Sekai:`location`指令放在`server`或另一个`location`指令中(参见[location docs](http://nginx.org/en/docs/http/ngx_http_core_module.html#location)).`backend_host`是一个`upstream`(参见[upstream docs](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream)) - 你要代理的一个或一组服务器. (3认同)
  • 我应该在哪里放置此配置,什么是backend_host? (2认同)

cro*_*ies 53

不用担心,因为一群勇敢的Ops程序员已经通过一个新的nginx_tcp_proxy_module品牌解决了这个问题

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

先决条件

假设您使用的是CentOS:

  • 删除NGINX的当前实例(建议使用dev服务器)
  • 如果可能,保存旧的NGINX配置文件,以便可以重复使用它们(包括init.d/nginx脚本)
  • yum install pcre pcre-devel openssl openssl-devel 以及用于构建NGINX的任何其他必要的库
  • 从GitHub 获取nginx_tcp_proxy_module这里https://github.com/yaoweibin/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中的最高级别创建指令.确保它不在你的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这非常有帮助,但我仍然在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; (5认同)
  • 感谢您的分享!后来我意识到自己也遇到类似的问题,巧合的是,yaoweibin本人也回答了我的GitHub问题,并提供了您对第28期的评论的链接。小世界... (2认同)
  • 如果2018年的其他人来到这里,这些指令不再起作用.有关最近的说明,请访问http://nginx.org/en/docs/http/websocket.html,或参阅下面的Harlan T Wood的回答. (2认同)

Har*_*ood 33

这对我有用:

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";
}
Run Code Online (Sandbox Code Playgroud)

- 借鉴:https://github.com/nicokaiser/nginx-websocket-proxy/blob/df67cd92f71bfcb513b343beaa89cb33ab09fb05/simple-wss.conf

  • 我无法让TeamCity的Web套接字在我的反向代理之后工作.你的`#WebSocket支持'剪断了它为我做了.我以前试图转发400端口,但是wss工作超过443. FYI未来的读者:) (3认同)
  • 我最喜欢这个答案,因为很多人(比如你自己)都使用 / 来表示 websocket 和常规 HTTP2。 (2认同)

小智 16

for .net core 2.0 Nginx with 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;
}
Run Code Online (Sandbox Code Playgroud)

这对我有用


小智 7

对我来说,它归结为proxy_pass位置设置.需要更改http://nodeserverto https://nodeserver,并在节点服务器端设置有效的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 /horizon {
                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;
            }
}
Run Code Online (Sandbox Code Playgroud)


bti*_*nay 5

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;
    }
}
Run Code Online (Sandbox Code Playgroud)


joh*_*ith 5

使用 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;

    }
}
Run Code Online (Sandbox Code Playgroud)

  • 2022年这对我帮助很大。在我添加读取超时之前,WSS/WS 没有任何作用。 (3认同)