New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apache 2.4 ProxyPass Configuration #1696

Closed
Twipped opened this Issue Jul 28, 2014 · 32 comments

Comments

Projects
None yet
@Twipped

Twipped commented Jul 28, 2014

With 0.9 I was able to proxy our websockets through Apache 2.4 using the following config:

ProxyPass /socket.io/1/websocket ws://localhost:8082/socket.io/1/websocket
ProxyPassReverse /socket.io/1/websocket ws://localhost:8082/socket.io/1/websocket

ProxyPass /socket.io/ http://localhost:8082/socket.io/
ProxyPassReverse /socket.io/ http://localhost:8082/socket.io/

I'm attempting to migrate to 1.0.6 now and I immediately noticed that the socket endpoint changed, but updating the ProxyPass config like so does not seem to do the trick.

ProxyPass /socket.io/?EIO=2&transport=websocket ws://localhost:8082/socket.io/?EIO=2&transport=websocket
ProxyPassReverse /socket.io/?EIO=2&transport=websocket ws://localhost:8082/socket.io/?EIO=2&transport=websocket

ProxyPass /socket.io/ http://localhost:8082/socket.io/
ProxyPassReverse /socket.io/ http://localhost:8082/socket.io/

Chrome reports over and over again that it receives a 400 error when trying to open the websocket. There's no output in the console on the server to indicate that any connection attempt was received (DEBUG=socket.io).

Is there some other configuration factor that I need for this to work?

@Twipped

This comment has been minimized.

Twipped commented Jul 28, 2014

When I switch to DEBUG=engine I see the following for every socket opening attempt:

  engine intercepting request for path "/socket.io/" +5s
  engine handling "GET" http request "/socket.io/?EIO=2&transport=websocket" +0ms
  engine handshaking client "103lrAsEBsbf83EpAAAL" +0ms
@Twipped

This comment has been minimized.

Twipped commented Jul 29, 2014

So after a further day of exploration, an issue I'm running in to is that Apache doesn't support binding proxy paths to specific query arguments, so there's no way to separate the websocket from the normal http calls because they both land on /socket.io/. Is there any way to make socket.io use an alternate endpoint for the the just websocket?

@ghost

This comment has been minimized.

ghost commented Aug 7, 2014

I would like to confirme this issue. I tested reverse proxy on apache and on nginex.

In my opinion socket.io client should work in another way.

If I connect to server. io.connect('host') than host should be able to contain path, for example io.connect('example.com/nodejs') instead io.connect('example.com', {path: '/nodejs/socket.io'}).
And namespace shoulde be passed in optional parameter {namespace: 'namespace_name'}

p.s. correct working with reverse proxy will help with many another problems, like same origin policy or certificates for secure connections.

@akamensky

This comment has been minimized.

Contributor

akamensky commented Sep 1, 2014

Confirmed even with ProxyPassMatch which suppose to use general regex matching against requested URI.

@zhouwenhong

This comment has been minimized.

zhouwenhong commented Sep 2, 2014

I modified the source code of socket.io-client/socket.io.js 1.0.6

line 3387:
return schema + '://' + this.hostname + port + this.path + query;

Changed to:
return schema + '://' + this.hostname + port + this.path + 'ws/' + query;

And my ProxyPass config:

ProxyPass /socket.io/ws/ ws://localhost:60002/socket.io/
ProxyPassReverse /socket.io/ws/ ws://localhost:60002/socket.io/

ProxyPass /socket.io/ http://localhost:60002/socket.io/
ProxyPassReverse /socket.io/ http://localhost:60002/socket.io/

It works well.

@cyberwolf

This comment has been minimized.

cyberwolf commented Nov 17, 2014

Although not ideal, I managed to make it work without modifying socket.io by using a combination of Apache's mod_rewrite to check the transport query string parameter, and if it's set to "polling" proxy to the http url, otherwise proxy to the ws: url. Rewriting to the ws: protocol with a RewriteRule did not seem to work correctly here, so therefore ProxyPass was still necessary.

Here's the code, for a socket.io server on port 3000:

RewriteEngine on

RewriteCond %{QUERY_STRING} transport=polling
RewriteRule /(.*)$ http://localhost:3000/$1 [P]

ProxyRequests off
ProxyPass /socket.io/ ws://localhost:3000/socket.io/
ProxyPassReverse /socket.io/ ws://localhost:3000/socket.io/

@rauchg rauchg closed this Nov 25, 2014

@Twipped

This comment has been minimized.

Twipped commented Nov 25, 2014

The configuration that @cyberwolf provided only works in Apache 2.5, which has not yet released. Socket.io still cannot be proxied through the current version of Apache, this issue should not be closed.

@cyberwolf

This comment has been minimized.

cyberwolf commented Nov 25, 2014

@ChiperSoft , I use this configuration successfully on Apache 2.4.6 on an Ubuntu 13.10 server, so I don't think Apache 2.5 is the minimum requirement. I agree however that it's cumbersome to add additional configuration like this to make socket.io work behind a proxy, and that this could be better accommodated by socket.io.

@Twipped

This comment has been minimized.

Twipped commented Nov 25, 2014

@cyberwolf that's exactly the same configuration I'm on, but I couldn't get that config to work. when I googled it I found a ticket on the apache bug tracker saying that support for ws:// as a protocol in ProxyPass was added for 2.5 and that they would consider backporting it to 2.4 but had not yet done so.

Are you running any other patches to apache?

@Twipped

This comment has been minimized.

Twipped commented Nov 25, 2014

Wait, I think I got confused. I'm sorry, I was thinking of @zhouwenhong's config. I hadn't tried yours yet.

I'm looking into it now.

@Twipped

This comment has been minimized.

Twipped commented Nov 25, 2014

@cyberwolf Your configuration does indeed work, my apologies for my earlier denial. I had to add a proxypass directive for socket.io.js, but once that was in there everything worked as expected. Thank you!

@cyberwolf

This comment has been minimized.

cyberwolf commented Nov 25, 2014

@ChiperSoft, you're welcome! Glad you got it working.

@andy-h-chen

This comment has been minimized.

andy-h-chen commented Nov 28, 2014

Thanks guys. It works well.

@IgorDePaula

This comment has been minimized.

IgorDePaula commented Dec 7, 2014

I'm using apache 2.4.7 and i use this configuration

ProxyRequests Off

ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/ retry=0
ProxyPassReverse / http://127.0.0.1:3000/ retry=0

ProxyPass /socket.io/ ws://127.0.0.1:3000/socket.io/
ProxyPassReverse /socket.io/ wss://127.0.0.1:3000/socket.io/

I'm receveived this message

"NetworkError: 400 Bad Request - http://www.slidix.com.br/socket.io/?EIO=3&transport=websocket&sid=x96GxaLWUsvS5fDWAAAG"

@Toub

This comment has been minimized.

Toub commented Feb 12, 2015

Woah, thanks!

I can confirm that the following configuration works for me using Apache 2.2.22 with proxy_wstunnel backported.

    RewriteEngine on

    RewriteCond %{QUERY_STRING} transport=polling
    RewriteRule /(.*)$ http://localhost:$port/$1 [P]

    ProxyRequests off
    ProxyPass /socket.io-client/ ws://localhost:$port/socket.io-client/
    ProxyPassReverse /socket.io-client/ ws://localhost:$port/socket.io-client/

    ProxyPass / http://localhost:$port/
    ProxyPassReverse / http://localhost:$port/

Please note that $port should be replaced by your application port (I am using a template here).

An other solution is also documented here (in french): https://blog.crystalyx.net/utiliser-socket-io-et-les-websockets-avec-apache/ ::
<VirtualHost *:80 *:443>
ServerName node.bidule.fr
RewriteEngine On
RewriteRule /socket.io/1/websocket/ - [R=200,L]
ProxyPass /socket.io/socket.io.js http://127.0.0.1:8888/socket.io/socket.io.js
ProxyPassReverse /socket.io/socket.io.js http://127.0.0.1:8888/socket.io/socket.io.js
ProxyPass /socket.io/1/websocket ws://127.0.0.1:8888/socket.io/1/websocket
ProxyPassReverse /socket.io/1/websocket ws://127.0.0.1:8888/socket.io/1/websocket
ProxyPass /socket.io/1/ http://127.0.0.1:8888/socket.io/1/
ProxyPassReverse /socket.io/1/ http://127.0.0.1:8888/socket.io/1/

@IgorDePaula

This comment has been minimized.

IgorDePaula commented Feb 12, 2015

I will try

2015-02-12 6:35 GMT-02:00 Toub notifications@github.com:

Woah, thanks!

I can confirm that the following configuration works for me using Apache
2.2.22 with proxy_wstunnel backported.

RewriteEngine on

RewriteCond %{QUERY_STRING} transport=polling
RewriteRule /(.*)$ http://localhost:$port/$1 [P]

ProxyRequests off
ProxyPass /socket.io-client/ ws://localhost:$port/socket.io-client/
ProxyPassReverse /socket.io-client/ ws://localhost:$port/socket.io-client/

ProxyPass / http://localhost:$port/
ProxyPassReverse / http://localhost:$port/

Please note that $port should be replaced by your application port (I am
using a template here).

An other solution is also documented here (in french):
https://blog.crystalyx.net/utiliser-socket-io-et-les-websockets-avec-apache/
::

ServerName node.bidule.fr
RewriteEngine On
RewriteRule /socket.io/1/websocket/ - [R=200,L]
ProxyPass /socket.io/socket.io.js
http://127.0.0.1:8888/socket.io/socket.io.js
ProxyPassReverse /socket.io/socket.io.js
http://127.0.0.1:8888/socket.io/socket.io.js
ProxyPass /socket.io/1/websocket ws://127.0.0.1:8888/socket.io/1/websocket
ProxyPassReverse /socket.io/1/websocket ws://
127.0.0.1:8888/socket.io/1/websocket
ProxyPass /socket.io/1/ http://127.0.0.1:8888/socket.io/1/
ProxyPassReverse /socket.io/1/ http://127.0.0.1:8888/socket.io/1/


Reply to this email directly or view it on GitHub
#1696 (comment)
.

@p-afraz

This comment has been minimized.

p-afraz commented May 4, 2015

Tnx guys, I managed to setup an Apache 2.4.9 load balancer for socket io 1.3.5, but the problem is with "Session Affinity". Sticky sessions just don't work with this approach. When I've got two load balancers (one for XHR and one for WS), the cookie is set by the first request and everything is OK but when it tries to upgrade to WS the upgrade is routed to another instance and connection gets lost! Here's my Apache config.

Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED

ProxyRequests off

ServerName localhost

<Proxy balancer://http-localhost/>
    BalancerMember http://localhost:8081 route=1 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
    BalancerMember http://localhost:8082 route=2 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900

    ProxySet lbmethod=byrequests
    ProxySet stickysession=ROUTEID
</Proxy>

<Proxy balancer://ws-localhost/>
    BalancerMember ws://localhost:8081 route=1 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
    BalancerMember ws://localhost:8082 route=2 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900

    ProxySet lbmethod=byrequests
    ProxySet stickysession=ROUTEID
</Proxy>

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/socket.io                [NC]
RewriteCond %{QUERY_STRING} transport=websocket        [NC]
RewriteRule /(.*)           balancer://ws-localhost/$1 [P,L]

ProxyPass /socket.io balancer://http-localhost/socket.io
ProxyPassReverse /socket.io balancer://http-localhost/socket.io

ErrorLog logs/nodejs_error_log
CustomLog logs/nodejs_access_log common 
LogLevel debug
@lopezdonaque

This comment has been minimized.

lopezdonaque commented Jun 23, 2015

Hi,

I have used "Connection" header detection to resolve it.

<VirtualHost x.x.x.x:443>
  ServerName domain.local

  RewriteEngine On
  RewriteCond %{HTTP:Connection} Upgrade [NC]
  RewriteRule /(.*) ws://x.x.x.x:3000/$1 [P,L]

  ProxyPass / http://x.x.x.x:3000/

  SSLEngine on
  SSLCertificateFile /etc/apache2/ssl/STAR_x_com.crt
  SSLCertificateKeyFile /etc/apache2/ssl/STAR_x_com.key
  SSLCertificateChainFile /etc/apache2/ssl/STAR_x_com.ca-bundle

  CustomLog /var/log/apache2/access.x.log combined
  ErrorLog /var/log/apache2/error.x.log

 </VirtualHost>

See issue at:
faye/faye#387

@jorgeram

This comment has been minimized.

jorgeram commented Jul 21, 2015

Hi, I'm getting a 400 Bad Request with this configuration:

RewriteEngine on
RewriteCond %{QUERY_STRING} transport=polling
RewriteRule /(.*)$ http://localhost:3000/$1 [P]
ProxyRequests off
ProxyPass /socket.io/ ws://localhost:3000/socket.io/
ProxyPassReverse /socket.io/ ws://localhost:3000/socket.io/

Any idea? How could I get more info about the problem?

Thanks in advance.

@hutber

This comment has been minimized.

hutber commented Sep 17, 2015

@cyberwolf Hey fella

I'm just trying to get this working myself, any chance you could post your whole vhost?

I'm node and using the proxy to pass over to localhost:4001 for my entire site.

@soend

This comment has been minimized.

soend commented Dec 24, 2015

The solution provided here does not work for me also. Heres my apache conf:

<Location /tools/>
    RewriteEngine on

    RewriteCond %{QUERY_STRING} transport=polling
    RewriteRule /(.*)$ http://localhost:8181/$1 [P]

    ProxyPass ws://localhost:8181/
    ProxyPassReverse ws://localhost:8181/
</Location>
@andig

This comment has been minimized.

andig commented Feb 10, 2016

I'm failing to use this config on apache 2.4- has anybody seen this?

Server version: Apache/2.4.18 (Win64)
Invalid ProxyPass|ProxyPassMatch parameter. Parameter must be in the form 'key=value'

Resolved- wrong syntax for using this inside a <Location>.

@silasrm

This comment has been minimized.

silasrm commented Jul 16, 2016

I'm using this config:

<VirtualHost *:80>
    ServerName ws.domain.com

    RewriteEngine On
    RewriteCond %{QUERY_STRING} transport=polling
    RewriteRule /(.*)$ http://localhost:3000/$1 [P]

    ProxyRequests off
    ProxyPass /socket.io/ ws://localhost:3000/socket.io/
    ProxyPassReverse /socket.io/ ws://localhost:3000/socket.io/

    ErrorLog /.../logs/nodejs_error_log
    CustomLog /.../logs/nodejs_access_log common
    LogLevel warn
</VirtualHost>

Before, install proxy modules:

sudo a2enmod proxy proxy_http proxy_wstunnel

Is ok on Apache/2.4.7

@IftachSadeh

This comment has been minimized.

IftachSadeh commented Aug 22, 2016

The above examples didn't quite work for me. However, the solution of Marijn Ophorst did the trick:

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/socket.io/1/websocket  [NC]
RewriteRule /(.*)           ws://localhost:3000/$1 [P,L]

ProxyPass        /socket.io http://localhost:3000/socket.io
ProxyPassReverse /socket.io http://localhost:3000/socket.io

Setup: apache 2.4.23, with Pyramid + gevent-socketio (v0.9.6 of socket.io) for gunicorn.

@jdc20181

This comment has been minimized.

jdc20181 commented Aug 22, 2016

They aren't working for anyone I don't think I have a issue open about the
chat one as my project is needing a messaging system for communication and
the fact the whole thing is a social network- I hope someone can fix the
examples they are needed to get things working correctly.

On Monday, August 22, 2016, Iftach Sadeh notifications@github.com wrote:

The above examples didn't quite work for me. However, the solution of Marijn
Ophorst
http://www.marijnophorst.com/2015/07/19/websockets-with-angular-socket-io-and-apache/
did the trick:

RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io/1/websocket [NC]
RewriteRule /(.*) ws://localhost:3000/$1 [P,L]

ProxyPass /socket.io http://localhost:3000/socket.io
ProxyPassReverse /socket.io http://localhost:3000/socket.io

Setup: apache 2.4.23, with Pyramid + gevent-socketio (v0.9.6 of socket.io)
for gunicorn.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#1696 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AMphBp6uOTSPKj0GoIDsqF9_iBSo_SzCks5qiaXrgaJpZM4CRv5I
.

@IftachSadeh

This comment has been minimized.

IftachSadeh commented Aug 22, 2016

Maybe I wasn't clear, sorry.
The solution of Marijn Ophorst did indeed work for my setup.
I suppose the details depend on the version of socket.io . For use with Pyramid, only version 0.9 can unfortunately be used at this point... But for this, it does work.

@SargonII SargonII referenced this issue Mar 5, 2017

Closed

Error: Not Found #75

@saikiran939

This comment has been minimized.

saikiran939 commented Mar 14, 2017

Sorry for commenting on closed issue - few of the users complained about stickiness not honoured for websockets when wstunnel is enabled. For our internal testing purposes we wanted stickiness therefore I used rewrite engine by manually writing the conditions like below:

if worker1 - route to 5050
if worker2 - route to 6060

RewriteEngine On RewriteCond %{QUERY_STRING} ^.*(websocket).*$ [NC] RewriteCond %{HTTP_COOKIE} ^.*(worker1).*$ [NC] RewriteRule ^/(.*)$ "ws://localhost:5050/$1" [P,L]
RewriteCond %{QUERY_STRING} ^.*(websocket).*$ [NC]
RewriteCond %{HTTP_COOKIE} ^.*(worker2).*$ [NC]
RewriteRule ^/(.*)$ "ws://localhost:6060/$1" [P,L]

This is not for production environments just for automation testing this would do.

@ghost

This comment has been minimized.

ghost commented Apr 7, 2017

I get this error on apache logs:

No protocol handler was valid for the URL /socket.io/. 
If you are using a DSO version of mod_proxy, make sure the proxy submodules 
are included in the configuration using LoadModule.

but I've all the modules loaded:

$ httpd -M (dump modules)
proxy_module (shared)
proxy_http_module (shared)
proxy_wstunnel_module (shared)

with this conf:

 ProxyPass        /socket.io ws://localhost:3000/socket.io/
 ProxyPassReverse /socket.io ws://localhost:3000/socket.io/
@darrachequesne

This comment has been minimized.

Member

darrachequesne commented Apr 9, 2017

Does that help?

@ghost

This comment has been minimized.

ghost commented Apr 11, 2017

@darrachequesne nope.. I've installed all the modules but it still give:
Invalid command 'env=BALANCER_ROUTE_CHANGED', perhaps misspelled
with the config you linked.. I think for now I'll give it up.. maybe i'll try again next months.. I'm spending too much time on this :)

Edit:
I made it working with this:

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
RewriteCond %{QUERY_STRING} transport=websocket    [NC]
RewriteRule /(.*)           ws://localhost:9000/$1 [P,L]

ProxyPass        /socket.io https://localhost:9000/socket.io
ProxyPassReverse /socket.io https://localhost:9000/socket.io

also (my fault) I was not using https and probably it was complaining about that too.

@dsudzy

This comment has been minimized.

dsudzy commented Feb 13, 2018

I am having the same problem none of the comments that have helped other people have worked. My socket.io code works on a vagrant box running ubuntu 14.04 and apache 2.4.7. I am now trying to get it on an aws instance running ubuntu 16.04 and apache 2.4.18.

Here is the full apache conf file:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/projects/name/public

    <Directory /var/www/projects/name/public>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
        Require all granted
    </Directory>

    RewriteEngine On
    RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
    RewriteCond %{QUERY_STRING} transport=websocket    [NC]
    RewriteRule /(.*)           ws://localhost:3000/$1 [P,L]

    ProxyPass        /socket.io https://localhost:3000/socket.io
    ProxyPassReverse /socket.io https://localhost:3000/socket.io

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

here is the full error: http://<ip>:3000/socket.io/?EIO=3&transport=polling&t=M6HBy9b net::ERR_CONNECTION_TIMED_OUT

Is there a way to get a better error?
Should the rewrite/proxy pass code live in a different file or different node?

I also haven't set up https yet I will get to that eventually just want to get this working

@darrachequesne

This comment has been minimized.

Member

darrachequesne commented Feb 20, 2018

@dsudzy maybe you'd have more change there: https://httpd.apache.org/lists.html#http-users

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment