所有的Apache代理连接到不同的端口

在我的Apache 2.4虚拟主机我试图让所有的https://stream量继续到端口443,但所有ws://stream量转发到ws://*:6969

例如:

正常情况下, https://example.com/index:443 https://example.com/index //example.com/index只会转到https://example.com/index:443

ws://example.com/anypathhere/将被转发到ws://example.com/anypathhere:6969

到目前为止,我已经尝试了在vhost中注释掉的值。

 <VirtualHost *:443> SSLEngine on SSLCertificateFile /etc/pki/tls/certs/ca.crt SSLCertificateKeyFile /etc/pki/tls/private/ca.key DocumentRoot /var/www/html/ RewriteOptions Inherit AccessFileName .htaccess AllowEncodedSlashes NoDecode DirectoryIndex disabled <Directory /var/www/html> Options +FollowSymlinks RewriteEngine On AllowOverride All Require all granted RewriteCond %{REQUEST_FILENAME} -d RewriteRule .* %{REQUEST_URI}index.php [L] </Directory> ServerName localhost.localdomain #ProxyPreserveHost On #ProxyRequests Off #ProxyPassMatch / ws://192.16.4.177:6969/ retry=0 #ProxyPassReverse ws:// ws://192.16.4.177:6969/ #ProxyPass ws:// ws://192.16.4.177:6969/ #RewriteEngine On #RewriteRule ws:// ws://%{HTTP_HOST}/$1:6969 [NC,R=301,L] 

所有这些导致

 Firefox can't establish a connection to the server at ws://192.16.4.177:443 

或400错误。

你真的需要添加一个虚拟机监听*:80stream量

Theres是一个点,与RewriteCondProxyPass在错误的VHost文件中都失败了。 您的stream量是由您使用的证书encryption的。 因此连接不会正确build立。 您的远程主机无法读取它。

基于维基百科的文档:

通信是通过TCP端口号80 […]完成的。

你的额外的VHost文件应该是这样的:

 <VirtualHost *:80> ServerName localhost.localdomain ProxyPreserveHost On ProxyRequests Off ProxyPassReverse / ws://192.16.4.177:6969/ ProxyPass / ws://192.16.4.177:6969/ </VirtualHost> 

作为解释。 您的所有请求通过http:80被redirect到ws:6969。

不幸的是,我不认为有一个简单的方法来做到这一点。 彼得的答案不起作用,因为Websockets搭载HTTP(S)作为具有特殊标头的GET请求。 无论mod_rewrite使用什么逻辑来检测URLscheme都不够智能,无法检测到这一点,所以scheme总是显示为httphttps

从理论上讲,你可以自己寻找头,像下面的语法:

 RewriteCond %{HTTP:Upgrade} ^websocket$ [nocase] RewriteRule ^(.*)$ ws://192.16.4.177:6969/$1 [proxy] 

但是,虽然这个规则确实匹配开放客户端握手(在我的日志中确认),但这并不能使我工作的Websocketredirect。 我怀疑, mod_rewrite实际上并不知道如何代理Websocket连接,即使你可以握手去正确的地方。

这让我们与JinnFox的答案。 如果你能够把你的Websockets端点移到/以外的地方,那可能是一个可以接受的解决scheme。

PS同时,我发现NGINX几乎可以无缝地处理这种情况 (向下滚动到第6步find适用于HTTP和WS的代码片段)。

最好的办法是告诉客户端使用正确的端口…但是如果你想要代理或redirect,当他们使用错误的端口:

我不知道任何有关ws://,但我相信你会需要使用RewriteCond ,因为RewriteRule和类似的不包含计划匹配。 请参阅指令参考 。 这可能只有在ws://请求看起来像HTTP请求时才有效,或者你有一个专门处理ws://请求的模块。 (要使用RewriteCond ,你可以根据需要多次列出它,它只适用于下一个RewriteRule [或类似的?])

例如。 代理:

 RewriteEngine On ProxyRequests Off ProxyPreserveHost On RewriteCond %{REQUEST_SCHEME} "^ws$" RewriteRule "^(/?.*)$" ws://otherhost:6969/$1 [P]