You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@community.apache.org by tv...@able.be on 2016/03/08 17:28:34 UTC

mod_proxy_wstunnel incomplete handshake

Hi,

I'm currently testing a Web socket application behind an apache reverse 
proxy. I started off with apache version 2.4.12, but after some weird 
behavior decided to test versions 2.4.16, 2.4.18 and latest svn.

https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html[1] 
says that

"It provides support for the tunnelling of web socket connections to a 
backend websockets server. The connection is automatically upgraded 
to a websocket connection".

Consider the following config, where reverse proxy listens on 
192.168.0.1 port 80 and web socket application is hosted on internal 
web server 192.168.15.233 port 8888.

LoadModule proxy_module          modules/mod_proxy.so 
LoadModule proxy_wstunnel_module 
modules/mod_proxy_wstunnel.so

Listen 192.168.0.1:80 


    Servername test-ws.domain.org

    ProxyRequests Off 


    RewriteRule ^/([a-zA-Z0-9\.\_\ -:/]*)$  ws://192.168.15.233:8888/$1 [P]

    RewriteRule     .* - [F]

    ProxyPass / ws://192.168.15.233:8888/
    ProxyPassReverse / ws://192.168.15.233:8888/

</VirtualHost>

>From reading the docs it appeared as if HTTP requests are processed 
as normal, unless it is requested to upgrade it to a web socket. 
Basically in apache 2.4.12 the above config expects everything to be a 
web socket. The first request on a connection is processed as normal, 
but once considered a web socket, data is proxied as is without any 
further processing.

On 2.4.18 the behavior is different, only requests with the "Upgrade: 
Websocket" present are considered valid, any other request is denied 
stating unsupported protocol.


For instance:

$ telnet 192.168.0.1 80
Trying 192.168.0.1... 


The error log shows: 

"[Mon Mar 07 11:26:03.133185 2016] [proxy:warn] [pid 26745] [client 
192.168.0.1:33296] AH01144: No protocol handler was valid for the URL 
/. If you are using a DSO ve




The source code also reads that only the request is considered, and a 
response of the server is not/never expected. The only expectation is 
that the connection is opened at both sides (and readable), where it 
should expect a response to complete the handshake of the HTTP 
upgrade mechanism.

Any success or failure of the web server is not considered, eg. in 
success situations a 101 "Switching protocols" can be expected, any 
error status code to indicate a failure. Moreover this allows anyone to 
open a (secure) tunnel towards the back-end server, and possibly 
request anything (other) through it without apache noticing or notifying 
about it (no access/error logs).

Consider the following configuration on 2.4.18:

LoadModule proxy_module          modules/mod_proxy.so 
LoadModule proxy_wstunnel_module 
modules/mod_proxy_wstunnel.so

Listen 192.168.0.1:80 


    Servername test-ws.domain.org

    ProxyRequests Off 


    RewriteRule ^/(TEST/[a-zA-Z0-9\.\_\ -:/]*)$ 
 ws://192.168.15.233:8888/$1 [P]
    RewriteRule ^/[a-zA-Z0-9\.\_\ -:/]*)$  http://192.168.15.233:8888/$1 [P]

    RewriteRule     .* - [F]

    ProxyPass /TEST/ ws://192.168.15.233:8888/TEST/
    ProxyPassReverse /TEST ws://192.168.15.233:8888/TEST/

    ProxyPass / ws://192.168.15.233:8888/
    ProxyPassReverse / ws://192.168.15.233:8888/

</VirtualHost>

$ telnet 192.168.0.1 80

HTTP/1.1 404 Not Found 


HTTP/1.1 200 OK 
                                                                                                                                  
                    


The access log is empty, no trace of any failure. Still the connection is 
persistent and tunneling is further allowed.


The error log shows :
[Tue Mar 08 12:58:31.391351 2016] [rewrite:trace1] [pid 5988] 
mod_rewrite.c(476): [client 192.168.0.1:34207] 192.168.0.1 - - 
[192.168.0.1/sid#8c95ed8][rid#8cf0130/initial] go-ahead with proxy 
request proxy:wss://192.168.15.233:8888/TEST/anyapp [OK] [Tue Mar 
08 12:58:31.391726 2016] [ssl:info] [pid 5988] [remote 
192.168.15.233:8888] AH01964: Connection to child 0 established 
(server 192.168.0.1:80)


Later when the connection is terminated or times out, the access log 
shows:

192.168.0.1 - - [08/Mar/2016:12:58:30 +0100] "GET /INS-
AWINGU/anyapp HTTP/1.1" 200 -

Shouldn't there be some additional processing that at least completes 
the HTTP upgrade handshake before opening the tunnel permanently. If 
not, connections are left open and can be reused for other purposes.

Kind regards,
Tijs

Re: mod_proxy_wstunnel incomplete handshake

Posted by Yann Ylavic <yl...@gmail.com>.
Actually I was working on these lands lately to implement some Upgrade
forwarding.

I ended up with the attached patch (still incomplete, but working)
which moves some mod_proxy_wstunnel parts (TCP-forwarding) to
proxy_util and finally uses the parsing/power of mod_proxy_http for
this achievement.
The patch is based on 2.4.18 and does not apply to trunk or 2.4.x due
latest changes wrt lifetime_transform buckets, but could be easily
adapted...

I think handling Upgrade in mod_proxy_http would "deprecate"
mod_proxy_wstunnel which, as Tijs noticed, can't handle conditional
Upgrade w/o some logic already in mod_proxy_http, and which does not
play well with mod_proxy_http either when the requested (sub)paths
collide.

I'm proposing it now (quite quickly) to see if the approach looks
relevant/suitable/viable (and I could work further on it), or if it is
simply not a good idea :)

Thoughts?

Re: mod_proxy_wstunnel incomplete handshake

Posted by Jim Jagielski <ji...@jaguNET.com>.
Thank you for your email. I am forwarding this to the
correct Email list, which is dev@httpd.apache.org.

> On Mar 8, 2016, at 11:28 AM, tvb@able.be wrote:
> 
> Hi,
> 
> I'm currently testing a Web socket application behind an apache reverse 
> proxy. I started off with apache version 2.4.12, but after some weird 
> behavior decided to test versions 2.4.16, 2.4.18 and latest svn.
> 
> https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html[1] 
> says that
> 
> "It provides support for the tunnelling of web socket connections to a 
> backend websockets server. The connection is automatically upgraded 
> to a websocket connection".
> 
> Consider the following config, where reverse proxy listens on 
> 192.168.0.1 port 80 and web socket application is hosted on internal 
> web server 192.168.15.233 port 8888.
> 
> LoadModule proxy_module          modules/mod_proxy.so 
> LoadModule proxy_wstunnel_module 
> modules/mod_proxy_wstunnel.so
> 
> Listen 192.168.0.1:80 
> 
> 
>    Servername test-ws.domain.org
> 
>    ProxyRequests Off 
> 
> 
>    RewriteRule ^/([a-zA-Z0-9\.\_\ -:/]*)$  ws://192.168.15.233:8888/$1 [P]
> 
>    RewriteRule     .* - [F]
> 
>    ProxyPass / ws://192.168.15.233:8888/
>    ProxyPassReverse / ws://192.168.15.233:8888/
> 
> </VirtualHost>
> 
> From reading the docs it appeared as if HTTP requests are processed 
> as normal, unless it is requested to upgrade it to a web socket. 
> Basically in apache 2.4.12 the above config expects everything to be a 
> web socket. The first request on a connection is processed as normal, 
> but once considered a web socket, data is proxied as is without any 
> further processing.
> 
> On 2.4.18 the behavior is different, only requests with the "Upgrade: 
> Websocket" present are considered valid, any other request is denied 
> stating unsupported protocol.
> 
> 
> For instance:
> 
> $ telnet 192.168.0.1 80
> Trying 192.168.0.1... 
> 
> 
> The error log shows: 
> 
> "[Mon Mar 07 11:26:03.133185 2016] [proxy:warn] [pid 26745] [client 
> 192.168.0.1:33296] AH01144: No protocol handler was valid for the URL 
> /. If you are using a DSO ve
> 
> 
> 
> 
> The source code also reads that only the request is considered, and a 
> response of the server is not/never expected. The only expectation is 
> that the connection is opened at both sides (and readable), where it 
> should expect a response to complete the handshake of the HTTP 
> upgrade mechanism.
> 
> Any success or failure of the web server is not considered, eg. in 
> success situations a 101 "Switching protocols" can be expected, any 
> error status code to indicate a failure. Moreover this allows anyone to 
> open a (secure) tunnel towards the back-end server, and possibly 
> request anything (other) through it without apache noticing or notifying 
> about it (no access/error logs).
> 
> Consider the following configuration on 2.4.18:
> 
> LoadModule proxy_module          modules/mod_proxy.so 
> LoadModule proxy_wstunnel_module 
> modules/mod_proxy_wstunnel.so
> 
> Listen 192.168.0.1:80 
> 
> 
>    Servername test-ws.domain.org
> 
>    ProxyRequests Off 
> 
> 
>    RewriteRule ^/(TEST/[a-zA-Z0-9\.\_\ -:/]*)$ 
> ws://192.168.15.233:8888/$1 [P]
>    RewriteRule ^/[a-zA-Z0-9\.\_\ -:/]*)$  http://192.168.15.233:8888/$1 [P]
> 
>    RewriteRule     .* - [F]
> 
>    ProxyPass /TEST/ ws://192.168.15.233:8888/TEST/
>    ProxyPassReverse /TEST ws://192.168.15.233:8888/TEST/
> 
>    ProxyPass / ws://192.168.15.233:8888/
>    ProxyPassReverse / ws://192.168.15.233:8888/
> 
> </VirtualHost>
> 
> $ telnet 192.168.0.1 80
> 
> HTTP/1.1 404 Not Found 
> 
> 
> HTTP/1.1 200 OK 
> 
> 
> 
> 
> The access log is empty, no trace of any failure. Still the connection is 
> persistent and tunneling is further allowed.
> 
> 
> The error log shows :
> [Tue Mar 08 12:58:31.391351 2016] [rewrite:trace1] [pid 5988] 
> mod_rewrite.c(476): [client 192.168.0.1:34207] 192.168.0.1 - - 
> [192.168.0.1/sid#8c95ed8][rid#8cf0130/initial] go-ahead with proxy 
> request proxy:wss://192.168.15.233:8888/TEST/anyapp [OK] [Tue Mar 
> 08 12:58:31.391726 2016] [ssl:info] [pid 5988] [remote 
> 192.168.15.233:8888] AH01964: Connection to child 0 established 
> (server 192.168.0.1:80)
> 
> 
> Later when the connection is terminated or times out, the access log 
> shows:
> 
> 192.168.0.1 - - [08/Mar/2016:12:58:30 +0100] "GET /INS-
> AWINGU/anyapp HTTP/1.1" 200 -
> 
> Shouldn't there be some additional processing that at least completes 
> the HTTP upgrade handshake before opening the tunnel permanently. If 
> not, connections are left open and can be reused for other purposes.
> 
> Kind regards,
> Tijs


Re: mod_proxy_wstunnel incomplete handshake

Posted by Jim Jagielski <ji...@jaguNET.com>.
Thank you for your email. I am forwarding this to the
correct Email list, which is dev@httpd.apache.org.

> On Mar 8, 2016, at 11:28 AM, tvb@able.be wrote:
> 
> Hi,
> 
> I'm currently testing a Web socket application behind an apache reverse 
> proxy. I started off with apache version 2.4.12, but after some weird 
> behavior decided to test versions 2.4.16, 2.4.18 and latest svn.
> 
> https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html[1] 
> says that
> 
> "It provides support for the tunnelling of web socket connections to a 
> backend websockets server. The connection is automatically upgraded 
> to a websocket connection".
> 
> Consider the following config, where reverse proxy listens on 
> 192.168.0.1 port 80 and web socket application is hosted on internal 
> web server 192.168.15.233 port 8888.
> 
> LoadModule proxy_module          modules/mod_proxy.so 
> LoadModule proxy_wstunnel_module 
> modules/mod_proxy_wstunnel.so
> 
> Listen 192.168.0.1:80 
> 
> 
>    Servername test-ws.domain.org
> 
>    ProxyRequests Off 
> 
> 
>    RewriteRule ^/([a-zA-Z0-9\.\_\ -:/]*)$  ws://192.168.15.233:8888/$1 [P]
> 
>    RewriteRule     .* - [F]
> 
>    ProxyPass / ws://192.168.15.233:8888/
>    ProxyPassReverse / ws://192.168.15.233:8888/
> 
> </VirtualHost>
> 
> From reading the docs it appeared as if HTTP requests are processed 
> as normal, unless it is requested to upgrade it to a web socket. 
> Basically in apache 2.4.12 the above config expects everything to be a 
> web socket. The first request on a connection is processed as normal, 
> but once considered a web socket, data is proxied as is without any 
> further processing.
> 
> On 2.4.18 the behavior is different, only requests with the "Upgrade: 
> Websocket" present are considered valid, any other request is denied 
> stating unsupported protocol.
> 
> 
> For instance:
> 
> $ telnet 192.168.0.1 80
> Trying 192.168.0.1... 
> 
> 
> The error log shows: 
> 
> "[Mon Mar 07 11:26:03.133185 2016] [proxy:warn] [pid 26745] [client 
> 192.168.0.1:33296] AH01144: No protocol handler was valid for the URL 
> /. If you are using a DSO ve
> 
> 
> 
> 
> The source code also reads that only the request is considered, and a 
> response of the server is not/never expected. The only expectation is 
> that the connection is opened at both sides (and readable), where it 
> should expect a response to complete the handshake of the HTTP 
> upgrade mechanism.
> 
> Any success or failure of the web server is not considered, eg. in 
> success situations a 101 "Switching protocols" can be expected, any 
> error status code to indicate a failure. Moreover this allows anyone to 
> open a (secure) tunnel towards the back-end server, and possibly 
> request anything (other) through it without apache noticing or notifying 
> about it (no access/error logs).
> 
> Consider the following configuration on 2.4.18:
> 
> LoadModule proxy_module          modules/mod_proxy.so 
> LoadModule proxy_wstunnel_module 
> modules/mod_proxy_wstunnel.so
> 
> Listen 192.168.0.1:80 
> 
> 
>    Servername test-ws.domain.org
> 
>    ProxyRequests Off 
> 
> 
>    RewriteRule ^/(TEST/[a-zA-Z0-9\.\_\ -:/]*)$ 
> ws://192.168.15.233:8888/$1 [P]
>    RewriteRule ^/[a-zA-Z0-9\.\_\ -:/]*)$  http://192.168.15.233:8888/$1 [P]
> 
>    RewriteRule     .* - [F]
> 
>    ProxyPass /TEST/ ws://192.168.15.233:8888/TEST/
>    ProxyPassReverse /TEST ws://192.168.15.233:8888/TEST/
> 
>    ProxyPass / ws://192.168.15.233:8888/
>    ProxyPassReverse / ws://192.168.15.233:8888/
> 
> </VirtualHost>
> 
> $ telnet 192.168.0.1 80
> 
> HTTP/1.1 404 Not Found 
> 
> 
> HTTP/1.1 200 OK 
> 
> 
> 
> 
> The access log is empty, no trace of any failure. Still the connection is 
> persistent and tunneling is further allowed.
> 
> 
> The error log shows :
> [Tue Mar 08 12:58:31.391351 2016] [rewrite:trace1] [pid 5988] 
> mod_rewrite.c(476): [client 192.168.0.1:34207] 192.168.0.1 - - 
> [192.168.0.1/sid#8c95ed8][rid#8cf0130/initial] go-ahead with proxy 
> request proxy:wss://192.168.15.233:8888/TEST/anyapp [OK] [Tue Mar 
> 08 12:58:31.391726 2016] [ssl:info] [pid 5988] [remote 
> 192.168.15.233:8888] AH01964: Connection to child 0 established 
> (server 192.168.0.1:80)
> 
> 
> Later when the connection is terminated or times out, the access log 
> shows:
> 
> 192.168.0.1 - - [08/Mar/2016:12:58:30 +0100] "GET /INS-
> AWINGU/anyapp HTTP/1.1" 200 -
> 
> Shouldn't there be some additional processing that at least completes 
> the HTTP upgrade handshake before opening the tunnel permanently. If 
> not, connections are left open and can be reused for other purposes.
> 
> Kind regards,
> Tijs