NGINX proxy web yuvalarını ters çevirecek VE SSL'yi etkinleştirecek (wss: //)?


136

NGINX'i kendi başıma oluşturmada çok kayboldum ve yeniyim, ancak ek bir katmana sahip olmadan güvenli web soketlerini etkinleştirebilmek istiyorum.

Websocket sunucusunda SSL'yi etkinleştirmek istemiyorum, bunun yerine her şeye bir SSL katmanı eklemek için NGINX kullanmak istiyorum.

Dışarıdaki her web sayfası bunu yapamayacağımı söylüyor, ama yapabileceğimi biliyorum! (Kendim) bana nasıl olduğunu gösterebilecek kişi sayesinde!

Yanıtlar:


185

Sadece nginx'in 1.3.13 sürümünde Websockets'ı desteklediğini belirtmek isterim. Kullanım örneği:

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;

}

Ayrıca nginx değişiklik günlüğünü ve WebSocket proxy oluşturma belgelerini de kontrol edebilirsiniz .


Yukarıda ifade
edilenle

5
@ 3rdEden: Zaman aşımı sorunları için proxy_read_timeoutçalışıyor, yanıtı düzenledim.
Steve Kehlet

2
Bu yapılandırmayı nereye koymalıyım ve backend_host nedir?
Aysennoussi

3
@Sekai: Bir locationyönerge, bir serverveya başka bir locationyönergenin içine yerleştirilir ( konum belgelerine bakın ). backend_hostbir upstream( yukarı akış belgelerine bakın ) - proxy kullanacağınız bir veya bir grup sunucu.
Radko Dinev

1
Bu zaman aşımı sorunu ne olacak? Bundan kaçınmak için gerçekten çok büyük bir sayıya ayarlamalı mıyız? Artık daha zarif bir çözüm yok mu?
Muhammed Nureldin

54

Korkmayın, çünkü cesur bir Operasyon Programcısı grubu durumu yeni nginx_tcp_proxy_module şaplak atan bir markayla çözdü

Ağustos 2012'de yazıldı, bu yüzden gelecekten iseniz ev ödevinizi yapmalısınız.

Ön şartlar

CentOS kullandığınızı varsayar:

  • Mevcut NGINX örneğini kaldırın (bunun için geliştirme sunucusu kullanmanızı öneririz)
  • Mümkünse, eski NGINX yapılandırma dosyalarınızı kaydedin, böylece onları yeniden kullanabilirsiniz ( init.d/nginxbetiğiniz dahil)
  • yum install pcre pcre-devel openssl openssl-devel ve NGINX'i oluşturmak için gerekli diğer kitaplıklar
  • GitHub'dan nginx_tcp_proxy_module dosyasını buradan alın https://github.com/yaoweibin/nginx_tcp_proxy_module ve yerleştirdiğiniz klasörü hatırlayın (sıkıştırılmadığından emin olun)

Yeni NGINX'inizi Oluşturun

Yine, CentOS varsayar:

  • 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 (ihtiyacınız olursa daha fazla modül ekleyebilirsiniz)
  • make
  • make install

İsteğe bağlı:

  • sudo /sbin/chkconfig nginx on

Nginx'i Kurun

Yeniden kullanmak istiyorsanız, önce eski yapılandırma dosyalarınızı kopyalamayı unutmayın.

Önemli:tcp {} conf'inizde en üst düzeyde bir yönerge oluşturmanız gerekecektir . Direktifinizin içinde olmadığından emin olun http {}.

Aşağıdaki örnek yapılandırma, tek bir yukarı akış web soket sunucusunu ve hem SSL hem de SSL olmayan için iki proxy gösterir.

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
Bu oldukça yardımcı oldu, ancak yine de 60 saniyede mola alıyordum. Aşağıdakileri ayarlayarak bunu düzeltmeyi başardım: 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
Bunu paylaştığınız için teşekkürler! Daha sonra benzer problemler yaşadığımı fark ettim ve tesadüfen yaoweibin de GitHub sorunuma 28. Sayı hakkındaki yorumunuza bir bağlantıyla cevap verdi. Small world ...
crockpotveggies

1
Aynı http bağlantı noktasından ve yalnızca tarayıcının kimliği doğrulandıktan sonra web soketlerine hizmet vermek istedim. Görünüşe göre bu aynı bağlantı noktasındaki web yuvalarını işleyemiyor. İnsanlar bununla nasıl başa çıkıyor?
uroc

1
Gelen protokolü tespit etmek için bazı yazılım modifikasyonları gerekecektir. Web soketleri aslında bir HTTP el sıkışması olarak başladığından (TCP'den daha yüksek bir yazılım seviyesi) uygulamanızı hem TCP hem de HTTP trafiğini işleyecek şekilde ayarlamanız gerekir. Bunu henüz yapmanın bir yolunu öneremem.
crockpotveggies

2
2018'den başka insanların buraya gelmesi durumunda, bu direktifler artık çalışmıyor. Son talimatlar için nginx.org/en/docs/http/websocket.html adresine gidin veya aşağıdaki Harlan T Wood'un cevabına bakın.
GaryO

37

Bu benim için çalıştı:

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

- ödünç alınmıştır: https://github.com/nicokaiser/nginx-websocket-proxy/blob/df67cd92f71bfcb513b343beaa89cb33ab09fb05/simple-wss.conf


3
TeamCity'nin web soketlerinin ters proxy'm arkasında çalışmasını sağlamakta sorun yaşadım. Kişisel # WebSocket supportKesik benim için yaptı. Daha önce 400 numaralı bağlantı noktasını iletmeye çalışıyordum, ancak wss 443'ün üzerinde çalışıyor. Bilginize, gelecekteki okuyucular :)
Mario Tacke

Çözümü buldunuz mu? Ben de benzer bir sorun karşı karşıya zorunda yana stackoverflow.com/q/53411060/7713811
Nɪsʜᴀɴᴛʜ

Bu yanıtı en çok beğendim, çünkü birçok kişi (sizin gibi) hem web soketleri hem de normal HTTP2 için / kullanıyor.
mikemaccana

@Herkes çağıran Javascript ne olurdu?
Andrew Simpson

17

.net core 2.0 Nginx için SSL ile

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

Bu benim için çalıştı


c # kodu nedir. Şu anda Windows / iis _server = new WebSocketServer ("wss: //0.0.0.0: 8200 / MessageRelayer") {Certificate = new X509Certificate2 (PfxFileName, SslPassword), RestartAfterListenError = true};
Andrew Simpson

SignalR kullanıyorum
Altair CA

Benim için işe yarayan tek çözüm buydu. Teşekkürler!
m-ketan

8

Benim için proxy_passkonum ayarına geldi . HTTPS protokolünü kullanmaya geçmem ve nesnelerin düğüm sunucusu tarafında geçerli bir SSL sertifikasına sahip olmam gerekiyordu. Bu şekilde, harici bir düğüm sunucusu sunduğumda, yalnızca IP'yi değiştirmem gerekir ve diğer her şey aynı yapılandırma olarak kalır.

Umarım bu yol boyunca birine yardımcı olur ... Ben her zaman soruna bakıyordum ... ah ...

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

Denedim localtion /horizonama çalışmıyor. Sadece localtion /ya da location /websockifyçalışıyor. Neden bilmiyorum ...
njuguoyi

6

Pankaj Malhotra tarafından yazılan güzel, kısa ve öz bir makale bunun NGINX ile nasıl yapılacağını tartışıyor ve buradan ulaşılabilir .

Temel NGINX yapılandırması aşağıda yeniden üretilmiştir:

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'in modern sürümleri de zaman aşımı sorunlarını ele alıyor mu?
crockpotveggies

2

Nginx / 1.14.0 kullanma

8097 numaralı bağlantı noktasında çalışan bir web soket sunucum var ve kullanıcılar 8098 numaralı bağlantı noktasından wss'e bağlanıyor, nginx yalnızca içeriğin şifresini çözüyor ve websocket sunucusuna iletiyor

Bu yüzden bu yapılandırma dosyasına sahibim (benim durumumda /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;

    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.