SSL Configuration

edit

Configuring SSL is a little more complex. First you need to identify if your certificate has been signed by a public Certificate Authority (CA), or if it is a self-signed certificate. Then you need to identify which ConnectionClass you are using, since they have slightly different syntax to enable SSL.

A note on libcurl version

If you believe the client is configured to correctly use SSL, but it simply is not working, check your libcurl version. On certain platforms, various features may or may not be available depending on version number of libcurl. For example, the --cacert option was not added to the OSX version of libcurl until version 7.37.1. The --cacert option is equivalent to PHP’s CURLOPT_CAINFO constant, meaning that custom certificate paths will not work on lower versions.

If you are encountering problems, update your libcurl version and/or check the curl changelog.

GuzzleConnection + Public CA Cert

edit

If your certificate has been signed by a public Certificate Authority and your server has up-to-date root certificates, you only need to use https in the host path. Guzzle will automatically verify SSL certificates:

$params = array();
$params['hosts'] = array (
    'https://localhost:9200' 
);

$client = new Elasticsearch\Client($params);

Note that https is used, not http

If your server has out-dated root certificates, you may need to use a certificate bundle. For PHP clients, the best way is to use Kdyby/CurlCaBundle. Once installed, you would use inject it into the client:

$params = array();
$params['hosts'] = array (
    'https://localhost:9200'
);

$params['guzzleOptions'] = array(
    \Guzzle\Http\Client::SSL_CERT_AUTHORITY => 'system', 
    \Guzzle\Http\Client::CURL_OPTIONS => [
        CURLOPT_SSL_VERIFYPEER => true, 
        CURLOPT_SSL_VERIFYHOST => 2, 
        CURLOPT_CAINFO => \Kdyby\CurlCaBundle\CertificateHelper::getCaInfoFile() 
    ]
);
$client = new Elasticsearch\Client($params);

Tell Guzzle that we are providing our own root certificates

Verify that the certificate has been signed by a CA and can be trusted

Verify that the host you are talking to is the host in the certificate. Note that cURL needs the value of 2, not true or 1 (due to an internal cURL depreciation)

Tell cURL where the certificate bundle is located

Note: Guzzle’s CURL_OPTIONS parameter will accept any PHP curl_opt constant for configuring.

GuzzleConnection + Self-Signed Certificate

edit

Self-signed certificates are certs that have not been signed by a public CA. They are signed by your own organization. Self-signed certificates are often used for internal purposes, when you can securely spread the root certificate yourself. It should not be used when being exposed to public consumers, since this leaves the client vulnerable to man-in-the-middle attacks.

If you are using a self-signed certificate, you need to provide the certificate to the client:

$params = array();
$params['hosts'] = array (
    'https://localhost:9200'
);

$params['guzzleOptions'] = array(
    \Guzzle\Http\Client::SSL_CERT_AUTHORITY => 'system',
    \Guzzle\Http\Client::CURL_OPTIONS => [
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_CAINFO => 'cacert.pem', 
        CURLOPT_SSLCERTTYPE => 'PEM', 
    ]
);
$client = new Elasticsearch\Client($params);

CAInfo is used to specify the path to the self-signed certificate

Finally, the certificate type is specified. PEM is default, so you can omit this if you are using .pem certs

CurlMultiConnection + Public CA Cert

edit

Similar to Guzzle, CurlMultiConnection will work seamlessly with publicly signed certs. You just need to specify the ConnectionClass and use https in the URI:

$params = array();
$params['connectionClass'] = '\Elasticsearch\Connections\CurlMultiConnection';

$params['hosts'] = array (
    'https://localhost:9200' 
);

$client = new Elasticsearch\Client($params);

Note that https is used, not http

If your server does not have up-to-date root certificates, you can also use Kdyby/CurlCaBundle with CurlMultiConnection:

$params = array();
$params['connectionClass'] = '\Elasticsearch\Connections\CurlMultiConnection';

$params['hosts'] = array (
    'https://localhost:9200'
);

$params['connectionParams']['curlOpts'] = array(
    CURLOPT_CAINFO => \Kdyby\CurlCaBundle\CertificateHelper::getCaInfoFile()
);
$client = new Elasticsearch\Client($params);

Note that the syntax for specifying curl options is different from Guzzle.

CurlMultiConnection + Self-Signed Certificates

edit

To use self-signed certificates, you need to provide the certificate, just like Guzzle, albeit with slightly different syntax:

$params = array();
$params['connectionClass'] = '\Elasticsearch\Connections\CurlMultiConnection';

$params['hosts'] = array (
    'https://localhost:9200'
);

$params['connectionParams']['curlOpts'] = array(
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_CAINFO => 'cacert.pem',
    CURLOPT_SSLCERTTYPE => 'PEM'
);
$client = new Elasticsearch\Client($params);