Apache websocket redirection to Tomcat: mod_proxy and mod_proxy_wstunnel

风流意气都作罢 提交于 2019-12-06 12:27:40

After many trials I have finally solved it. Next is the working configuration in case anyone needs it:

This is the vhost.conf file of Apache:

<VirtualHost *:443>
    ServerName www.example.com
    ServerAdmin admin@example.com
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
    CustomLog /var/log/httpd/lavnet_access.log combined
    ErrorLog /var/log/httpd/lavnet_error.log

    ProxyPreserveHost On
    ProxyPass / http://www.example.com:8080/
    ProxyPassReverse / http://www.example.com:8080/
    ProxyRequests Off
    RewriteEngine on
    RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
    RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
    RewriteRule .* ws://www.example.com:8080%{REQUEST_URI} [P]

    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/example.com/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
</VirtualHost>

And this one the connector defined in server.xml in Tomcat:

<Connector URIEncoding="UTF-8"
    connectionTimeout="20000"
    port="8080"
    protocol="org.apache.coyote.http11.Http11AprProtocol">
    <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
</Connector>

Thanks.

The accepted solution works in single instance. But I have cluster with multiple servers and I have load balancer with mod_jk module. In this case after hours of searching I could find a solution to resolve my problem. In mod_jk the name of server appended to end of JSESSIONID like this: JSESSIONID=25B9813E079BA3543C242438FD74CA84.banana.

So I could write a rule to proxy the websocket request to the proper server with the bellow code:

SSLProxyEngine On
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteCond %{HTTP_COOKIE} (^|;\ *)JSESSIONID=.*\.(.+?)(?=;|$) [NC]
RewriteRule .* wss://%2:8443%{REQUEST_URI} [P]

As you see in the last RewriteCond I write a regex which find the name of server in the second regex group. So I write a proxy that route the request to wss://%2:8443%{REQUEST_URI} which is the correct server.

p.s: Don't forget to add server names and IP to /etc/hosts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!