使用最新版本的Crossbar(0.13,从apt-get
安装在Ubuntu 14.04上)我无法使用SSL和中间证书建立连接。
如果我在ca_certificates
密钥中设置了没有tls
属性的服务器,那么服务器运行正常,可以通过wss
协议使用Google Chrome进行连接。但是,尝试使用thruway建立连接失败,并出现以下错误:
无法连接:无法完成SSL / TLS握手:stream_socket_enable_crypto():SSL操作失败,代码为1. OpenSSL错误消息:错误:14094410:SSL例程:ssl3_read_bytes:sslv3警报握手失败
哪个having spoken with the Thruway team似乎是证书问题 - 在我们的实际网站上,我们使用了某些浏览器所需的intermediate and cross-signed certificate from Gandi,因此需要一些open-ssl实现。
虽然浏览器很乐意只使用密钥和证书建立TLS连接,但Thruway需要一个链。但是,下面使用Gandi提供的两个证书的配置不适用于 Chrome或Thruway。 Chrome会显示错误:
失败:WebSocket开放握手被取消
使用下面的.crossbar/config.json
文件时。那么,这是我的配置,我的证书还是Open-SSL堆栈的其他部分的问题?
(以下文件已被更改以删除任何可能的敏感信息,因此可能会因其他原因而无效。如果连接有效,则基础身份验证和其他组件工作正常,请保留答案/有关TLS实现的评论。评论不是有效的JSON,但包含在内以便读者可以看到正在使用的证书文件)
{
"version": 2,
"controller": {},
"workers": [
{
"type": "router",
"realms": [
{
"name": "test",
"roles": [
{
"name": "web",
"authorizer": "test.utils.permissions",
"disclose": {
"caller": true,
"publisher": true
}
},
{
"name": "no",
"permissions": []
}
]
}
],
"transports": [
{
"type": "websocket",
"endpoint": {
"type": "tcp",
"port": 9001,
"interface": "127.0.0.1"
},
"auth": {
"wampcra": {
"type": "static",
"users": {
"authenticator": {
"secret": "authenticator-REDACTED",
"role": "authenticator"
}
}
}
}
},
{
"type": "web",
"endpoint": {
"type": "tcp",
"port": 8089,
"tls": {
"key": "../ssl/key.pem",
"certificate": "../ssl/cert.pem",
"ca_certificates": [
"../ssl/gandi.pem", // https://www.gandi.net/static/CAs/GandiProSSLCA2.pem
"../ssl/gandi-cross-signed.pem" // https://wiki.gandi.net/en/ssl/intermediate#comodo_cross-signed_certificate
],
"dhparam": "../ssl/dhparam.pem"
}
},
"paths": {
"/": {
"type": "static",
"directory": "../web"
},
"ws": {
"type": "websocket",
"url": "wss://OUR-DOMAIN.com:8089/ws",
"auth": {
"wampcra": {
"type": "dynamic",
"authenticator": "test.utils.authenticate"
}
}
}
}
}
]
},
{
"type": "guest",
"executable": "/usr/bin/env",
"arguments": [
"php",
"../test.php",
"ws://127.0.0.1:9001",
"test",
"authenticator",
"authenticator-REDACTED"
]
}
]
}
还有其他问题可以解决类似于@
的问题答案 0 :(得分:0)
这不是Crossbar的问题。这似乎是WAMP客户端的一个问题 - 高速公路。 Davidwdan是Thruway Github回购的所有者,他说:
" Thruway的Ratchet传输提供商不直接支持SSL。你需要在它面前放置某种代理。"
您可以在此处找到有关Davidwdan和其他人对此有何建议的更多信息https://github.com/voryx/Thruway/issues/163。
现在来解决问题。请注意,以下仅适用于Apache用户。如果你在Nginx上运行,那么这个想法几乎是一样的。
在我们开始之前需要注意几点。
您要做的第一件事是创建一个新的虚拟主机。我为这个虚拟主机选择了端口4043,但你可以选择你想要的任何东西。这个虚拟主机将用于每个没有通过wss://(使用SSL)连接的WAMP库。以下是WAMP客户的完整列表:http://wamp-proto.org/implementations/。确保ProxyPass指令和ProxyPassReverse指令具有指向CROSSBAR路由器所在机器的IP地址。在我的情况下,由于Apache和Crossbar在同一台机器上运行,我只使用127.0.0.1。还要确保在ProxyPass指令和ProxyPassReverse指令中使用的端口与您在.crossbar / config.json中定义的端口完全相同!您还需要在此虚拟主机上设置SSL证书,您可以看到我在Proxy指令下面添加了该证书。
Listen 4043
<VirtualHost *:4043>
ServerName example.org
ProxyRequests off
SSLProxyEngine on
ProxyPass /ws/ ws://127.0.0.1:8000/
ProxyPassReverse /ws/ ws://127.0.0.1:8000/
## Custom fragment
SSLEngine on
SSLCertificateFile /path/to/server_cert.pem
SSLCertificateKeyFile /path/to/server_key.pem
SSLCertificateChainFile /path/to/server_ca.pem
</VirtualHost>
接下来,确保您的Crossbar路由器未使用SSL进行设置!这非常重要。高速公路或任何其他无法通过SSL WON连接的磁带库如果您将路由器配置为使用SSL,则可以使用该路由器!下面是一个可以使用的Crossbar config.json文件。
{
"version": 2,
"controller": {},
"workers": [
{
"type": "router",
"realms": [
{
"name": "production_realm",
"roles": [
{
"name": "production_role",
"permissions": [
{
"uri": "",
"match": "prefix",
"allow": {
"call": true,
"register": true,
"publish": true,
"subscribe": true
}
}
]
}
]
}
],
"transports": [
{
"type": "websocket",
"endpoint": {
"type": "tcp",
"port": 8000
},
"options": {
"allowed_origins": ["http://*","https://*"]
},
"auth": {
"ticket": {
"type": "static",
"principals": {
"production_user": {
"ticket": "tSjlwueuireladgte",
"role": "production_role"
}
}
}
}
}
]
}
]
}
请注意上面定义的端口号如何与虚拟主机中定义的端口号匹配。
./横杆/ config.json:
"endpoint": {
"type": "tcp",
"port": 8000
},
虚拟主机:
ProxyPass /ws/ ws://127.0.0.1:8000/
ProxyPassReverse /ws/ ws://127.0.0.1:8000/
此外,如果您阅读其他教程,有些人会告诉您确保在虚拟主机文件中使用ProxyPreserveHost指令。不要听他们的意思!这将产生许多意想不到的结果。启用此指令后,此选项将从传入请求传递Host:行到代理主机,而不是ProxyPass行中指定的主机名!甚至Apache也说要远离这个指令https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypreservehost。如果确实启用了它,您将收到类似于以下内容的错误:
failing WebSocket opening handshake ('missing port in HTTP Host header
'example.org' and server runs on non-standard port 8000 (wss =
False)')
最后但并非最不重要的是,确保安装并启用了所有以下Apache库。在最近的Apache安装中,默认情况下安装了以下所有库,只需要启用它们:
$ sudo a2enmod proxy
$ sudo a2enmod proxy_http
$ sudo a2enmod proxy_balancer
$ sudo a2enmod lbmethod_byrequests
$ sudo a2enmod proxy_wstunnel
确保打开虚拟主机文件正在侦听的端口以及纵横交叉路由器正在侦听的端口。就我而言:
$ sudo ufw allow 4043
$ sudo ufw allow 8000
最后重启Apache,以便所有更改生效。
$ sudo service apache2 restart
最后但并非最不重要的是,我想快速解释为什么要做所有这些:
而且......那是所有人!我知道我需要对这个问题给出一个详细的答案,因为我花了5天的时间来计算这一切!
答案 1 :(得分:0)
@ Tay-Bae的回答已经非常有用。但这对我不起作用,客户得到200 OK响应。我要做的就是将WSS通信转发到不支持WSS(Thruway)的内部WS客户端。 在论坛上浏览后,我偶然发现了这个答案:https://serverfault.com/a/846936。 他们添加了一个重写部分,似乎是重新路由请求所必需的。我以为ProxyPassReverse应该这样做,但事实并非如此。所以这是我的工作配置:
Listen 4043
<VirtualHost *:4043>
ServerName mydomain.net
ProxyRequests off
SSLProxyEngine on
ProxyPass /ws/ ws://127.0.0.1:8080/
ProxyPassReverse /ws/ ws://127.0.0.1:8080/
## Custom fragment
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/mydomaine.net/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.net/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/mydomain.net/chain.pem
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule .* ws://localhost:8080%{REQUEST_URI} [P]
</IfModule>
LogLevel debug
ErrorLog ${APACHE_LOG_DIR}/error_thruway.log
CustomLog ${APACHE_LOG_DIR}/access_thruway.log combined
</VirtualHost>