Skip to content

Connection fail due to ssl #348

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Deamon51 opened this issue Mar 20, 2017 · 9 comments
Closed

Connection fail due to ssl #348

Deamon51 opened this issue Mar 20, 2017 · 9 comments

Comments

@Deamon51
Copy link

Deamon51 commented Mar 20, 2017

Hello,

I’m having trouble connecting my PHP app to MongoDB through SSL with the new MongoDB PHP extension and the MongoDB library for PHP

-Mac os x El Capitan 10.11.6
-Mamp 4.1.1
-PHP 7.0.15
-MongoDB PHP extension 1.2.7
-MongoDB driver library mongodb/mongodb 1.1.2

All seems to be well (screenshot of my php.ini) but I have the following error :

"PHP Fatal error: Uncaught MongoDB\Driver\Exception\ConnectionTimeoutException: No suitable servers found (`serverSelectionTryOnce` set): [TLS handshake failed: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed calling ismaster on 'nosqljoel.documents.azure.com:10250'] in /Applications/MAMP/htdocs/website/vendor/mongodb/mongodb/src/Collection.php:513
Stack trace:
#0 /Applications/MAMP/htdocs/website/vendor/mongodb/mongodb/src/Collection.php(513): MongoDB\Driver\Manager->selectServer(Object(MongoDB\Driver\ReadPreference))
#1 /Applications/MAMP/htdocs/website/public/home.php(63): MongoDB\Collection->find(Array)
#2 {main}
thrown in /Applications/MAMP/htdocs/website/vendor/mongodb/mongodb/src/Collection.php on line 513”

I tried to change extension=mongodb.so in php.ini by the full path at the end of file extension="/Applications/MAMP/bin/php/php7.0.15/lib/php/extensions/no-debug-non-zts-20131226/mongodb.so" but in both case it’s doesn’t work.

mongodb

openssl

@jmikola
Copy link
Member

jmikola commented Mar 20, 2017

Could you attempt capturing some trace information via the mongodb.debug INI option? If you're running in a web server context, you can set this to a writable directory, which will cause the driver to dump one file per request. Alternatively, you can use "stderr" if running the script from a CLI context. These logs are quite verbose, so I would suggest either doing it only for a single request. You can enable the setting at runtime with ini_set() to avoid putting this in php.ini and having it apply globally.

Additionally, let's check that you can verify the certificate using PHP's OpenSSL extension:

<?php

$uri = 'https://nosqljoel.documents.azure.com:10250';

$context = stream_context_create([
    'ssl' => [
        'capture_peer_cert' => true,
        'verify_peer' => true,
        'verify_peer_name' => true,
        'allow_self_signed' => false,
    ],
]);
$contents = file_get_contents($uri, false, $context);
$response = stream_context_get_params($context);

$certificateProperties = openssl_x509_parse($response['options']['ssl']['peer_certificate']);
var_dump($certificateProperties);
var_dump(strlen($contents));

Depending how the MongoDB server is configured, you may get a simple HTTP response with "It looks like you are trying to access MongoDB over HTTP on the native driver port." or an error if HTTP traffic is being filtered. That's fine, as we're mainly interested in the certificate contents and whether it can be verified.

Note: this is roughly the same investigative process previously done with another user in #313.

@Deamon51
Copy link
Author

Deamon51 commented Apr 4, 2017

Thank's @jmikola ,

Here my log file of mongodb.debug
log.txt

Furthermore I tried to verify the certificate using PHP's OpenSSL extension, I'm raised the following error.

ssl error.pdf.

Note: I follow the thread #313 before to open my issue.

@jmikola
Copy link
Member

jmikola commented Apr 4, 2017

Furthermore I tried to verify the certificate using PHP's OpenSSL extension, I'm raised the following error.

In the future, please stick to text files instead of PDFs. If you're unable to validate the certificate with PHP's vanilla stream functions, this hints at a general issue with your PHP or OpenSSL environment. I don't believe it's an issue with the server certificate itself, as that appears to be fine according to some checking tools (e.g. DigiCert, Symantec).

Looking at the MySQL example from your repository, it appears that you had to provide a root certificate manually (certs/azure_mysql_root.pem). Did you also have issues verifying that server without explicitly providing a certificate?

MongoDB\Client::__construct()'s third argument takes driver options, which may be used to provide certificates and control TLS verification. Our ca_file option should correlate with the $ca argument you pass to mysqli::ssl_set(), although you may need a separate certificate since the domains are different.

That said, this would only be a work-around for resolving your PHP and OpenSSL environment.

On a side note, https://github.com/Deamon51/AzureOssPHPSample/ currently contains credentials for your MySQL and MongoDB servers. I'd suggest you move those strings to an ignored file and follow steps in https://help.github.com/articles/removing-sensitive-data-from-a-repository/ to clean up any remnants of the sensitive data.

@Deamon51
Copy link
Author

Deamon51 commented Apr 5, 2017

I forgot to specify this in my first post, but all works fine when I run the application https://github.com/Deamon51/AzureOssPHPSample/ on docker images, it's doesn't work only in local on my Mac environment.
So I think we can avoid certificate issue. Anyway without provide it, I have the same issues as mentioned before.

What do you mean by "Our ca_file option should correlate with the $ca argument you pass to mysqli::ssl_set()"

Thank's for the sensitive data. I will remove it, I totally forgot !

@jmikola
Copy link
Member

jmikola commented Apr 5, 2017

What do you mean by "Our ca_file option should correlate with the $ca argument you pass to mysqli::ssl_set()"

In your example app, you're passing the path to a PEM file as the third argument to mysqli::ssl_set(), which I assume directs the MySQL driver to use that certificate authority instead of the default in your PHP environment. The analogous option in the MongoDB driver is the ca_file option, which is passed in the third array parameter to MongoDB\Client::__construct() or MongoDB\Driver\Manager::__construct().

Both of these are related to the PHP's cafile option for SSL stream contexts, which applies to things like file_get_contents() when doing network requests.

@Deamon51
Copy link
Author

Deamon51 commented Apr 5, 2017

Thanks for your help. Let me try to recap:

It seems that I have an issue with my PHP and OpenSSL environment.

To workaround it, your suggestion would be to use the MongoDB driver the same way I use the PHP driver, by providing a root certificate manually, thanks to the ca_file option.

That's an interesting workaround but do you have an idea on how I can investigate more on the PHP and OpenSSL environment issue to fix it?

Thanks again

@jmikola
Copy link
Member

jmikola commented Apr 5, 2017

To workaround it, your suggestion would be to use the MongoDB driver the same way I use the PHP driver, by providing a root certificate manually, thanks to the ca_file option.

Does the MySQL driver verify the host without explicitly providing a CA file?

Also, can you share a paste of the phpinfo() output (or php -i from the command line if the configurations are the same)?

By default, I believe the mysqli extension uses mysqlnd, which relies on PHP's streams and OpenSSL extension. In that case, the OpenSSL INI options may override the default system config for OpenSSL (e.g. /usr/lib/ssl/openssl.cnf). However, the mongodb extension uses OpenSSL directly through libmongoc (we don't use PHP streams or its OpenSSL extension), so only the system config applies.

@jmikola
Copy link
Member

jmikola commented Apr 5, 2017

Also, let's also confirm that the supplying the CA file to MongoDB\Client::__construct() works before looking into this further.

I forgot to specify this in my first post, but all works fine when I run the application https://github.com/Deamon51/AzureOssPHPSample/ on docker images, it's doesn't work only in local on my Mac environment.

If this is specific to the Mac environment, you may have multiple versions of OpenSSL installed (e.g. Homebrew, native OS), each of which may have different configurations.

@Deamon51
Copy link
Author

Thanks for all @jmikola , my problem has been solved.
I think it's due to a conflict with my local OpenSSL environment.
I proceeded to os update (El capitan -> Sierra) and all seems work fine now !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants