NGINX는 프록시 웹 소켓을 역전시키고 SSL을 활성화합니까 (wss : //)?


136

나는 스스로 길을 잃어 버렸고 NGINX를 스스로 만들지 않았지만 추가 계층을 사용하지 않고도 안전한 웹 소켓을 사용할 수 있기를 원합니다.

웹 소켓 서버 자체에서 SSL을 활성화하고 싶지 않지만 대신 NGINX를 사용하여 SSL 레이어를 전체에 추가하고 싶습니다.

거기에있는 모든 웹 페이지는 할 수 없다고 말하지만 할 수는 있습니다! 누구 (나 자신) 덕분에 나에게 방법을 보여줄 수 있습니다!

답변:


185

nginx는 이제 1.3.13 릴리스에서 Websocket을 지원합니다. 사용 예 :

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 프록시 문서를 확인할 수도 있습니다.


상기 표현 된 동일한 제한 문제를 가진다)
3rdEden

5
@ 3rdEden : 시간 초과 문제, proxy_read_timeout작동에 대한 답변을 편집했습니다.
Steve

2
이 구성을 어디에 배치하고 backend_host는 무엇입니까?
Aysennoussi

3
@Sekai : location지시어는 하나 server이상의 location지시어 안에 있습니다 ( location docs 참조 ). backend_host는 프록시 할 서버 그룹 또는 하나의 그룹입니다 upstream( 업스트림 문서 참조 ).
Radko Dinev

1
이 시간 초과 문제는 어떻습니까? 우리는 그것을 피하기 위해 매우 큰 숫자로 설정해야합니까? 더 우아한 솔루션이 없습니까?
Mohammed Noureldin

54

용감한 Ops 프로그래머 그룹이 새로운 nginx_tcp_proxy_module을 사용하는 브랜드로 상황을 해결 했으므로 걱정하지 마십시오.

2012 년 8 월에 작성되었으므로 미래에 온다면 숙제를해야합니다.

전제 조건

CentOS를 사용한다고 가정합니다.

  • NGINX의 현재 인스턴스를 제거하십시오 (dev 서버를 사용하는 것이 가장 좋습니다)
  • 가능하면 이전 NGINX 구성 파일을 저장하여 다시 사용할 수 있도록하십시오 ( init.d/nginx스크립트 포함 )
  • yum install pcre pcre-devel openssl openssl-devel NGINX 빌드에 필요한 다른 라이브러리들
  • 가져 오기 nginx_tcp_proxy_module을 여기 GitHub의에서 https://github.com/yaoweibin/nginx_tcp_proxy_module 당신이 그것을 배치 곳 (make가 확인이 압축되지 않습니다) 폴더를 기억

새로운 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 {}.

아래 구성 예는 단일 업스트림 웹 소켓 서버와 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;
    }
}

5
이것은 매우 도움이되었지만 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;
jbg

2
공유해 주셔서 감사합니다! 나중에 비슷한 문제가 있다는 것을 깨달았고 우연히 yaoweibin 자신도 문제 # 28에 대한 귀하의 의견에 대한 링크와 함께 내 GitHub 문제에 응답했습니다. 작은 세상 ...
crockpotveggies 1

1
브라우저가 인증 된 후에 만 ​​동일한 http 포트에서 웹 소켓을 제공하고 싶었습니다. 동일한 포트에서 웹 소켓을 처리 할 수없는 것 같습니다. 사람들은 이것을 어떻게 처리합니까?
uroc

1
들어오는 프로토콜을 감지하려면 소프트웨어를 약간 수정해야합니다. 웹 소켓은 실제로 HTTP 핸드 셰이크 (TCP보다 높은 소프트웨어 수준)로 시작하므로 TCP 및 HTTP 트래픽을 모두 처리하도록 앱을 조정해야합니다. 아직이 방법을 추천 할 수 없습니다.
crockpotveggies

2
2018 년의 다른 사람들이 여기에 오면이 지시문은 더 이상 작동하지 않습니다. 최신 지침을 보려면 nginx.org/en/docs/http/websocket.html방문 하거나 아래 Harlan T Wood의 답변을 참조하십시오.
GaryO

37

이것은 나를 위해 일했다 :

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


3
리버스 프록시 뒤에서 TeamCity의 웹 소켓을 작동시키는 데 문제가있었습니다. 당신의 # WebSocket support도둑은 나를 위해 그것을했다. 이전에 포트 400을 전달하려고했지만 wss는 443 개 이상 작동합니다. 미래의 독자 :)
Mario Tacke

해결책을 찾았습니까? 나는 또한 비슷한 문제에 직면했다 이후 stackoverflow.com/q/53411060/7713811
Nɪsʜᴀɴᴛʜ

많은 사람들 (자신과 같은)이 웹 소켓과 일반 HTTP2 모두에 /를 사용함에 따라이 답변이 가장 좋습니다.
mikemaccana

@Anyone 호출하는 Javascript는 무엇입니까?
앤드류 심슨

17

SSL을 사용하는 .net 코어 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;
}

이것은 나를 위해 일했다


C # 코드는 무엇입니까? 현재 windows / iis의 경우 _server = new WebSocketServer ( "wss : //0.0.0.0 : 8200 / MessageRelayer") {Certificate = new X509Certificate2 (PfxFileName, SslPassword), RestartAfterListenError = true};
앤드류 심슨

SignalR
Altair CA

이것은 나를 위해 일한 유일한 솔루션이었습니다. 감사!
m-ketan

8

나를 위해, 그것은 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;
            }
}

시도 localtion /horizon했지만 작동하지 않습니다. 만 localtion /또는 location /websockify작동합니다. 이유를 모릅니다 ...
njuguoyi

6

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

1
최신 버전의 NGINX도 시간 초과 문제를 해결합니까?
crockpotveggies

2

nginx / 1.14.0 사용

포트 8097에서 실행되는 웹 소켓 서버가 있고 사용자가 포트 8098의 wss에 연결하면 nginx는 내용을 해독하고 웹 소켓 서버로 전달합니다.

그래서 나는이 구성 파일을 가지고 있습니다 (제 경우에는 /etc/nginx/conf.d/default.conf)

server {
    listen   8098;
        ssl on;
        ssl_certificate      /etc/ssl/certs/combined.pem;
        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;

    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.