Frage Konfigurieren von Apache2 zum Proxy von WebSocket?


Das WebSocket-Protokoll ist eine Erweiterung des HTTP-Protokolls. Das Proxy-Modul von Apache2 scheint jedoch nichts davon zu wissen und verwirft wichtige Header, wodurch der Anruf in einen Standard-HTTP-Anruf umgewandelt wird.

Gibt es eine Möglichkeit, Apache2 dazu zu bringen, (1) WebSocket zu verstehen oder (2) einfach blindlings weiterzugeben, was auch immer es bekommt?


40
2017-07-13 22:28


Ursprung




Antworten:


Es gibt jetzt ein Modul in der Apache-Trunk namens mod_proxy_wstunnel, das mod_proxy (ProxyPass / ProxyPassReverse) ermöglicht, um WebSocket-Verkehr zu passieren. Jemand hat einen Blogbeitrag über geschrieben Portierung von mod_proxy_wstunnel auf Apache 2.4 / 2.2 und stellte dafür einen Patch zur Verfügung.

Ich habe Beton gefunden Anleitung zum Einrichten von mod_proxy_wstunnel auf Ubuntu (getestet mit Ubuntu Server 11.10 und Apache 2.2.20) und auf meinem Blog veröffentlicht. Ich habe sie unten kopiert:

# Check apache version (should be 2.2.20 as of writing, if not adjust the next step)
dpkg -s apache2

# Checkout apache source
svn checkout http://svn.apache.org/repos/asf/httpd/httpd/tags/2.2.20/ httpd-2.2.20

# Get patch and apply it
wget http://cafarelli.fr/gentoo/apache-2.2.24-wstunnel.patch
cd httpd-2.2.20
patch -p1 < ../apache-2.2.24-wstunnel.patch

# Build Apache 
svn co http://svn.apache.org/repos/asf/apr/apr/branches/1.4.x srclib/apr
svn co http://svn.apache.org/repos/asf/apr/apr-util/branches/1.3.x srclib/apr-util
./buildconf
./configure --enable-proxy=shared --enable-proxy_wstunnel=shared
make

# Copy the module and recompiled mod_proxy (for new symbols) to the ubuntu apache installation and update the permissions to match the other modules
sudo cp modules/proxy/.libs/mod_proxy{_wstunnel,}.so /usr/lib/apache2/modules/
sudo chmod 644 /usr/lib/apache2/modules/mod_proxy{_wstunnel,}.so
echo -e "# Depends: proxy\nLoadModule proxy_wstunnel_module /usr/lib/apache2/modules/mod_proxy_wstunnel.so" | sudo tee -a /etc/apache2/mods-available/proxy_wstunnel.load

# Enable the module (also make any configuration changes you need)
sudo a2enmod proxy_wstunnel
sudo service apache2 restart

23
2018-06-08 18:57



Als ich deinem Führer folgte, gab es einen Schritt, den du nicht hattest. Nach dem Apr-Check-out musste ich laufen ./buildconfig um die Konfigurationsdatei zu erstellen. Und es gab ein paar Abhängigkeiten, die es mir zu installieren gab. - notbad.jpeg
funktioniert das mit Glassfish 4 über wss: (SSL) - Archimedes Trajano
@ notbad.jpeg: Du meinst wohl ./buildconf (nicht ./buildconfig) :-) - Erik Forsberg
Nur mein Feedback ... das installierte und geladene in Apache 2.2.22-1ubuntu1.10 von Ubuntu 12.04, aber am Ende funktionierte es nicht für mich. Der Proxy löschte den "Upgrade" -Header (der Quellcode sagt "RFC2616 13.5.1 sagt, wir sollten diese Header entfernen"), was ein Header ist, den der Server erwartet, nicht nur einen Hop, also hat es nicht für mich funktioniert, und ich habe es stattdessen mit einer iptables-DNAT-Regel ersetzt. - Peter


Es gibt nichts zu zeigen Apache httpd wird sie in absehbarer Zeit unterstützen.

Wenn Sie Websockets durch Apache laufen müssen, versuchen Sie es mod_pywebsocket. Ich habe es versucht, und es funktioniert.

Hier sind ein paar Alternativen, die ich bevorzuge:


11
2017-07-23 18:01





Mit einer Kombination aus dem Trennungs-Plugin und etwas extra Code ist das jetzt möglich:

http://blog.alex.org.uk/2012/02/16/using-apache-websocket-to-proxy-tcp-connection/ 


6
2018-03-23 14:51





Bitte werfen Sie einen Blick auf http://github.com/disconnect/apache-websocket

Das Apache-Websocket-Modul ist ein Apache 2.x-Servermodul, mit dem Anfragen mithilfe des WebSocket-Protokolls von einem Apache 2.x-Server verarbeitet werden können.


3
2017-10-21 20:57



Ich habe mir das obige GitHub-Projekt angesehen. Es handelt nicht als Proxy. Zitat The module consists of a plugin architecture ... - guettli


Diese Ergänzung zu @ Andrew Moss'beantworten, wie man den VirtualHost mit socket.io 1.0 arbeiten! Zögern Sie nicht, den Teil über CentOS zu überspringen!


Wenn Sie auf CentOS 6 stecken bleiben, gehen Sie folgendermaßen vor:

  1. Laden Sie die zurückportierte Quelle für die mod_proxy_wstunnel Modul Hier (entweder den Gist klonen oder die Dateien einzeln herunterladen)
  2. Installiere alles, was du bauen musst: yum install make gcc httpd-devel
  3. Richten Sie ein ein RPM Build-Umgebung (im Grunde ein unprivilegierter Benutzer und einige Verzeichnisse)
  4. Kopiere das .c-Datei in die SOURCES Unterordner der Umgebung und der .spec-Datei in die SPECS Unterordner.
  5. Lauf rpmbuild -ba mod_proxy_wstunnel.spec
  6. Das Paket ist jetzt in der SRPMS Unterordner
  7. Installieren Sie das Paket: rpm -i /path/to/package.rpm
  8. Profitieren

Dadurch wird auch das Modul automatisch in Apache geladen, sodass Sie es nur mit starten müssen service httpd restart.


Einrichten eines VirtualHost um den Socket.io-Server und das Client-Skript (das standardmäßig unter http://your.server/socket.io/socket.io.js) ist auf Apache 2.2 etwas komplizierter, weil a Fehler in der mod_proxy Modul:

Angesichts der folgenden Rewrite-Regel:

RewriteRule    ^/ws(.*)$  ws://localhost:9000/ws  [P]

mod_rewrite behandelt dies als Dateipfad, so dass das Zugriffsprotokoll Folgendes anzeigt:

[26/Sep/2013:09:46:07 -0400] "GET /ws://localhost:9000/ws HTTP/1.1" 400 317

Also, du kann das nicht benutzen ws-Protokoll in einer Rewrite-Regel, denn das wird intern zu einer HTTP-GET-Anfrage.

Es gibt jedoch eine Problemumgehung:

<VirtualHost *:80>
        ServerName your.server

        # Proxy socket.io Websocket
        RewriteEngine On

        # socket.io 1.0+ starts all connections with an HTTP polling request
        RewriteCond %{QUERY_STRING} transport=polling       [NC]
        RewriteRule /(.*)           http://localhost:8081/$1 [P]

        ProxyRequests Off

        # Explicitly send the request for the client-script to HTTP:
        ProxyPass /socket.io/socket.io.js http://localhost:8081/socket.io/socket.io.js
        ProxyPassReverse /socket.io/socket.io.js http://localhost:8081/socket.io/socket.io.js

        # Anything else goes to the WebSocket protocol:
        ProxyPass /socket.io/ ws://localhost:8081/socket.io/
        ProxyPassReverse /socket.io/ ws://localhost:8081/socket.io/

        # Any additional stuff (the actual site) comes here
        ProxyPass / http://localhost:8081/
        ProxyPassReverse / http://localhost:8081/
</VirtualHost>

Dies stellt sicher, dass alles gesendet wird /socket.io geht zu dem ws://-protocol, mit Ausnahme der Anforderung für Long-Polling (was ein Fallback-Mechanismus ist, wenn WebSockets nicht verfügbar sind) und der Anforderung für die Client-Bibliothek.


1
2018-05-03 13:42