varspool / Wrench

A simple PHP WebSocket implementation for PHP 7.1
Do What The F*ck You Want To Public License
596 stars 210 forks source link

stream_socket_accept(): Unable to set local cert chain file, failed to create an SSL handle, Failed to enable crypto #79

Closed jdavidzapatab closed 4 years ago

jdavidzapatab commented 8 years ago

Using:

wrench/wrench, version v2.0.7, via Composer.

I've been testing for a while the creation of a Secure Websocket server. I have tested that from my website with no problems, it uses a valid certificate. But a friend of mine is trying to do the same with his valid certificate with no good results.

I helped him to create the secure websocket with Wrench, the PEM certificate was correctly created and the php script has the correct path.

When I start the php script it does not report any problem, it just says the server was initialized. But when the first connection from the browser arrives, it fails with this error message:

root@thedomain:~/websockettest# php secure_server.php
info: Server initialized
PHP Warning:  stream_socket_accept(): Unable to set local cert chain file `/root/.ssl/thedomain.net/2/thedomain.net.pem'; Check that your cafile/capath settings include details of your certificate and its issuer in /root/websockettest/vendor/wrench/wrench/lib/Wrench/Socket/ServerSocket.php on line 87

Warning: stream_socket_accept(): Unable to set local cert chain file `/root/.ssl/thedomain.net/2/thedomain.net.pem'; Check that your cafile/capath settings include details of your certificate and its issuer in /root/websockettest/vendor/wrench/wrench/lib/Wrench/Socket/ServerSocket.php on line 87
PHP Warning:  stream_socket_accept(): failed to create an SSL handle in /root/websockettest/vendor/wrench/wrench/lib/Wrench/Socket/ServerSocket.php on line 87

Warning: stream_socket_accept(): failed to create an SSL handle in /root/websockettest/vendor/wrench/wrench/lib/Wrench/Socket/ServerSocket.php on line 87
PHP Warning:  stream_socket_accept(): Failed to enable crypto in /root/websockettest/vendor/wrench/wrench/lib/Wrench/Socket/ServerSocket.php on line 87

Warning: stream_socket_accept(): Failed to enable crypto in /root/websockettest/vendor/wrench/wrench/lib/Wrench/Socket/ServerSocket.php on line 87
PHP Warning:  stream_socket_accept(): accept failed: Success in /root/websockettest/vendor/wrench/wrench/lib/Wrench/Socket/ServerSocket.php on line 87

Warning: stream_socket_accept(): accept failed: Success in /root/websockettest/vendor/wrench/wrench/lib/Wrench/Socket/ServerSocket.php on line 87
PHP Warning:  socket_last_error() expects parameter 1 to be resource, boolean given in /root/websockettest/vendor/wrench/wrench/lib/Wrench/Socket/ServerSocket.php on line 90

Warning: socket_last_error() expects parameter 1 to be resource, boolean given in /root/websockettest/vendor/wrench/wrench/lib/Wrench/Socket/ServerSocket.php on line 90
err: Socket error: exception 'Wrench\Exception\ConnectionException' with message 'Success' in /root/websockettest/vendor/wrench/wrench/lib/Wrench/Socket/ServerSocket.php:90
Stack trace:
#0 /root/websockettest/vendor/wrench/wrench/lib/Wrench/ConnectionManager.php(183): Wrench\Socket\ServerSocket->accept()
#1 /root/websockettest/vendor/wrench/wrench/lib/Wrench/ConnectionManager.php(166): Wrench\ConnectionManager->processMasterSocket()
#2 /root/websockettest/vendor/wrench/wrench/lib/Wrench/Server.php(198): Wrench\ConnectionManager->selectAndProcess()
#3 /root/websockettest/secure_server.php(41): Wrench\Server->run()
#4 {main}

The certificate PEM file is in the correct path:

root@thedomain:~/websockettest# ls -al /root/.ssl/thedomain.net/2/thedomain.net.pem
-rwxrwxrwx 1 root root 3602 Dec  9 14:15 /root/.ssl/thedomain.net/2/thedomain.net.pem

That PEM file was created with:

cat thedomain.net.crt thedomain.net.key > thedomain.net.pem

The Key file has no Passphrase.

Here is the secure_server.php content:

#!/usr/bin/env php
<?php

ini_set('display_errors', 1);
error_reporting(E_ALL);

require_once "vendor/autoload.php";

$pemFile = '/root/.ssl/thedomain.net/2/thedomain.net.pem';
$pemPassphrase = '';

//$websocketUrl = 'wss://thedomain.net:3001/'; // We used this one, but it fails.
$websocketUrl = 'wss://0.0.0.0:3001/';

// User can use tls in place of ssl
$server = new \Wrench\Server($websocketUrl, array(
    'connection_manager_options' => array(
        'socket_master_options' => array(
            'server_ssl_local_cert'        => $pemFile,
            'server_ssl_passphrase'        => $pemPassphrase,
            'server_ssl_allow_self_signed' => true,
            'server_ssl_verify_peer'       => false,
        )
    )
));

$server->registerApplication('echo', new \Wrench\Application\EchoApplication());
$server->registerApplication('time', new \Wrench\Application\ServerTimeApplication());
$server->run();

For better compatibility, we created a simple apache with SSL on the same machine, and we changed the default index.html to have a very simple echo websocket client connecting to this server. Of course, we added SSL support by using the very same certificate (crt, key, ca_bundle).

I tried all of this with my domain and certificate and it works correctly.

Both certificates were issued by the same company and both are of the same type/class, generated only with a few days of difference.

Is there anything wrong with the secure_server.php script, or perhaps there is any kind of problem with PHP socket functions and how it handles certain certificates?

My webpage with the echo test working is here: [https://jdzb.org/servicios/testwebsockets]. This one works fine.

To test the failing service, right now it is not pointed by the domain, but please add to your host file ("/etc/hosts" in linux, "C:\Windows\System32\drivers\etc\hosts" in windows) the following:

104.236.0.50    ecompound.net

Then access [https://ecompound.net] to test it, although tis page will only display "DISCONNECTED {} Error undefined". The browser console shows:

WebSocket connection to 'wss://ecompound.net:3001/echo' failed: Error in connection establishment: net::ERR_CONNECTION_RESET

Any help is highly appreciated.

UPDATE 01

We have some other ssl certificates available, and we have tested some of those with success, but if we try to connect to the same page from an iPad, somehow it fails, as if there were incompatibility issues between the iPad and the secure websocket server with certain certificates. Again, for this case from an iPad the echo test in my site [https://jdzb.org/servicios/testwebsockets] works correctly, but it has failed from other ssl certificates that are considered valid by all mayor PC web browsers.

dumshi commented 8 years ago

I used this guide to create crt and key. https://www.digitalocean.com/community/tutorials/how-to-create-a-ssl-certificate-on-apache-for-ubuntu-14-04

Then I merged them into joined.pem ( cat apache.crt apache.key > joined.pem ) location of crt, key and joined.pem "/etc/apache2/ssl/".

Then in php: $pemFile = '/etc/apache2/ssl/joined.pem'; $pemPassphrase = 'The one I used to create cert';
//Although apache restart will not ask for pass anymore with this cert, i decided to pass cert anyway as this was on wss

Moreover, I went to my new https://site.com and add cert to acception as it was self signed. I also went to https://site.com:8000/ and add cert to acception as well (make sure your wss server is running). After that, i went back to https://site.com and wss connected fine.

I still have some issues as I upgraded Wrench from older version, but with new install there should be no problem.