安全

Elasticsearch-PHP 客户端支持两种安全设置方式:HTTP 认证和 SSL 加密。

HTTP 认证

如果你的 Elasticsearch 是通过 HTTP 认证来维持安全,你就要为 Elasticsearch-PHP 客户端提供身份凭证(credentials),这样服务端才能认证客户端请求。在实例化客户端时,身份凭证(credentials)需要配置在 host 数组中:

  1. $hosts = [
  2. 'http://user:pass@localhost:9200', // HTTP Basic Authentication
  3. 'http://user2:pass2@other-host.com:9200' // Different credentials on different host
  4. ];
  5. $client = ClientBuilder::create()
  6. ->setHosts($hosts)
  7. ->build();

每个 host 都要添加身份凭证(credentials),这样的话每个 host 都拥有自己的身份凭证(credentials)。所有发送到集群中的请求都会根据访问节点来使用相应的身份凭证(credentials)。

SSL 加密

配置 SSL 会有些复杂。你要去识别 Certificate Authority (CA) 签名的证书或者自签名证书。

libcurl版本注意事项

如果你觉得客户端已经正确配置 SSL,但是没有起效,请检查你的 libcurl 版本。在某些平台上,一些设置可能有效也可能无效,这取决于 libcurl 版本号。例如直到 libcurl 7.37.1,OSX 平台的 libcurl 才添加 --cacert 选项。 --cacert 选项对应 PHP 的 CURLOPT_CAINFO 常量, 这就意味着自定义的证书在低版本下是无法使用的。

如果你现在正面临这个问题,请更新你的 libcurl,然后/或者查看 curl changelog 有无增加该选项。

公共 CA 证书

如果你的证书是公共 CA 签名证书,且你的服务器用的是最新的根证书,你只需要在 host 中使用 https。客户端会自动识别 SSL 证书:

  1. $hosts = [
  2. 'https://localhost:9200'
  3. ];
  4. $client = ClientBuilder::create()
  5. ->setHosts($hosts)
  6. ->build();

注意:这里用的是 https 而非 http

如果服务器的根证书已经过期,你就要用证书 bundle。对于客户端来说,最好的方法是使用 composer/ca-bundle。一旦安装好 ca-bundle,你要告诉客户端使用你提供的证书来替代系统的 bundle:

  1. $hosts = ['https://localhost:9200'];
  2. $caBundle = \Composer\CaBundle\CaBundle::getBundledCaBundlePath();
  3. $client = ClientBuilder::create()
  4. ->setHosts($hosts)
  5. ->setSSLVerification($caBundle)
  6. ->build();

自签名证书

自签名证书是指没有被公共 CA 签名的证书。自签名证书由你自己的组织来签名。在你确保安全发送自己的根证书前提下,自签名证书可用作内部使用的。当自签名证书暴露给公众客户时就不应该使用了,因为客户端容易受到中间人攻击。

如果你正使用自签名证书,你要给客户端提供证书路径。这与指定一个根 bundle 的语法一致,只是把根 bundle 替换为自签名证书:

  1. $hosts = ['https://localhost:9200'];
  2. $myCert = 'path/to/cacert.pem';
  3. $client = ClientBuilder::create()
  4. ->setHosts($hosts)
  5. ->setSSLVerification($myCert)
  6. ->build();

同时使用认证与 SSL

同时使用认证与 SSL 也是有可能的。在 URI 中指定 https 与身份凭证(credentials),同时提供 SSL 所需的自签名证书。例如下面的代码段就同时使用了 HTTP 认证和自签名证书:

  1. $hosts = ['https://user:pass@localhost:9200'];
  2. $myCert = 'path/to/cacert.pem';
  3. $client = ClientBuilder::create()
  4. ->setHosts($hosts)
  5. ->setSSLVerification($myCert)
  6. ->build();