Apache2 als Proxy für WebSocket konfigurieren?

40

Das WebSocket-Protokoll ist eine Erweiterung des HTTP-Protokolls. Das Proxy-Modul von Apache2 scheint jedoch nichts davon zu wissen und wirft wichtige Header weg und wandelt den Aufruf in einen Standard-HTTP-Aufruf um.

Gibt es eine Möglichkeit, Apache2 zu veranlassen, entweder (1) WebSocket zu verstehen oder (2) einfach blind weiterzugeben, was immer es bekommt?

Blixt
quelle

Antworten:

23

Es gibt jetzt ein Modul im Apache-Trunk mit dem Namen mod_proxy_wstunnel, mit dem mod_proxy (ProxyPass / ProxyPassReverse) den WebSocket-Verkehr passieren kann. Jemand schrieb einen Blog-Beitrag über die Back-Portierung von mod_proxy_wstunnel auf Apache 2.4 / 2.2 und stellte dafür einen Patch zur Verfügung.

Ich fand konkrete Anweisungen zum Einrichten von mod_proxy_wstunnel unter Ubuntu (getestet mit Ubuntu Server 11.10 und Apache 2.2.20) und stellte sie auf meinem Blog zur Verfügung. 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
Andrew Moss
quelle
2
Als ich Ihrem Führer folgte, gab es einen Schritt, den Sie nicht hatten. Nach dem Auschecken musste ich ausführen ./buildconfig, um die Konfigurationsdatei zu erstellen. Und es gab ein paar Abhängigkeiten, die ich installieren sollte.
notbad.jpeg
geht das mit Glassfish 4 über wss: (SSL)
Archimedes Trajano
1
@ notbad.jpeg: Du meinst wahrscheinlich ./buildconf (nicht ./buildconfig) :-)
Erik Forsberg
1
Nur mein Feedback ... dies wurde in Apache 2.2.22-1ubuntu1.10 von Ubuntu 12.04 installiert und geladen, aber es funktionierte letztendlich nicht für mich. Der Proxy hat den "Upgrade" -Header entfernt (der Quellcode sagt "RFC2616 13.5.1 sagt, wir sollten diese Header entfernen"). Dies ist ein Header, den der Server erwartet, nicht nur einen Hop, also hat er bei mir nicht funktioniert. und ich habe es stattdessen durch eine iptables-DNAT-Regel ersetzt.
Peter
11

Es gibt keinen Hinweis darauf , Apache wird sie in nächster Zeit unterstützen.

Wenn Sie Websockets über Apache ausführen müssen, versuchen Sie es mit mod_pywebsocket . Ich habe es versucht und es funktioniert.

Hier sind ein paar Alternativen, die ich bevorzuge:

h0tw1r3
quelle
3

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

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

Marat Denenberg
quelle
Ich habe mir das obige Github-Projekt angesehen. Es fungiert nicht als Proxy. quoteThe module consists of a plugin architecture ...
guettli
1

Dieses Add ist die Antwort von @Andrew Moss , wie man das richtig konfiguriert VirtualHost, um mit socket.io 1.0 zu arbeiten! Fühlen Sie sich frei, den Teil über CentOS zu überspringen!


Wenn Sie auf CentOS 6 nicht weiterkommen, gehen Sie wie folgt vor:

  1. Laden Sie die zurückportiert Quelle für das mod_proxy_wstunnelModul hier (entweder Klon der Gist oder laden Sie die Dateien einzeln)
  2. Installieren Sie alles, was Sie zum Erstellen benötigen: yum install make gcc httpd-devel
  3. Einrichten einer RPM-Build-Umgebung (im Grunde genommen ein nicht privilegierter Benutzer und einige Verzeichnisse)
  4. Kopieren Sie die .c-Datei in den SOURCESUnterordner der Umgebung und die .spec-Datei in den SPECSUnterordner.
  5. Lauf rpmbuild -ba mod_proxy_wstunnel.spec
  6. Das Paket befindet sich jetzt im SRPMSUnterordner
  7. Installieren Sie das Paket: rpm -i /path/to/package.rpm
  8. Profitieren

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


Einrichten eines VirtualHosttatsächlich dient der Socket.io Server- und Client-Skript (standardmäßig unter ist http://your.server/socket.io/socket.io.js) ist ein wenig komplizierter auf Apache 2.2, wegen eines Fehlers in dem mod_proxyModul :

Unter Berücksichtigung der folgenden Umschreiberegel:

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

mod_rewrite Behandelt dies als Dateipfad, sodass das Zugriffsprotokoll Folgendes anzeigt:

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

Sie können das ws-Protokoll also nicht in einer Rewrite-Regel verwenden , da dies intern zu einer HTTP-GET-Anforderung wird.

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, was an gesendet wird, /socket.ioan das ws://-Protokoll gesendet wird, mit Ausnahme der Anforderung für langes Polling (was ein Fallback-Mechanismus ist, wenn WebSockets nicht verfügbar sind) und der Anforderung für die Client-Bibliothek.

Lukas Knuth
quelle