WebSockets i Apache proxy: jak skonfigurować Mod proxy wstunnel?

Mam:

  1. Apache (v2.4) na porcie 80 mojego serwera dla www.domain1.com, z mod_proxy oraz mod_proxy_wstunnel enabled

  2. node.js + socket.io na porcie 3001 tego samego serwera.

Dostęp do www.domain2.com (z portem 80) przekierowuje na 2. dzięki opisanej tu metodzie. Ustawiłem to w konfiguracji Apache:

<VirtualHost *:80>
    ServerName www.domain2.com
    ProxyPass / http://localhost:3001/
    ProxyPassReverse / http://localhost:3001/
    ProxyPass / ws://localhost:3001/
    ProxyPassReverse / ws://localhost:3001/
</VirtualHost>

Działa na wszystko, z wyjątkiem części websocket : ws://... nie są przekazywane tak, jak powinny przez pełnomocnika.

Kiedy wchodzę na stronę na www.domain2.com, mam:

Impossible to connect ws://www.domain2.com/socket.io/?EIO=3&transport=websocket&sid=n30rqg9AEqZIk5c9AABN.

Pytanie: Jak zrobić Apache proxy również WebSockets?

Author: Community, 2014-12-17

12 answers

W końcu udało mi się to zrobić, dzięki temu tematowi.

TODO:

1) mieć zainstalowany Apache 2.4 (nie działa z 2.2), i zrobić:

a2enmod proxy
a2enmod proxy_http
a2enmod proxy_wstunnel

2) Czy nodejs działa na porcie 3001

3) Zrób to w Apache config

<VirtualHost *:80>
  ServerName www.domain2.com

  RewriteEngine On
  RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
  RewriteCond %{QUERY_STRING} transport=websocket    [NC]
  RewriteRule /(.*)           ws://localhost:3001/$1 [P,L]

  ProxyPass / http://localhost:3001/
  ProxyPassReverse / http://localhost:3001/
</VirtualHost>

Uwaga: Jeśli masz więcej niż jedną usługę na tym samym serwerze, która używa websockets, możesz zrobić to , aby je rozdzielić.

 173
Author: Basj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-06 15:27:35

Zamiast filtrowania według adresu URL, możesz również filtrować według nagłówka HTTP. Ta konfiguracja będzie działać dla wszystkich aplikacji internetowych, które używają websockets, również jeśli nie są one używane socket.io:

<VirtualHost *:80>
  ServerName www.domain2.com

  RewriteEngine On
  RewriteCond %{HTTP:Upgrade} =websocket [NC]
  RewriteRule /(.*)           ws://localhost:3001/$1 [P,L]
  RewriteCond %{HTTP:Upgrade} !=websocket [NC]
  RewriteRule /(.*)           http://localhost:3001/$1 [P,L]

  ProxyPassReverse / http://localhost:3001/
</VirtualHost>
 106
Author: cdauth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-28 08:49:09

Od Socket.IO 1.0 (Maj 2014), wszystkie połączenia zaczynają się od żądania ankiety HTTP (więcej informacji tutaj ). Oznacza to, że oprócz przekazywania ruchu WebSocket, musisz przesłać wszelkie żądania HTTP transport=polling.

Poniższe rozwiązanie powinno poprawnie przekierowywać cały ruch gniazd, bez przekierowywania żadnego innego ruchu.

  1. Zapraszamy do zapoznania się z naszą ofertą]}
    sudo a2enmod proxy rewrite proxy_http proxy_wstunnel
    
  2. Użyj tych ustawień w swoim *.plik conf (np. /etc/apache2/sites-available/mysite.com.conf). I ' ve included komentarze wyjaśniające każdy utwór:

    <VirtualHost *:80>
        ServerName www.mydomain.com
    
        # Enable the rewrite engine
        # Requires: sudo a2enmod proxy rewrite proxy_http proxy_wstunnel
        # In the rules/conds, [NC] means case-insensitve, [P] means proxy
        RewriteEngine On
    
        # socket.io 1.0+ starts all connections with an HTTP polling request
        RewriteCond %{QUERY_STRING} transport=polling       [NC]
        RewriteRule /(.*)           http://localhost:3001/$1 [P]
    
        # When socket.io wants to initiate a WebSocket connection, it sends an
        # "upgrade: websocket" request that should be transferred to ws://
        RewriteCond %{HTTP:Upgrade} websocket               [NC]
        RewriteRule /(.*)           ws://localhost:3001/$1  [P]
    
        # OPTIONAL: Route all HTTP traffic at /node to port 3001
        ProxyRequests Off
        ProxyPass           /node   http://localhost:3001
        ProxyPassReverse    /node   http://localhost:3001
    </VirtualHost>
    
  3. Dodałem dodatkową sekcję trasowania /node ruchu, która jest mi przydatna, zobacz tutaj aby uzyskać więcej informacji.

 20
Author: Erik Koopmans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:31

May be will be useful. Tylko wszystkie zapytania wysyłane przez ws do węzła

<VirtualHost *:80>
  ServerName www.domain2.com

  <Location "/">
    ProxyPass "ws://localhost:3001/"
  </Location>
</VirtualHost>
 18
Author: Sergey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-28 07:53:36

U mnie działa po dodaniu tylko jednej linii w httpd.conf jak poniżej(pogrubiona linia).


<VirtualHost *:80>
    ServerName: xxxxx

    #ProxyPassReverse is not needed
    ProxyPass /log4j ws://localhost:4711/logs
<VirtualHost *:80>

Wersja Apache to 2.4.6 na CentOS.

 10
Author: Leon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-25 02:32:45

Z Pomocą tych odpowiedzi w końcu dostałem odwrócone proxy dla Node-RED działającego na Raspberry Pi z Ubuntu Mate i działa Apache2, używając tej konfiguracji witryny:

<VirtualHost *:80>
    ServerName nodered.domain.com
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule /(.*)           ws://localhost:1880/$1 [P,L]
    RewriteCond %{HTTP:Upgrade} !=websocket [NC]
    RewriteRule /(.*)           http://localhost:1880/$1 [P,L]
</VirtualHost>

Musiałem też włączyć takie moduły:

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
 8
Author: Otto Paulsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-20 07:12:47

Wykonałem następujące czynności dla aplikacji spring uruchamiającej zawartość statyczną, rest I websocket.

Apache jest używany jako serwer Proxy i punkt końcowy SSL dla następujących Uri:
  • / app → static content
  • / api → REST API
  • / api / ws → websocket

Konfiguracja Apache

<VirtualHost *:80>
    ServerName xxx.xxx.xxx    

    ProxyRequests Off
    ProxyVia Off
    ProxyPreserveHost On

    <Proxy *>
         Require all granted
    </Proxy>

    RewriteEngine On

    # websocket 
    RewriteCond %{HTTP:Upgrade}         =websocket                      [NC]
    RewriteRule ^/api/ws/(.*)           ws://localhost:8080/api/ws/$1   [P,L]

    # rest
    ProxyPass /api http://localhost:8080/api
    ProxyPassReverse /api http://localhost:8080/api

    # static content    
    ProxyPass /app http://localhost:8080/app
    ProxyPassReverse /app http://localhost:8080/app 
</VirtualHost>

Używam tego samego vhost config do konfiguracji SSL, nie ma potrzeby zmieniać niczego związanego z proxy.

Konfiguracja sprężyny

server.use-forward-headers: true
 6
Author: Ortwin Angermeier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 21:47:19

Moja konfiguracja:

  • Apache 2.4.10 (uruchamiany z Debiana)
  • węzeł.js (Wersja 4.1.1) aplikacja działająca na porcie 3000, która akceptuje WebSockets w path /api/ws

Jak wspomniano powyżej przez @ Basj, upewnij się, że proxy a2enmod i ws_tunnel są włączone.

To jest zrzut ekranu z pliku konfiguracyjnego Apache, który rozwiązał mój problem:

Apache config

Odpowiednia część jako tekst:

<VirtualHost *:80>
  ServerName *******
  ServerAlias *******
  ProxyPass / http://localhost:3000/
  ProxyPassReverse / http://localhost:3000/

  <Location "/api/ws">
      ProxyPass "ws://localhost:3000/api/ws"
  </Location>
</VirtualHost>
Mam nadzieję, że to pomoże.
 6
Author: Anwaarullah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-21 11:09:35

Oprócz głównej odpowiedzi: jeśli masz więcej niż jedną usługę na tym samym serwerze, która używa websockets, możesz chcieć to zrobić, aby je rozdzielić, używając niestandardowej ścieżki (*):

Serwer węzła:

var io = require('socket.io')({ path: '/ws_website1'}).listen(server);

Klient HTML:

<script src="/ws_website1/socket.io.js"></script>
...
<script>
var socket = io('', { path: '/ws_website1' });
...

Apache config:

RewriteEngine On

RewriteRule ^/website1(.*)$ http://localhost:3001$1 [P,L]

RewriteCond %{REQUEST_URI}  ^/ws_website1 [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule ^(.*)$ ws://localhost:3001$1 [P,L]

RewriteCond %{REQUEST_URI}  ^/ws_website1 [NC]
RewriteRule ^(.*)$ http://localhost:3001$1 [P,L]

( * ) Uwaga: użycie domyślnego RewriteCond %{REQUEST_URI} ^/socket.io nie byłoby specyficzne dla strony internetowej, a żądania websockets byłyby mieszane między różnymi stronami internetowymi!

 2
Author: Basj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-06 15:26:30

User this link for perfact solution for ws https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html

Musisz wykonać poniższy krok..

Idź do /etc/apache2/mods-available

Krok...1

Włącz mode proxy_wstunnel.load używając poniższego polecenia

$a2enmod proxy_wstunnel.load

Krok...2

Idź do /etc/apache2/sites-available

I dodaj poniższy wiersz w swoim .plik conf wewnątrz wirtualnego hosta

ProxyPass "/ws2/"  "ws://localhost:8080/"

ProxyPass "/wss2/" "wss://localhost:8080/"

Uwaga: 8080 oznacza, że Twój tomcat uruchamia port, ponieważ chcemy połączyć się ws gdzie nasz Plik War umieszczony w tomcat i tomcat serwuje apache dla ws. dziękuję

Moja Konfiguracja

ws://localhost/ws2/ALLCAD-Unifiedcommunication-1.0/chatserver?userid=4 =Connected
 2
Author: Arvind Madhukar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-08 01:45:41

Do transportu "ankietowego".

Strona Apacza:

<VirtualHost *:80>
    ServerName mysite.com
    DocumentRoot /my/path


    ProxyRequests Off

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    ProxyPass /my-connect-3001 http://127.0.0.1:3001/socket.io
    ProxyPassReverse /my-connect-3001 http://127.0.0.1:3001/socket.io   
</VirtualHost>

Strona klienta:

var my_socket = new io.Manager(null, {
    host: 'mysite.com',
    path: '/my-connect-3001'
    transports: ['polling'],
}).socket('/');
 1
Author: sNICkerssss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-13 07:50:27

TODO:

  1. Mieć zainstalowany Apache 2.4 (nie działa z 2.2), a2enmod proxy i a2enmod proxy_wstunnel.load

  2. Zrób to w Apache config
    po prostu dodaj dwie linie w pliku, gdzie 8080 jest portem uruchomionym przez tomcat

    <VirtualHost *:80>
    ProxyPass "/ws2/" "ws://localhost:8080/" 
    ProxyPass "/wss2/" "wss://localhost:8080/"
    
    </VirtualHost *:80>
    
 1
Author: Arvind Madhukar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-30 13:50:14