在 Apache mod_proxy_wstunnel 后面使用 go-websocket

Posted

技术标签:

【中文标题】在 Apache mod_proxy_wstunnel 后面使用 go-websocket【英文标题】:Using go-websocket behind Apache mod_proxy_wstunnel 【发布时间】:2013-09-18 01:02:44 【问题描述】:

注意:更新了配置并在 websocket 路径中添加了斜杠。还是一样的问题

是否可以在带有mod_proxy_wstunnel 的 Apache 反向代理后面使用 go-websocket?

我尝试过,但没有成功。

我尝试在 Apache 反向代理后面使用the Chat example(启用了mod_proxy_wstunnel)。它不起作用。代理成功了,而websocket部分完全不行。

我的 Apache 配置如下所示:

<VirtualHost *:80>
    DocumentRoot /var/www/foobar
    ServerName foobar.com
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
    ProxyPass /ws/ ws://localhost:8080/ws/
    ProxyPassReverse /ws/ ws://localhost:8080/ws/
    ErrorLog logs/error_log-foobar
    CustomLog logs/access_log-foobar common
    LogLevel debug
</VirtualHost>

当然,我在 8080 端口上运行聊天服务器。我已经使用 SSH 隧道对其进行了测试,一切正常。然后我转向 Apache。

我第一次尝试时,javascript 控制台报错:

NetworkError: 403 Forbidden - http://foobar.com/ws/

请求似乎停留在源检查中。 然后我在注释掉原点检查后再次尝试,它得到了这个:

NetworkError: 400 Bad Request - http://foobar.com/ws/

聊天服务器似乎根本没有收到升级请求。

我应该如何调试这个? 我应该从哪里开始寻找?

【问题讨论】:

尾部斜线/ 重要吗?只是猜测...... 没有。我想不是。我刚刚尝试在所有内容中添加斜杠。问题还是一样。 我想两台服务器都有日志记录,他们说什么? httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass 表示ProxyPass 指令按顺序匹配,因此您的/ws/ 可能会被/ 遮蔽。如果您更改订单,您会得到不同的行为吗? 谢谢!顺序很重要。 【参考方案1】:

谢谢大家!看了以上几条建议,终于找到了解决办法。

对于可能有类似问题的人,这是我的问题的解决方案:

    正如Aralo 建议的那样,必须将尾部斜杠添加到 WebSocket 路径(在我的例子中:“/ws/”)。看起来 Apache 只会处理带有有效 GET 请求的 WebSocket。

    James Henstridge 是对的。 ProxyPass 的顺序相关。 /ws/的ProxyPass必须放在/行之前。

    查阅Chat示例代码后,在ServeWs()函数中找到an origin check并删除。

现在一切正常。

感谢covener,阅读日志确实有帮助。

【讨论】:

您能否发布您的最终解决方案。您的问题包含您在回答中提到的所有内容。所以,我有点困惑。 这是我最终解决方案的完整描述。你想让我在这里发布实际配置吗?或者你觉得哪一部分难以理解? @KoalaYeung 你也可以发布你的 apache conf 吗? 我们需要查看您在哪个路径编辑了哪个文件以及它最终的外观,以便我们可以将我们的文件与您的文件进行比较。请尽快发布,因为我在搜索解决方案时已经浪费了 2 天时间。 你自己解决真是太好了。您能否提供此源代码...我的电子邮件是 veshraj.joshi1@gmail.com【参考方案2】:

我在 CentOS 7 上使用 Apache 2.4.18 后面的 Go 安全 WebSocket (wss://) 服务器。以下是设置:

确保系统有 mod_proxy_wstunnel:

# 查找 /usr/lib64/httpd/modules/ | grep ws

/usr/lib64/httpd/modules/mod_proxy_wstunnel.so

在 00-proxy.conf 中添加以下行:

# vim /etc/httpd/conf.modules.d/00-proxy.conf

LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

重启 Apache:

#systemctl重启httpd

检查设置:

# httpd -M | grep -iE '代理'

 proxy_module (shared)
 proxy_fcgi_module (shared)
 proxy_http_module (shared)
 proxy_wstunnel_module (shared)

编辑 httpd-vhosts.conf:

# vim /etc/httpd/conf.d/httpd-vhosts.conf

<VirtualHost *:443>
    ServerName go.mydomain.com:443

    ProxyPreserveHost On
    ProxyRequests off

    SSLProxyEngine On
    SSLCertificateFile "/etc/pki/tls/certs/mydomain.com/mydomain.crt"
    SSLCertificateKeyFile "/etc/pki/tls/certs/mydomain.com/mydomain.key"

    ### The configured ProxyPass and ProxyPassMatch rules are checked
    ### in the order of configuration. The first rule that matches wins.
    ProxyPassMatch ^/(ws(/.*)?)$ wss://192.168.0.1:443/$1

    ProxyPass / https://192.168.0.1:443/
    ProxyPassReverse / https://192.168.0.1:443/

    ErrorLog "/var/log/httpd/go.mydomain.com-error_log"
    CustomLog "/var/log/httpd/go.mydomain.com-access_log" common
</VirtualHost>

<VirtualHost *:80>
    ServerName go.mydomain.com:80

    ProxyPreserveHost On
    ProxyRequests off

    ###
    ProxyPassMatch ^/(ws(/.*)?)$ ws://192.168.0.1:80/$1

    ProxyPass / http://192.168.0.1:80/
    ProxyPassReverse / http://192.168.0.1:80/

    ErrorLog "/var/log/httpd/go.mydomain.com-error_log"
    CustomLog "/var/log/httpd/go.mydomain.com-access_log" common
</VirtualHost>

【讨论】:

这个答案对我很有用,因为我必须在没有任何 /path/ 的情况下反向代理 wss 和 https 请求来区分它们。 ProxyPassMatch 派上用场了。

以上是关于在 Apache mod_proxy_wstunnel 后面使用 go-websocket的主要内容,如果未能解决你的问题,请参考以下文章

我无法让 Apache::VMonitor 在 Apache2 中工作

linux apache 配置文件在哪

阿里云linux服务器apache文件夹在哪

Apache 不会在 xampp 上启动:“Apache 服务检测到错误的路径”

怎么在linux搭建Apache?在linux下对apache进行简单配置

在window上安装Apache