使用 TLS 证书身份验证添加远程集群

编辑

使用 TLS 证书身份验证添加远程集群编辑

要使用 TLS 证书身份验证添加远程集群

如果您遇到任何问题,请参阅 故障排除.

先决条件编辑

  1. Elasticsearch 安全功能需要在所有节点上的两个集群中启用。安全默认情况下已启用。如果已禁用,请在 elasticsearch.yml 中将 xpack.security.enabled 设置为 true。请参阅 常规安全设置.
  2. 本地和远程集群版本必须兼容。

    • 任何节点都可以与同一主版本上的另一个节点通信。例如,7.0 可以与任何 7.x 节点通信。
    • 只有特定主版本的最后一个次要版本上的节点才能与下一个主版本上的节点通信。在 6.x 系列中,6.8 可以与任何 7.x 节点通信,而 6.7 只能与 7.0 通信。
    • 版本兼容性是对称的,这意味着如果 6.7 可以与 7.0 通信,则 7.0 也可以与 6.7 通信。下表描述了本地和远程节点之间的版本兼容性。

      版本兼容性表

      本地集群

      远程集群

      5.0–5.5

      5.6

      6.0–6.6

      6.7

      6.8

      7.0

      7.1–7.16

      7.17

      8.0–8.14

      5.0–5.5

      Yes

      Yes

      No

      No

      No

      No

      No

      No

      No

      5.6

      Yes

      Yes

      Yes

      Yes

      Yes

      No

      No

      No

      No

      6.0–6.6

      No

      Yes

      Yes

      Yes

      Yes

      No

      No

      No

      No

      6.7

      No

      Yes

      Yes

      Yes

      Yes

      Yes

      No

      No

      No

      6.8

      No

      Yes

      Yes

      Yes

      Yes

      Yes

      Yes

      Yes

      No

      7.0

      No

      No

      No

      Yes

      Yes

      Yes

      Yes

      Yes

      No

      7.1–7.16

      No

      No

      No

      No

      Yes

      Yes

      Yes

      Yes

      No

      7.17

      No

      No

      No

      No

      Yes

      Yes

      Yes

      Yes

      Yes

      8.0–8.14

      No

      No

      No

      No

      No

      No

      No

      Yes

      Yes

      Elastic 仅支持这些配置子集上的跨集群搜索。请参阅 支持的跨集群搜索配置.

与远程集群建立信任编辑

要安全地使用跨集群复制或跨集群搜索与远程集群,请在所有连接的集群上启用安全,并在每个节点上配置传输层安全 (TLS)。在传输接口上配置 TLS 安全是远程集群的最低要求。为了提高安全性,请在 HTTP 接口 上也配置 TLS。

所有连接的集群必须相互信任,并在传输接口上使用 TLS 进行相互身份验证。这意味着本地集群信任远程集群的证书颁发机构 (CA),而远程集群信任本地集群的 CA。在建立连接时,所有节点都将验证来自另一方节点的证书。这种相互信任是安全连接远程集群所必需的,因为所有连接的节点实际上形成了一个单一的安全域。

用户身份验证在本地集群上执行,用户和用户的角色名称将传递到远程集群。远程集群会根据其本地角色定义检查用户的角色名称,以确定用户可以访问哪些索引。

在使用跨集群复制或跨集群搜索与安全的 Elasticsearch 集群之前,请完成以下配置任务

  1. 在每个节点上配置传输层安全 (TLS),以加密节点间流量并使用本地集群中的节点对所有远程集群中的节点进行身份验证。请参阅 为 Elastic Stack 设置基本安全,了解配置安全的必要步骤。

    此过程使用相同的 CA 为所有节点生成证书。或者,您可以将本地集群中的证书添加为每个远程集群中的受信任 CA。您还必须将远程集群中的证书添加为本地集群中的受信任 CA。使用相同的 CA 为所有节点生成证书可以简化此任务。

连接到远程集群编辑

您必须具有 manage 集群权限才能连接远程集群。

本地集群使用 传输接口 与远程集群建立通信。本地集群中的协调节点与远程集群中的特定节点建立 长时间保持 TCP 连接。Elasticsearch 要求这些连接保持打开状态,即使连接在较长时间内处于空闲状态。

要从 Kibana 中的堆栈管理添加远程集群

  1. 从侧边导航中选择 远程集群
  2. 为远程集群输入一个名称(集群别名)。
  3. 指定 Elasticsearch 端点 URL,或远程集群的 IP 地址或主机名,后跟传输端口(默认为 9300)。例如,cluster.es.eastus2.staging.azure.foundit.no:9300192.168.1.1:9300

或者,使用 集群更新设置 API 添加远程集群。您也可以使用此 API 为本地集群中的每个节点动态配置远程集群。要在本地集群中的各个节点上配置远程集群,请在每个节点的 elasticsearch.yml 中定义静态设置。

以下请求添加了一个别名为 cluster_one 的远程集群。此集群别名是表示与远程集群的连接的唯一标识符,用于区分本地和远程索引。

PUT /_cluster/settings
{
  "persistent" : {
    "cluster" : {
      "remote" : {
        "cluster_one" : {    
          "seeds" : [
            "127.0.0.1:9300" 
          ]
        }
      }
    }
  }
}

此远程集群的集群别名为 cluster_one

指定远程集群中种子节点的主机名和传输端口。

您可以使用 远程集群信息 API 验证本地集群是否已成功连接到远程集群

resp = client.cluster.remote_info()
print(resp)
response = client.cluster.remote_info
puts response
GET /_remote/info

API 响应表明本地集群已连接到别名为 cluster_one 的远程集群

{
  "cluster_one" : {
    "seeds" : [
      "127.0.0.1:9300"
    ],
    "connected" : true,
    "num_nodes_connected" : 1,  
    "max_connections_per_cluster" : 3,
    "initial_connect_timeout" : "30s",
    "skip_unavailable" : false, 
    "mode" : "sniff"
  }
}

本地集群连接到的远程集群中的节点数。

指示是否在通过跨集群搜索进行搜索但没有节点可用时跳过远程集群。

动态配置远程集群编辑

使用 集群更新设置 API 在集群中的每个节点上动态配置远程设置。以下请求添加三个远程集群:cluster_onecluster_twocluster_three

参数 seeds 指定远程集群中种子节点的主机名和 传输端口(默认值为 9300)。

参数 mode 确定配置的连接模式,默认为 sniff。由于 cluster_one 未指定 mode,因此它使用默认值。cluster_twocluster_three 都明确使用不同的模式。

PUT _cluster/settings
{
  "persistent": {
    "cluster": {
      "remote": {
        "cluster_one": {
          "seeds": [
            "127.0.0.1:9300"
          ]
        },
        "cluster_two": {
          "mode": "sniff",
          "seeds": [
            "127.0.0.1:9301"
          ],
          "transport.compress": true,
          "skip_unavailable": true
        },
        "cluster_three": {
          "mode": "proxy",
          "proxy_address": "127.0.0.1:9302"
        }
      }
    }
  }
}

您可以在初始配置后动态更新远程集群的设置。以下请求更新 cluster_two 的压缩设置,以及 cluster_three 的压缩和 ping 计划设置。

当压缩或 ping 计划设置更改时,所有现有的节点连接都必须关闭并重新打开,这会导致正在进行的请求失败。

response = client.cluster.put_settings(
  body: {
    persistent: {
      cluster: {
        remote: {
          cluster_two: {
            'transport.compress' => false
          },
          cluster_three: {
            'transport.compress' => true,
            'transport.ping_schedule' => '60s'
          }
        }
      }
    }
  }
)
puts response
PUT _cluster/settings
{
  "persistent": {
    "cluster": {
      "remote": {
        "cluster_two": {
          "transport.compress": false
        },
        "cluster_three": {
          "transport.compress": true,
          "transport.ping_schedule": "60s"
        }
      }
    }
  }
}

您可以通过为每个远程集群设置传递 null 值来从集群设置中删除远程集群。以下请求从集群设置中删除 cluster_two,保留 cluster_onecluster_three

response = client.cluster.put_settings(
  body: {
    persistent: {
      cluster: {
        remote: {
          cluster_two: {
            mode: nil,
            seeds: nil,
            skip_unavailable: nil,
            'transport.compress' => nil
          }
        }
      }
    }
  }
)
puts response
PUT _cluster/settings
{
  "persistent": {
    "cluster": {
      "remote": {
        "cluster_two": {
          "mode": null,
          "seeds": null,
          "skip_unavailable": null,
          "transport.compress": null
        }
      }
    }
  }
}

静态配置远程集群编辑

如果您在 elasticsearch.yml 中指定设置,则只有具有这些设置的节点才能连接到远程集群并提供远程集群请求。

使用 集群更新设置 API 指定的远程集群设置优先于您在 elasticsearch.yml 中为各个节点指定的设置。

在以下示例中,cluster_onecluster_twocluster_three 是表示与每个集群的连接的任意集群别名。这些名称随后用于区分本地和远程索引。

cluster:
    remote:
        cluster_one:
            seeds: 127.0.0.1:9300
        cluster_two:
            mode: sniff
            seeds: 127.0.0.1:9301
            transport.compress: true      
            skip_unavailable: true        
        cluster_three:
            mode: proxy
            proxy_address: 127.0.0.1:9302 

cluster_two 的请求明确启用了压缩。

断开的远程集群对于 cluster_two 是可选的。

用于连接到 cluster_three 的代理端点的地址。

为远程集群配置角色和用户编辑

连接远程集群 后,您将在本地和远程集群上创建用户角色并分配必要的权限。这些角色是使用跨集群复制和跨集群搜索所必需的。

您必须在本地和远程集群上使用相同的角色名称。例如,以下跨集群复制配置在本地和远程集群上都使用 remote-replication 角色名称。但是,您可以在每个集群上指定不同的角色定义。

您可以在 Kibana 的堆栈管理中管理用户和角色,方法是从侧边导航中选择 安全 > 角色。您也可以使用 角色管理 API 动态添加、更新、删除和检索角色。当您使用 API 在 native 领域管理角色时,这些角色将存储在内部 Elasticsearch 索引中。

以下请求使用 创建或更新角色 API。您必须至少具有 manage_security 集群权限才能使用此 API。

配置跨集群复制的权限编辑

跨集群复制用户需要在远程集群和本地集群上拥有不同的集群和索引权限。使用以下请求在本地和远程集群上创建单独的角色,然后创建一个具有所需角色的用户。

远程集群编辑

在包含领导者索引的远程集群上,跨集群复制角色需要 read_ccr 集群权限,以及对领导者索引的 monitorread 权限。

如果请求使用 API 密钥 进行身份验证,则 API 密钥需要在 本地 集群上拥有上述权限,而不是远程集群。

如果请求以 其他用户的身份 发出,则身份验证用户必须在远程集群上拥有 run_as 权限。

以下请求在远程集群上创建一个 remote-replication 角色

POST /_security/role/remote-replication
{
  "cluster": [
    "read_ccr"
  ],
  "indices": [
    {
      "names": [
        "leader-index-name"
      ],
      "privileges": [
        "monitor",
        "read"
      ]
    }
  ]
}
本地集群编辑

在包含跟随者索引的本地集群上,remote-replication 角色需要 manage_ccr 集群权限,以及对跟随者索引的 monitorreadwritemanage_follow_index 权限。

以下请求在本地集群上创建一个 remote-replication 角色

POST /_security/role/remote-replication
{
  "cluster": [
    "manage_ccr"
  ],
  "indices": [
    {
      "names": [
        "follower-index-name"
      ],
      "privileges": [
        "monitor",
        "read",
        "write",
        "manage_follow_index"
      ]
    }
  ]
}

在每个集群上创建 remote-replication 角色后,使用 创建或更新用户 API 在本地集群上创建一个用户并分配 remote-replication 角色。例如,以下请求将 remote-replication 角色分配给名为 cross-cluster-user 的用户

POST /_security/user/cross-cluster-user
{
  "password" : "l0ng-r4nd0m-p@ssw0rd",
  "roles" : [ "remote-replication" ]
}

您只需要在 本地 集群上创建此用户。

然后,您可以 配置跨集群复制 以跨数据中心复制您的数据。

配置跨集群搜索的权限编辑

跨集群搜索用户需要在远程集群和本地集群上拥有不同的集群和索引权限。以下请求在本地和远程集群上创建单独的角色,然后创建一个具有所需角色的用户。

远程集群编辑

在远程集群上,跨集群搜索角色需要对目标索引拥有 readread_cross_cluster 权限。

如果请求使用 API 密钥 进行身份验证,则 API 密钥需要在 本地 集群上拥有上述权限,而不是远程集群。

如果请求以 其他用户的身份 发出,则身份验证用户必须在远程集群上拥有 run_as 权限。

以下请求在远程集群上创建一个 remote-search 角色

POST /_security/role/remote-search
{
  "indices": [
    {
      "names": [
        "target-indices"
      ],
      "privileges": [
        "read",
        "read_cross_cluster"
      ]
    }
  ]
}
本地集群编辑

在本地集群(用于启动跨集群搜索的集群)上,用户只需要 remote-search 角色。角色权限可以为空。

以下请求在本地集群上创建一个 remote-search 角色

POST /_security/role/remote-search
{}

在每个集群上创建 remote-search 角色后,使用 创建或更新用户 API 在本地集群上创建一个用户并分配 remote-search 角色。例如,以下请求将 remote-search 角色分配给名为 cross-search-user 的用户

POST /_security/user/cross-search-user
{
  "password" : "l0ng-r4nd0m-p@ssw0rd",
  "roles" : [ "remote-search" ]
}

您只需要在 本地 集群上创建此用户。

拥有 remote-search 角色的用户可以 跨集群搜索

配置跨集群搜索和 Kibana 的权限编辑

当使用 Kibana 跨多个集群搜索时,一个两步验证过程决定用户是否可以访问远程集群上的数据流和索引

  • 首先,本地集群确定用户是否有权访问远程集群。本地集群是 Kibana 连接到的集群。
  • 如果用户有权访问,则远程集群会确定用户是否可以访问指定的数据流和索引。

要授予 Kibana 用户访问远程集群的权限,请为他们分配一个本地角色,该角色对远程集群上的索引具有读取权限。您将远程集群中的数据流和索引指定为 <remote_cluster_name>:<target>

要授予用户对远程数据流和索引的读取访问权限,您必须在远程集群上创建一个匹配的角色,该角色授予 read_cross_cluster 权限,并允许访问相应的数据流和索引。

例如,您可能正在本地集群上积极地索引 Logstash 数据,并定期将较旧的基于时间的索引卸载到远程集群上的存档中。您希望跨两个集群进行搜索,因此您必须在两个集群上启用 Kibana 用户。

本地集群编辑

在本地集群上,创建一个 logstash-reader 角色,该角色对本地 logstash-* 索引授予 readview_index_metadata 权限。

如果您将本地集群配置为 Elasticsearch 中的另一个远程集群,则本地集群上的 logstash-reader 角色还需要授予 read_cross_cluster 权限。

POST /_security/role/logstash-reader
{
  "indices": [
    {
      "names": [
        "logstash-*"
        ],
        "privileges": [
          "read",
          "view_index_metadata"
          ]
    }
  ]
}

为您的 Kibana 用户分配一个角色,该角色授予 访问 Kibana 的权限,以及您的 logstash_reader 角色。例如,以下请求创建 cross-cluster-kibana 用户并分配 kibana-accesslogstash-reader 角色。

PUT /_security/user/cross-cluster-kibana
{
  "password" : "l0ng-r4nd0m-p@ssw0rd",
  "roles" : [
    "logstash-reader",
    "kibana-access"
    ]
}
远程集群编辑

在远程集群上,创建一个 logstash-reader 角色,该角色授予 read_cross_cluster 权限,以及对 logstash-* 索引的 readview_index_metadata 权限。

POST /_security/role/logstash-reader
{
  "indices": [
    {
      "names": [
        "logstash-*"
        ],
        "privileges": [
          "read_cross_cluster",
          "read",
          "view_index_metadata"
          ]
    }
  ]
}