it-swarm.com.de

WebSockets und Apache-Proxy: Wie konfiguriere ich mod_proxy_wstunnel?

Ich habe :

  1. Apache (v2.4) an Port 80 meines Servers für www.domain1.com, wobei mod_proxy und mod_proxy_wstunnel aktiviert sind

  2. node.js + socket.io an Port 3001 desselben Servers.

Der Zugriff auf www.domain2.com (mit Port 80) führt zu 2. dank der hier beschriebenen Methode . Ich habe dies in der Apache-Konfiguration eingestellt:

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

Es funktioniert für alles, außer dem Websocket-Teil: ws://... wird nicht so übertragen, wie es vom Proxy sein sollte.

Wenn ich auf www.domain2.com auf die Seite zugreife, habe ich:

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

Frage: Wie kann Apache auch für die WebSockets verwendet werden? 

65
Basj

Ich habe es endlich geschafft, dank diesem Thema .

MACHEN:

1) Installieren Sie Apache 2.4 (funktioniert nicht mit 2.2), und führen Sie Folgendes aus:

a2enmod proxy
a2enmod proxy_http
a2enmod proxy_wstunnel

2) Lassen Sie nodejs auf Port 3001 laufen

3) Tun Sie dies in der Apache-Konfiguration

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

Hinweis: Wenn Sie mehr als einen Dienst auf demselben Server haben, der Websockets verwendet, möchten Sie tun Sie dies , um sie zu trennen.

112
Basj

Anstatt nach URL zu filtern, können Sie auch nach HTTP-Header filtern. Diese Konfiguration funktioniert für alle Webanwendungen, die Websockets verwenden, auch wenn sie socket.io nicht verwenden:

<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>
70
cdauth

Möglicherweise wird es nützlich sein. Alle Abfragen werden nur über ws an den Knoten gesendet

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

  <Location "/">
    ProxyPass "ws://localhost:3001/"
  </Location>
</VirtualHost>
15
Sergey

Ab Socket.IO 1.0 (Mai 2014) beginnen alle Verbindungen mit einer HTTP-Polling-Anfrage (mehr Infos hier ). Das bedeutet, dass Sie neben der Weiterleitung von WebSocket-Datenverkehr transport=polling-HTTP-Anforderungen weiterleiten müssen.

Die Lösung unten sollte den gesamten Socket-Verkehr korrekt umleiten, ohne anderen Verkehr umzuleiten.

  1. Aktivieren Sie die folgenden Apache2-Mods:

    Sudo a2enmod proxy rewrite proxy_http proxy_wstunnel
    
  2. Verwenden Sie diese Einstellungen in Ihrer * .conf-Datei (z. B. /etc/Apache2/sites-available/mysite.com.conf). Ich habe Kommentare hinzugefügt, um jedes Stück zu erklären:

    <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. Ich habe einen zusätzlichen Abschnitt für das Weiterleiten von /node-Verkehr hinzugefügt, den ich für praktisch halte, siehe hier für weitere Informationen.

9
Erik Koopmans

Mit Hilfe dieser Antworten bekam ich schließlich den Reverse Proxy für Node-RED, der auf einem Raspberry Pi mit Ubuntu Mate und Apache2 ausgeführt wurde und diese Apache2-Site-Konfiguration verwendete:

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

Ich musste auch Module wie folgt aktivieren:

Sudo a2enmod proxy
Sudo a2enmod proxy_http
Sudo a2enmod proxy_wstunnel
6
Otto Paulsen

Mein Setup:

Apache 2.4.10 (läuft unter Debian) NodeJS (Version 4.1.1) App, die an Port 3000 ausgeführt wird und WebSockets unter Pfad/api/ws akzeptiert

Stellen Sie sicher, dass a2enmod-Proxy und ws_tunnel aktiviert sind.

Dies ist ein Screengrab der Apache-Conf-Datei, die mein Problem gelöst hat:

 enter image description here

Hoffentlich hilft das.

5
Anwaarullah

Folgendes wurde für eine Federanwendung ausgeführt, die statische Inhalte, Ruhe- und Websocket-Inhalte lief.

Der Apache wird als Proxy und SSL-Endpunkt für die folgenden URIs verwendet:

  • / app → statischer Inhalt 
  • / api → REST API
  • / api/ws → websocket

Apache-Konfiguration

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

Ich verwende dieselbe vHost-Konfiguration für die SSL-Konfiguration. Es ist nicht notwendig, irgendetwas in Bezug auf den Proxy zu ändern.

Federkonfiguration

server.use-forward-headers: true
2

Bei mir funktioniert es nach dem Hinzufügen von nur einer Zeile in httpd.conf wie unten (fettgedruckte Zeile).


<VirtualHost *:80>
    ServerName: xxxxx

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

Die Apache-Version ist 2.4.6 unter CentOS. 

2
Leon

Zusätzlich zur Hauptantwort: Wenn Sie mehr als einen -Dienst auf demselben Server haben, der Websockets verwendet, möchten Sie dies möglicherweise mit einem benutzerdefinierten Pfad (*) trennen.

Knotenserver:

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

Client HTML:

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

Apache-Konfiguration:

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]

(*) Hinweis: Die Verwendung des Standardcodes RewriteCond %{REQUEST_URI} ^/socket.io wäre nicht spezifisch für eine Website, und Websocket-Anforderungen würden zwischen verschiedenen Websites gemischt sein!

1
Basj

Für "Polling" -Transport.

Apache Seite:

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

Kundenseite:

var my_socket = new io.Manager(null, {
    Host: 'mysite.com',
    path: '/my-connect-3001'
    transports: ['polling'],
}).socket('/');
0
sNICkerssss

MACHEN:

  1. Apache 2.4 muss installiert sein (funktioniert nicht mit 2.2), a2enmod proxy und a2enmod proxy_wstunnel.load

  2. Tun Sie dies in der Apache-Konfiguration
    Fügen Sie einfach zwei Zeilen in Ihre Datei ein, wobei 8080 Ihr Tomcat-Port ist

    <VirtualHost *:80>
    ProxyPass "/ws2/" "ws://localhost:8080/" 
    ProxyPass "/wss2/" "wss://localhost:8080/"
    
    </VirtualHost *:80>
    
0
Arvind Madhukar

Benutzer dieser Verbindung für perfact-Lösung für ws https://httpd.Apache.org/docs/2.4/mod/mod_proxy_wstunnel.html

Sie müssen nur unten Schritt tun ..

Bekommen zu/etc/Apache2/mods-available

Schritt 1

Aktivieren Sie den Modus proxy_wstunnel.load mit dem folgenden Befehl

$ a2enmod proxy_wstunnel.load

Schritt 2 

Gehe zu/etc/Apache2/sites-available

und fügen Sie in Ihrer .conf-Datei innerhalb des virtuellen Hosts eine Zeile unterhalb der Zeile hinzu

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

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

Hinweis: 8080 bedeutet, dass Ihr Tomcat-Port aktiv ist, weil wir "ws" verbinden möchten, wo unsere in Tomcat und Tomcat gepufferte Kriegsdatei Apache für "ws" ..__

Meine Konfiguration 

ws: //localhost/ws2/ALLCAD-Unifiedcommunication-1.0/chatserver? userid = 4 = Verbunden

0
Arvind Madhukar