Websocket 具有中间和交叉签名证书的Crossbar SSL/TLS配置

Websocket 具有中间和交叉签名证书的Crossbar SSL/TLS配置,websocket,tls1.2,crossbar,thruway,Websocket,Tls1.2,Crossbar,Thruway,使用最新版本的(0.13,安装于Ubuntu 14.04上的apt-get),我在使用SSL和中间证书进行连接时遇到问题 如果我在tls键中设置服务器时没有ca\u certificates属性,那么服务器运行正常,可以通过wss协议使用Google Chrome建立连接。但是,尝试使用建立连接失败,出现以下错误: 无法连接:无法完成SSL/TLS握手:流\u套接字\u启用\u加密():SSL操作失败,代码为1。OpenSSL错误消息:错误:14094410:SSL例程:ssl3\u读取字节:s

使用最新版本的(0.13,安装于Ubuntu 14.04上的
apt-get
),我在使用SSL和中间证书进行连接时遇到问题

如果我在
tls
键中设置服务器时没有
ca\u certificates
属性,那么服务器运行正常,可以通过
wss
协议使用Google Chrome建立连接。但是,尝试使用建立连接失败,出现以下错误:

无法连接:无法完成SSL/TLS握手:流\u套接字\u启用\u加密():SSL操作失败,代码为1。OpenSSL错误消息:错误:14094410:SSL例程:ssl3\u读取字节:sslv3警报握手失败

这似乎是一个证书问题——在我们的实时站点上,我们使用了一些浏览器以及一些开放ssl实现所需的

看起来,虽然浏览器很乐意只使用一个密钥和证书建立TLS连接,但Throuway需要一个链。但是,下面使用Gandi提供的两个证书的配置不适用于Chrome或Throuway。Chrome显示错误:

失败:WebSocket打开握手已取消

使用下面的
.crossbar/config.json
文件时。那么,这是我的配置、证书还是开放SSL堆栈的其他部分的问题

(以下文件已被更改,以删除任何潜在的敏感信息,因此可能因其他原因而无法正常工作。如果连接正常,则底层auth和其他组件工作正常,因此请保留有关TLS实现的答案/注释。注释不是有效的JSON,但包含在内,以便读者可以查看证书文件(正在使用)

还有其他一些问题与此类似@

  • 处理这样一个事实:任何TLS错误都会在没有有用错误的情况下终止WSS连接
  • 专门处理握手取消,但在他们的情况下,这是一个在编译中使用的配置不当的库,这与本例无关,因为Crossbar是从
    apt get

这不是Crossbar的问题。这似乎是WAMP客户-Throuway的问题。Davidwdan是Throuway Github回购协议的所有者,他说:

“Throuway的Ratchet传输提供程序不直接支持SSL。您需要在其前面放置某种代理。”

你可以在这里找到更多关于戴维德丹和其他人对此的看法的信息

现在让我们来看看解决方案。请注意,以下内容仅适用于Apache用户。如果您运行的是Nginx,则想法基本相同

在我们开始之前,有几件事需要注意

  • 按照Crossbar的安装指南进行安装!不要尝试自己动手!安装Crossbar的过程还有很多。Crossbar的优秀人员已经为您提供了详细的说明
  • 对于这个例子,我让Crossbar和Apache在同一台机器上运行。虽然这不是一个要求,也不重要
  • 您要做的第一件事是创建一个新的虚拟主机。我为此虚拟主机选择了端口4043,但您可以选择任何您想要的。此虚拟主机将用于每个通过wss://(使用SSL)连接没有问题的WAMP库。以下是WAMP客户端的完整列表:。请确保ProxyPass指令和ProxyPassReverse指令的IP地址指向CROSSBAR路由器所在的计算机。在我的情况下,由于Apache和CROSSBAR在同一台计算机上运行,我只使用127.0.0.1。还要确保ProxyPass指令中使用的端口和ProxyPassReverse指令与您在.crossbar/config.json中定义的端口完全相同!您还需要在此虚拟主机上设置SSL证书,您可以看到我在代理指令下面添加了SSL证书

    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/config.json:

    "endpoint": {
            "type": "tcp",
            "port": 8000
            },
    
    虚拟主机:

    ProxyPass /ws/ ws://127.0.0.1:8000/
    ProxyPassReverse /ws/ ws://127.0.0.1:8000/
    
    此外,如果您阅读了其他教程,有些人会告诉您确保在虚拟主机文件中使用PROXYPREVEHOST指令。不要听他们的!这将产生许多意外结果。启用此指令后,此选项将从传入请求传递主机:行到代理主机,而不是hostnaProxyPass行中指定了me!甚至Apache也要求远离此指令。如果启用了此指令,您将收到类似于以下内容的错误:

    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
    
    确保打开虚拟主机文件正在侦听的端口和crossbar路由器正在侦听的端口。在我的示例中:

    $ sudo ufw allow 4043
    $ sudo ufw allow 8000
    
    最后重新启动Apache,使所有更改生效

    $ sudo service apache2 restart
    
    最后但并非最不重要的一点是,我想快速解释一下为什么必须这么做:

  • 当您在服务器上设置了SSL证书时,在尝试连接到任何WAMP路由器而不使用wss://时,浏览器将抛出错误
  • 通常情况下,解决方案是将WAMP路由器配置为使用服务器上已设置的SSL证书
  • 唯一的问题是Thruway.php(我所知道的唯一一个能与WAMP一起工作的好php客户端)不能很好地与wss://。就连GitHub上Thruway.php的创建者也说它不能工作
  • 解决此问题的方法是使用反向代理
  • 首先,您需要设置WAMP路由器,并确保它没有使用SSL证书
  • 接下来,您需要设置反向代理,以便wss://
    $ sudo ufw allow 4043
    $ sudo ufw allow 8000
    
    $ sudo service apache2 restart
    
    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>