Configuration d'Apache2 pour proxy WebSocket?

40

Le protocole WebSocket est une extension du protocole HTTP. Cependant, le module proxy d'Apache2 ne semble pas le savoir et jette les en-têtes cruciaux, convertissant l'appel en un appel HTTP standard.

Existe-t-il un moyen de faire en sorte qu'Apache2 (1) comprenne WebSocket ou (2) transmette tout simplement aveuglément ce qu'il obtient?

Blixt
la source

Réponses:

23

Il existe maintenant un module dans le tronc Apache appelé mod_proxy_wstunnel qui permet à mod_proxy (ProxyPass / ProxyPassReverse) de transiter par le trafic WebSocket. Quelqu'un a écrit un article sur le portage de mod_proxy_wstunnel vers Apache 2.4 / 2.2 et a fourni un correctif pour le faire.

J'ai compris des instructions concrètes pour configurer mod_proxy_wstunnel sur Ubuntu (testé avec Ubuntu Server 11.10 et Apache 2.2.20) et les ai postées sur mon blog. Je les ai copiés ci-dessous:

# 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
la source
2
Quand j'ai suivi votre guide, il y avait une étape que vous n'aviez pas. Après avoir effectué les vérifications après, je devais exécuter ./buildconfigpour créer le fichier de configuration. Et il y avait quelques dépendances qu'il m'a dit d'installer.
notbad.jpeg
Est-ce que cela connecte avec Glassfish 4 sur wss: (SSL)
Archimedes Trajano
1
@ notbad.jpeg: Vous voulez probablement dire ./buildconf (pas ./buildconfig) :-)
Erik Forsberg
1
Juste mes commentaires ... ceci a été installé et chargé dans Apache 2.2.22-1ubuntu1.10 d'Ubuntu 12.04, mais cela n'a pas fonctionné pour moi à la fin. Le proxy supprimait l'en-tête "Upgrade" (le code source indique "RFC2616 13.5.1 indique que nous devrions effacer ces en-têtes"), qui est un en-tête attendu par le serveur, pas seulement un saut, il n'a donc pas fonctionné, et je l'ai remplacé par une règle iptables DNAT à la place.
Peter
11

Rien n'indique qu'Apache httpd les supportera bientôt.

Si vous devez exécuter websockets via Apache, essayez mod_pywebsocket . Je l'ai essayé et ça marche.

Voici quelques alternatives que je préfère:

h0tw1r3
la source
3

S'il vous plaît jeter un oeil à http://github.com/disconnect/apache-websocket

Le module apache-websocket est un module de serveur Apache 2.x qui peut être utilisé pour traiter des requêtes utilisant le protocole WebSocket par un serveur Apache 2.x.

Marat Denenberg
la source
J'ai regardé le projet ci-dessus github. Il n'agit pas en tant que proxy. citationThe module consists of a plugin architecture ...
guettli
1

Ceci est ajouté à la réponse de @Andrew Moss sur la manière de configurer correctement le VirtualHostfonctionnement avec socket.io 1.0! N'hésitez pas à sauter la partie sur CentOS!


Si vous êtes bloqué sur CentOS 6, voici comment procéder:

  1. Téléchargez le code source du mod_proxy_wstunnelmodule ici (clonez le Gist ou téléchargez les fichiers individuellement).
  2. Installez tout le nécessaire pour construire: yum install make gcc httpd-devel
  3. Installer un environnement de compilation RPM (essentiellement un utilisateur non privilégié et certains répertoires)
  4. Copiez le .cfichier -file dans le SOURCESsous - dossier de l'environnement et le .specfichier -file dans le SPECSsous - dossier.
  5. Courir rpmbuild -ba mod_proxy_wstunnel.spec
  6. Le paquet est maintenant dans le SRPMSsous - dossier
  7. Installez le paquet: rpm -i /path/to/package.rpm
  8. Profit

Cela chargera aussi automatiquement le module dans Apache, il ne vous reste donc plus qu’à le redémarrer service httpd restart.


Configurer VirtualHostpour servir réellement le serveur Socket.io et le script client (qui est disponible par défaut sous http://your.server/socket.io/socket.io.js) est un peu plus compliqué sur Apache 2.2, à cause d'un bogue dans le mod_proxymodule :

Étant donné la règle de réécriture suivante:

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

mod_rewrite traite ce chemin comme un fichier afin que le journal des accès montre:

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

Donc, vous ne pouvez pas utiliser le wsprotocole -protoc dans une règle de réécriture , car cela se transformerait en interne en une requête HTTP GET.

Il existe cependant une solution de contournement:

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

Cela garantit que tout ce qui est envoyé /socket.iova au ws://protocole, à l'exception de la demande d'interrogation longue (qui est un mécanisme de secours lorsque WebSockets n'est pas disponible) et de la demande de la bibliothèque client.

Lukas Knuth
la source