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