45 votes

Configurer Apache2 pour proxy WebSocket?

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

Existe-t-il un moyen de faire comprendre à Apache2 le WebSocket ou simplement (2) de transmettre aveuglément tout ce qu'il reçoit?

24voto

Andrew Moss Points 381

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

J'ai découvert 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 publiées sur mon blog. Je les ai copiées ci-dessous :

# Vérifiez la version d'Apache (doit être 2.2.20 à la date de rédaction, sinon ajustez l'étape suivante)
dpkg -s apache2

# Récupérer la source d'Apache
svn checkout http://svn.apache.org/repos/asf/httpd/httpd/tags/2.2.20/ httpd-2.2.20

# Obtenir le correctif et l'appliquer
wget http://cafarelli.fr/gentoo/apache-2.2.24-wstunnel.patch
cd httpd-2.2.20
patch -p1 < ../apache-2.2.24-wstunnel.patch

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

# Copier le module et le mod_proxy recompilé (pour de nouveaux symboles) dans l'installation d'Apache d'Ubuntu et mettre à jour les autorisations pour correspondre aux autres 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 "# Dépendances: proxy\nLoadModule proxy_wstunnel_module /usr/lib/apache2/modules/mod_proxy_wstunnel.so" | sudo tee -a /etc/apache2/mods-available/proxy_wstunnel.load

# Activer le module (effectuez également les modifications de configuration nécessaires)
sudo a2enmod proxy_wstunnel
sudo service apache2 restart

11voto

h0tw1r3 Points 2706

Il n'y a rien pour indiquer qu'Apache httpd les supportera prochainement.

Si vous devez exécuter des websockets à travers apache, essayez mod_pywebsocket. Je l'ai essayé, et ça fonctionne.

Voici quelques alternatives que je préfère:

6voto

user113844 Points 11

Il semble qu'avec une combinaison du plugin de déconnexion et de quelques lignes de code supplémentaires, cela est maintenant possible :

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

4voto

Heri Points 11

Veuillez jeter un œil à http://github.com/disconnect/apache-websocket

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

4voto

Lukas Knuth Points 121

Ceci ajoute à la réponse de @Andrew Moss sur la manière de configurer correctement le VirtualHost pour fonctionner avec socket.io 1.0! N'hésitez pas à ignorer la partie sur CentOS!


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

  1. Téléchargez la source rétroportée pour le module mod_proxy_wstunnel ici (cloner le Gist ou télécharger les fichiers individuellement)
  2. Installez tout ce qui est nécessaire pour la compilation : yum install make gcc httpd-devel
  3. Configurez un environnement de compilation RPM (essentiellement un utilisateur non privilégié et quelques répertoires)
  4. Copiez le fichier .c dans le sous-dossier SOURCES de l'environnement et le fichier .spec dans le sous-dossier SPECS.
  5. Exécutez rpmbuild -ba mod_proxy_wstunnel.spec
  6. Le package se trouve maintenant dans le sous-dossier SRPMS
  7. Installez le package : rpm -i /chemin/vers/le/package.rpm
  8. Profit

Cela chargera également automatiquement le module dans Apache, donc vous n'avez qu'à le redémarrer avec service httpd restart.


Configurer un VirtualHost pour servir effectivement le serveur Socket.io et le script client (qui est par défaut disponible sous http://votre.serveur/socket.io/socket.io.js) est un peu plus compliqué sur Apache 2.2, en raison d'un bug dans le module mod_proxy :

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

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

mod_rewrite traite cela comme un chemin de fichier, donc le journal d'accès affiche :

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

Ainsi, vous ne pouvez pas utiliser le protocole ws dans une règle de réécriture, car cela se transformera en une requête GET HTTP interne.

Il y a cependant une solution de contournement :

        ServerName votre.serveur

        # Proxy socket.io Websocket
        RewriteEngine On

        # socket.io 1.0+ commence toutes les connexions par une demande de sondage HTTP
        RewriteCond %{QUERY_STRING} transport=polling       [NC]
        RewriteRule /(.*)           http://localhost:8081/$1 [P]

        ProxyRequests Off

        # Envoyer explicitement la demande pour le script client en 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

        # Tout le reste va vers le protocole WebSocket :
        ProxyPass /socket.io/ ws://localhost:8081/socket.io/
        ProxyPassReverse /socket.io/ ws://localhost:8081/socket.io/

        # Toutes les autres choses (le site réel) vont ici
        ProxyPass / http://localhost:8081/
        ProxyPassReverse / http://localhost:8081/

Cela garantit que tout ce qui est envoyé à /socket.io soit dirigé vers le protocole ws://, sauf la demande de sondage à long terme (qui est un mécanisme de repli lorsque les connexions WebSocket ne sont pas disponibles) et la demande de la bibliothèque client.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X