问题描述
我正在尝试使用mod_proxy和mod_proxy_wstunnel模块将流量从Apache重定向到Tomcat.重定向HTTP通信量没有问题,但是到目前为止,我无法使用任何配置成功重定向Websocket通信量.
I am trying to redirect traffic from Apache to Tomcat by using mod_proxy and mod_proxy_wstunnel modules. HTTP traffic is redirected without problems but I am not able to successfully redirect websocket traffic with any configuration I tried so far.
我正在使用Apache 2.4.28和Tomcat 8.5.13
I am using Apache 2.4.28 and Tomcat 8.5.13
我必须说,当我在不使用Apache的情况下使用Tomcat时,websockets可以正常工作:
I must say when I use Tomcat without Apache, websockets works perfectly fine:
适用于此配置的Tomcat连接器是下一个:
The Tomcat connector that works for this configuration is next:
<Connector URIEncoding="UTF-8"
compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript"
compression="on"
compressionMinSize="1024"
connectionTimeout="20000"
noCompressionUserAgents="gozilla, traviata"
port="443"
protocol="org.apache.coyote.http11.Http11AprProtocol"
SSLEnabled="true"
scheme="https"
secure="true">
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate certificateKeyFile="/opt/tomcat/cert/privkey.pem"
certificateFile="/opt/tomcat/cert/cert.pem"
certificateChainFile="/opt/tomcat/cert/chain.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
到目前为止很清楚.现在,我在Tomcat前面启动一个Apache服务器,而我要做的第一件事就是像这样的Tomcat连接器:
It's clear until this point. Now I start an Apache server in front of Tomcat and the first thing I change is the Tomcat connector like this:
<Connector URIEncoding="UTF-8"
compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript"
compression="on"
compressionMinSize="1024"
connectionTimeout="20000"
noCompressionUserAgents="gozilla, traviata"
port="8080"
protocol="org.apache.coyote.http11.Http11AprProtocol">
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
</Connector>
在Apache中,我成功加载了下一个模块(我已经检查了它们是否已真正加载):
In Apache I successfully load next modules (I have checked they are really loaded):
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
LoadModule ssl_module modules/mod_ssl.so
这是我在vhosts.conf文件中尝试过的配置之一:
This is one of the configurations I tried in my vhosts.conf file:
<VirtualHost *:443>
ServerName www.example.com
ServerAdmin [email protected]
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
SSLProxyEngine on
#websocket
RewriteEngine on
RewriteCond %{HTTP:Upgrade} "(?i)websocket"
RewriteRule ^/(.*)$ wss://www.example.com/$1 [P]
#rest
ProxyPass "/" "http://www.example.com:8080/"
ProxyPassReverse "/" "http://www.example.com:8080/"
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>
这是我获得的最佳效果的配置,但仍然无法正常工作.当我尝试建立此连接时,lavnet_error.log中的日志跟踪看起来非常不错:
This is the configuration with best results I have achieved but it's still not working. The log traces in lavnet_error.log seems quite good when I try to establish this connection:
[Tue Oct 10 16:46:39.014980 2017] [proxy:debug] [pid 10558:tid 47319680603904] proxy_util.c(2209): [client XX.XX.XX.109:11208] AH00944: connecting wss://www.example.com:443/rest/notify/675/fgcw02lm/websocket to www.example.com:443
[Tue Oct 10 16:46:39.016495 2017] [proxy:debug] [pid 10558:tid 47319680603904] proxy_util.c(2418): [client XX.XX.XX.109:11208] AH00947: connected /rest/notify/675/fgcw02lm/websocket to www.example.com:443
[Tue Oct 10 16:46:39.016567 2017] [proxy:debug] [pid 10558:tid 47319680603904] proxy_util.c(2887): AH02824: WSS: connection established with XX.XX.XX.109:443 (*)
[Tue Oct 10 16:46:39.016590 2017] [proxy:debug] [pid 10558:tid 47319680603904] proxy_util.c(3054): AH00962: WSS: connection complete to XX.XX.XX.109:443 (www.example.com)
[Tue Oct 10 16:46:39.016603 2017] [ssl:info] [pid 10558:tid 47319680603904] [remote 217.61.129.109:443] AH01964: Connection to child 0 established (server www.example.com:443)
[Tue Oct 10 16:46:39.026370 2017] [proxy:debug] [pid 10558:tid 47319680603904] proxy_util.c(2171): AH00943: WSS: has released connection for (*)
但这是Chrome显示的错误:
But this is the error that Chrome shows:
我也尝试了这种其他配置:
I have also tried this other configuration:
<VirtualHost *:443>
ServerName www.example.com
ServerAdmin [email protected]
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
SSLProxyEngine on
ProxyPass "/rest/notify/" "wss://www.example.com:8080/rest/notify"
ProxyPassReverse "/rest/notify/" "wss://www.example.com:8080/rest/notify"
ProxyPass "/" "http://www.example.com:8080/"
ProxyPassReverse "/" "http://www.example.com:8080/"
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>
但是在这种情况下,我得到"500(内部服务器错误)",并且我也可以在lavnet_error.log中看到下一条跟踪记录:
But in this case I get a "500 (Internal Server Error)" and also I can see next traces in lavnet_error.log:
[Tue Oct 10 17:14:14.778824 2017] [proxy:warn] [pid 11924:tid 47694559057664] [client XX.XX.XXX.189:11665] AH01144: No protocol handler was valid for the URL /rest/notify/info (scheme 'wss'). If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule., referer: https://www.example.com/equipment-command-panel/8287/8482
我尝试了许多配置,但无法正常工作.我希望你能帮助我.
I have tried many configurations but I cannot get this to work. I hope you can help me.
谢谢.
推荐答案
经过多次试验,我终于解决了它.接下来是可以正常使用的配置,以防有人需要:
After many trials I have finally solved it. Next is the working configuration in case anyone needs it:
这是Apache的vhost.conf文件:
This is the vhost.conf file of Apache:
<VirtualHost *:443>
ServerName www.example.com
ServerAdmin [email protected]
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>
这是Tomcat中server.xml中定义的连接器:
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>
谢谢.
这篇关于Apache WebSocket重定向到Tomcat:mod_proxy和mod_proxy_wstunnel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!