前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文秒懂!腾讯云ES HTTPS 集群访问通信最佳实践

一文秒懂!腾讯云ES HTTPS 集群访问通信最佳实践

原创
作者头像
吴容
发布2022-08-12 15:58:50
2.1K2
发布2022-08-12 15:58:50
举报

Elasticsearch提供了多种数据访问安全的方式,如用户名密码校验、api_key等。但是依然无法保障数据传输过程中的安全性问题。而HTTPS协议,则是一种以安全为目的的HTTP通道,在HTTP的基础上通过传输加密和身份认证等机制来保障数据传输过程中的安全性。本文将基于腾讯云ES集群环境,演示Beats、Logstash、Kibana和Java Client等客户端访问连接开启了HTTPS协议的ES集群。

一、HTTPS集群环境准备

1、创建HTTPS协议集群

首先我们在腾讯云ES控制台创建出一个HTTPS集群,在购买页这里勾选上HTTPS协议。目前该特性目前是通过白名单支持,可提工单申请开放。

图片
图片

其中,ES集群是通过在elasticsearch.yml配置文件中设置如下参数来开启HTTPS协议的:

代码语言:javascript
复制
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/ces-certificates.p12
xpack.security.http.ssl.truststore.path: certs/ces-certificates.p12

2、获取pem证书文件

集群创建成功后,提工单让腾讯云ES研发提供访问HTTPS集群所需要的鉴权证书文件。此时腾讯云ES侧会提供如下两个证书文件:

文件名称

用途

client-certificates.pem

用于Beats Logstash、Java Client连接ES集群

server-certificates.pem

用于Kibana连接ES集群

下面将详细介绍Beats、Logstash、Kibana和Java等客户端连接HTTPS集群的配置方式。

二、Beats输出到HTTPS集群

1、CVM Metriceat输出到ES

我们首先在腾讯云CVM控制台创建一个和ES集群同VPC下的CVM,创建好后,将得到的pem鉴权文件上传到该CVM上,这里的存放路径为:/usr/local/service/https-certs。随后到腾讯云ES控制台的Beats管理页,创建一个Metricbeat:

图2. 创建Metricbeat
图2. 创建Metricbeat

其中,最核心的步骤是在metricbeat.yml配置文件中进行如下配置。

代码语言:javascript
复制
output.elasticsearch:
  hosts: ["https://ES-VIP:9200"]
  username: "elastic"
  password: "changeme"
  ssl.certificate_authorities: ["/usr/local/service/https-certs/client-certificates.pem"]
  ssl.verification_mode: certificate

配置信息说明:

配置项

说明

hosts

ES集群的VIP,如https://10.0.X.29:9200,以https开头

username/password

ES集群的用户名密码

ssl.certificate_authorities

连接HTTPS集群所需的pem鉴权证书文件路径

ssl.verification_mode

服务器证书认证模式,有四种模式,分别是full,strict,certificate和none。我们这里以certificate模式进行认证,即只认证CA证书,不认证主机名信息。详情可参考官方文档。

配置完成后,即可在ES集群中看到自动创建了一个metricbeat-7.14.20-*开头的索引,到此CVM中Metricbeat连接HTTPS的ES集群配置完成。

图3. ES集群中自动创建了metricbeat相关的索引
图3. ES集群中自动创建了metricbeat相关的索引

2、TKE Filebeat日志采集器输出到ES

TKE Filebeat日志采集器输出到HTTPS的ES集群流程和CVM的metricBeat输出一样,首先我们将pem文件上传到创建TKE集群时自动创建的Worker所在的CVM节点上,如/var/log/https-certs目录下。

图片
图片

client-certificates.pem文件存放位置:

图片
图片

随后我们在腾讯云ES控制新建Fliebeat采集器,这里选择TKE日志采集:

图片
图片

下面进行Filebeat采集器的基本信息配置,如版本号选择,采集器输出ES集群选择,如图7、8所示:

图片
图片
图片
图片

创建好Filebeat TKE容器日志采集器后,随后我们在TKE集群的详情页,找到配置管理中的ConfigMap,然后找到对应beats的config文件:

图片
图片

点击“编辑yaml”后对output.elasticsearch配置项进行修改,如下图10所示:

图片
图片

具体配置信息如下:

代码语言:javascript
复制
output.elasticsearch:
    hosts: ['https://ES-VIP:9200']
    username: "elastic"
    ssl.certificate_authorities: ["/var/log/https-certs/client-certificates.pem"]
    ssl.verification_mode: "certificate"
    password: "changeme"
    indices:
      - index: "filebeat-tke-%{+yyyy.MM.dd}"
        when.equals:
          tke_collector_target_name: "logs_to_https_es"

进入到Pod管理页,选择对应的Pod销毁重建。

图片
图片

销毁重建后,Pod的运行状态变成Running,如图13所示。 

注:如果多次对pod进行销毁重建,仍是红色Running,有可能是beats的yml配置出现问题,可以在日志里面查看具体问题,或者重新检查一下yml配置是否错误。

图片
图片

随后我们到ES集群中,可以看到自动创建了以filebeat-tke-*开头的索引。表明TKE日志顺利输出到HTTPS集群中了。

图片
图片

三、Logstash输出到HTTPS集群

腾讯云Logstash是一款全托管的产品,因此我们首先需要在腾讯云Logstash控制台将pem文件以扩展文件方式进行上传,如下图15所示。

图片
图片

随后我们新建一个管道,在管道的Config配置编辑框里配置上ES的连接信息和证书路径。

图片
图片

管道详细配置文本信息如下:

代码语言:javascript
复制
output {
  elasticsearch {
      hosts => ["https://ES-VIP:9200"]
      user => "elastic"
      password => "changeme"
      ssl => true
      cacert => "/usr/local/service/logstash/extended-files/client-certificates.pem"
      ssl_certificate_verification => false
  }
}

其中cacert即可我们上一步上传的扩展文件pem的路径,固定路径为:/usr/local/service/logstash/extended-files/client-certificates.pem。点击保存并部署管道后,就会在管道列表里可以看到我们刚刚新建出来的管道信息了,此时状态为运行中。

图片
图片

这时候我们再到HTTPS集群中就可以看到有数据从input的集群中写入进来了。

四、Kibana连接HTTPS集群

腾讯云ES集群默认自带Kibana访问能力,因此一般情况下,客户是不需要对Kibana进行任何配置的。这里介绍自建Kibana连接HTTPS集群的配置方式。和Beats、Logstash等使用的客户端鉴权证书不一样,Kibana使用的是server-certificates.pem,腾讯云ES侧生成证书命令如下:

代码语言:javascript
复制
openssl pkcs12 -in ces-certificates.p12 -password pass:xxxxxx -nokeys -cacerts -out server-certificates.pem

由于前面我们已经拿到了pem证书文件。因此,我们将server-certificates.pem文件拷贝到Kibana所在节点的如下路径:/usr/local/service/https-certs。然后修改kibana.yml配置文件如下:

代码语言:javascript
复制
elasticsearch.hosts: ["https://ES-VIP:9200"]
elasticsearch.username: "elastic"
elasticsearch.password: "changeme"
elasticsearch.ssl.verificationMode: certificate
elasticsearch.ssl.certificateAuthorities: ["/usr/local/service/https-certs/server-certificates.pem"]
xpack.encryptedSavedObjects.encryptionKey: "dfed624ca4014135f61804440536xxxx"
xpack.fleet.registryUrl: "https://epr.elastic.co"

配置项说明:elasticsearch.ssl.certificateAuthorities:pem文件的存放路径。elasticsearch.ssl.verificationMode:证书鉴权模式,certificate 采用只鉴权CA证书,不鉴权主机名称的模式。xpack.fleet.registryUrl:(非必选配置)Fleet集成模块需要访问的公网仓库,这里需要Kibana节点具备公网访问能力。xpack.encryptedSavedObjects.encryptionKey:value可以通过bin/kibana-encryption-keys generate 命令获得。 

图片
图片

重新启动Kibana后即可正常访问HTTPS的ES集群了。

五、Java Client连接HTTPS集群

本文档演示在Spring项目中访问HTTPS集群的配置方式,首先需要添加如下maven依赖:

代码语言:javascript
复制
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>7.10.1</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.10.1</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.10.1</version>
</dependency>

随后我们在ElasticsearchConfig自定义类中实现对Elasticsearch连接的配置。

代码语言:javascript
复制
@Configuration
public class ElasticsearchConfig {
  @Value("${es.username}")
  private String userName;
  @Value("${es.password}")
  private String password;
  @Value("${es.scheme}")
  private String scheme;
  @Value("${es.domain}")
  private String domain;
  @Value("${es.https.cert}")
  private String certFile;
  @Value("${es.port}")
  private int port;
  private RestHighLevelClient client;
  @Bean
  public RestHighLevelClient EsConnectInit() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
      final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
      credentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCredentials(userName,password));
      RestClientBuilder builder;
      if (scheme.equals("https")) {
          Path caCertificatePath = Paths.get(certFile);
          System.out.println(certFile);
          CertificateFactory factory = CertificateFactory.getInstance("X.509");
          Certificate trustedCa;
          try(InputStream is = Files.newInputStream(caCertificatePath)) {
              trustedCa = factory.generateCertificate(is);
          }
          KeyStore trustStore = KeyStore.getInstance("pkcs12");
          trustStore.load(null,null);
          trustStore.setCertificateEntry("ca",trustedCa);
          SSLContextBuilder sslContextBuilder = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustStrategy() {
              @Override
              public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                  return true;
              }
          });
          final SSLContext sslContext = sslContextBuilder.build();
          final HostnameVerifier hostnameVerifier = new HostnameVerifier() {
              public boolean verify(String hostname, SSLSession session) {
                  return true;
              }
          };
          builder = RestClient.builder(new HttpHost(domain, port, scheme)).setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
              @Override
              public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) {
                  requestConfigBuilder.setConnectTimeout(-1);
                  requestConfigBuilder.setSocketTimeout(-1);
                  requestConfigBuilder.setConnectionRequestTimeout(-1);
                  return requestConfigBuilder;
              }
          }).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
              @Override
              public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                  httpClientBuilder.disableAuthCaching();
                  httpClientBuilder.setSSLHostnameVerifier(hostnameVerifier);
                  return httpClientBuilder.setSSLContext(sslContext)
                          .setDefaultCredentialsProvider(credentialsProvider);

              }
          });
      } else {
            builder = RestClient.builder(new HttpHost(domain, port, scheme))
                  .setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
                      @Override
                      public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) {
                      requestConfigBuilder.setConnectTimeout(-1);
                          requestConfigBuilder.setSocketTimeout(-1);
                          requestConfigBuilder.setConnectionRequestTimeout(-1);
                          return requestConfigBuilder;
                      }
                  }).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                      @Override
                      public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {                           httpClientBuilder.disableAuthCaching();
                          return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                      }
                  });
      }
      client = new RestHighLevelClient(builder);
      return client;
  }
}

其中Elasticsearch的配置信息如下:

代码语言:javascript
复制
es.scheme=https
es.port=9200
es.domain=9.10.1.X  #es vip
es.username=elastic
es.password=changeme
es.https.cert=/usr/local/services/certs/client-certificates.pem

通过如上配置后,即可在Spring项目中成功连接上开启了HTTPS协议的ES集群了。

扫码加入 Elasticsearch 技术社区👇

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、HTTPS集群环境准备
    • 1、创建HTTPS协议集群
    • 二、Beats输出到HTTPS集群
      • 1、CVM Metriceat输出到ES
        • 2、TKE Filebeat日志采集器输出到ES
        • 三、Logstash输出到HTTPS集群
        • 四、Kibana连接HTTPS集群
        • 五、Java Client连接HTTPS集群
        相关产品与服务
        Elasticsearch Service
        腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档