将远程集群从证书身份验证迁移到 API 密钥身份验证

编辑

将远程集群从证书身份验证迁移到 API 密钥身份验证编辑

与基于 TLS 证书的安全模型相比,基于 API 密钥的安全模型为远程集群提供了更细粒度的访问控制。因此,您可能希望从基于证书的安全模型迁移到基于 API 密钥的模型。

虽然可以通过定义新的远程集群连接(使用新的别名)来进行迁移,但这有一些缺点

  • 对于跨集群复制,无法更改现有任务的领导者集群别名。因此,对于新的远程集群,需要从头开始重新创建跟随者索引。
  • 对于跨集群搜索,转换和异常检测作业确实允许更新远程集群别名。但是,如果作业是使用通配符创建的,例如 *:source_indexsuperuser,则添加新的远程集群将导致作业执行双倍的工作量,并可能因重复而导致结果偏差。

出于这些原因,您可能更愿意通过以下步骤就地迁移远程集群

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

先决条件编辑

  • 本地集群和远程集群的节点必须在 8.10 或更高版本上。
  • 本地集群和远程集群必须具有适当的许可证。有关更多信息,请参阅https://elastic.ac.cn/subscriptions

重新配置远程集群并生成跨集群 API 密钥编辑

在远程集群上

  1. 在远程集群的每个节点上启用远程集群服务器。在 elasticsearch.yml

    1. remote_cluster_server.enabled 设置为 true
    2. 配置远程集群服务器流量的绑定和发布地址,例如使用remote_cluster.host。如果不配置地址,远程集群流量可能会绑定到本地接口,并且在其他机器上运行的远程集群将无法连接。
    3. (可选)使用remote_cluster.port 配置远程服务器端口(默认为 9443)。
  2. 接下来,生成证书颁发机构 (CA) 和服务器证书/密钥对。在远程集群的其中一个节点上,从安装 Elasticsearch 的目录

    1. 创建 CA(如果您还没有 CA)

      ./bin/elasticsearch-certutil ca --pem --out=cross-cluster-ca.zip --pass CA_PASSWORD

      CA_PASSWORD 替换为您要用于 CA 的密码。如果您没有部署到生产环境,则可以删除 --pass 选项及其参数。

    2. 解压缩生成的 cross-cluster-ca.zip 文件。此压缩文件包含以下内容

      /ca
      |_ ca.crt
      |_ ca.key
    3. 为远程集群中的节点生成证书和私钥对

      ./bin/elasticsearch-certutil cert --out=cross-cluster.p12 --pass=CERT_PASSWORD --ca-cert=ca/ca.crt --ca-key=ca/ca.key --ca-pass=CA_PASSWORD --dns=example.com --ip=127.0.0.1
      • CA_PASSWORD 替换为上一步中的 CA 密码。
      • CERT_PASSWORD 替换为您要用于生成的私钥的密码。
      • 使用 --dns 选项指定证书的相关 DNS 名称。您可以为多个 DNS 指定多次。
      • 使用 --ip 选项指定证书的相关 IP 地址。您可以为多个 IP 地址指定多次。
    4. 如果远程集群有多个节点,您可以

      • 为所有节点创建一个通配符证书;
      • 或者,为每个节点创建单独的证书,可以手动创建,也可以使用静默模式批量创建。
  3. 在远程集群的每个节点上

    1. 将上一步中的 cross-cluster.p12 文件复制到 config 目录。如果您没有创建通配符证书,请确保复制了正确的节点特定的 p12 文件。
    2. 将以下配置添加到 elasticsearch.yml

      xpack.security.remote_cluster_server.ssl.enabled: true
      xpack.security.remote_cluster_server.ssl.keystore.path: cross-cluster.p12
    3. 将 SSL 密钥库密码添加到 Elasticsearch 密钥库

      ./bin/elasticsearch-keystore add xpack.security.remote_cluster_server.ssl.keystore.secure_password

      出现提示时,输入前面步骤中的 CERT_PASSWORD

  4. 重新启动远程集群。
  5. 在远程集群上,生成一个跨集群 API 密钥,该密钥提供对您希望用于跨集群搜索或跨集群复制的索引的访问权限。您可以使用创建跨集群 API 密钥 API 或Kibana
  6. 将编码密钥(响应中的 encoded)复制到安全位置。稍后您将需要它来连接到远程集群。

停止跨集群操作编辑

在本地集群上,停止任何引用远程集群的持久任务

重新连接到远程集群编辑

在本地集群上

  1. 使用跨集群复制和跨集群搜索所需的远程索引权限增强本地集群用户使用的任何角色。请参阅配置角色和用户。注意

    • 您只需要为用于跨集群操作的现有角色分配额外的 remote_indices 权限。您应该能够从远程集群上的原始角色复制这些权限,这些权限是在基于证书的安全模型下定义的。
    • 本地集群上的角色不能超过跨集群 API 密钥授予的 access 权限。任何额外的本地权限都将被跨集群 API 密钥的权限抑制。
    • 如果跨集群复制或跨集群搜索任务已配置为使用 superuser 角色,则无需更新。superuser 角色会自动更新以允许访问所有远程索引。
    • 作为具有命名角色的常规用户运行的任务将立即使用新权限进行更新。任务将在下次运行时加载新的定义。
    • 您需要重新启动使用 API 密钥运行的任务(在后面的步骤中完成)。
  2. 如果您已动态配置远程集群(通过集群设置 API)

    1. 检索当前的远程集群配置,并将其存储在安全的地方。如果您需要回滚,则以后可能需要它。使用集群设置 API

      resp = client.cluster.get_settings(
          filter_path="persistent.cluster.remote",
      )
      print(resp)
      response = client.cluster.get_settings(
        filter_path: 'persistent.cluster.remote'
      )
      puts response
      GET /_cluster/settings?filter_path=persistent.cluster.remote
    2. 通过将远程集群设置设置为 null 来删除现有的远程集群定义。
  3. 如果您已静态配置远程集群(通过 elasticsearch.yml),请从 elasticsearch.yml 复制 cluster.remote 设置,并将其存储在安全的地方。如果您需要回滚,则以后可能需要它们。
  4. 在本地集群的每个节点上

    1. 将之前在远程集群上生成的 ca.crt 文件复制到 config 目录,并将文件重命名为 remote-cluster-ca.crt
    2. 将以下配置添加到 elasticsearch.yml

      xpack.security.remote_cluster_client.ssl.enabled: true
      xpack.security.remote_cluster_client.ssl.certificate_authorities: [ "remote-cluster-ca.crt" ]
    3. 将之前在远程集群上创建的跨集群 API 密钥添加到密钥库

      ./bin/elasticsearch-keystore add cluster.remote.ALIAS.credentials

      ALIAS 替换为迁移之前用于跨集群操作的相同别名。出现提示时,输入之前在远程集群上创建的编码跨集群 API 密钥。

  5. 如果您已动态配置远程集群(通过集群设置 API)

    1. 重新启动本地集群以加载对密钥库和设置的更改。
    2. 重新添加远程集群。使用相同的远程集群别名,并将传输端口更改为远程集群端口。例如

      resp = client.cluster.put_settings(
          body={
              "persistent": {
                  "cluster": {
                      "remote": {
                          "my_remote": {
                              "mode": "proxy",
                              "proxy_address": "my.remote.cluster.com:9443",
                          }
                      }
                  }
              }
          },
      )
      print(resp)
      response = client.cluster.put_settings(
        body: {
          persistent: {
            cluster: {
              remote: {
                my_remote: {
                  mode: 'proxy',
                  proxy_address: 'my.remote.cluster.com:9443'
                }
              }
            }
          }
        }
      )
      puts response
      PUT /_cluster/settings
      {
        "persistent" : {
          "cluster" : {
            "remote" : {
              "my_remote" : { 
                "mode": "proxy",
                "proxy_address": "my.remote.cluster.com:9443" 
              }
            }
          }
        }
      }

      远程集群别名。使用与迁移之前相同的别名。

      远程集群地址和远程集群端口,默认为 9443

  6. 如果您已静态配置远程集群(通过 elasticsearch.yml

    1. 在本地集群的每个节点上,更新 elasticsearch.yml 中的 cluster.remote 设置。将端口更改为远程集群端口,默认为 9443
    2. 重新启动本地集群以加载对密钥库和设置的更改。
  7. 使用远程集群信息 API 验证本地集群是否已成功连接到远程集群

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

    API 响应应表明本地集群已连接到远程集群

    {
      "my_remote": {
        "connected": true, 
        "mode": "proxy",
        "proxy_address": "my.remote.cluster.com:9443",
        "server_name": "",
        "num_proxy_sockets_connected": 0,
        "max_proxy_socket_connections": 18,
        "initial_connect_timeout": "30s",
        "skip_unavailable": false,
        "cluster_credentials": "::es_redacted::" 
      }
    }

    远程集群已连接。

    如果存在,则表示远程集群已使用 API 密钥身份验证进行连接。

恢复跨集群操作编辑

恢复您之前停止的所有持久任务。任务应由迁移前创建任务的同一用户或 API 密钥重新启动。确保已使用所需的 remote_indices 权限更新了此用户或 API 密钥的角色。对于用户,任务会在启动时捕获调用者的凭据,并在该用户的安全上下文中运行。对于 API 密钥,重新启动任务将使用更新后的 API 密钥更新任务。

禁用基于证书的身份验证和授权编辑

仅当迁移在本地集群上已成功完成时,才继续执行此步骤。如果迁移失败,请 找出问题所在并尝试解决回滚

接下来,禁用基于证书的连接。您也可以选择撤销授权。

  1. 没有特定的设置来启用或禁用基于证书的跨集群连接,因为它与集群内节点到节点通信共享相同的传输协议。

    远程集群管理员阻止现有本地集群连接的一种方法是更改 TLS 信任。确切的步骤会有所不同,具体取决于集群的配置方式。一种通用的解决方案是 重新创建远程传输接口使用的 CA 和证书/密钥,以便本地或分布式的任何现有证书/密钥不再受信任。

    另一种解决方案是对传输接口应用 IP 过滤器,阻止来自集群外部的流量。

  2. (可选)删除远程集群上仅用于跨集群操作的任何角色。在基于 API 密钥的安全模型下,不再使用这些角色。

回滚编辑

如果需要回滚,请在本地集群上执行以下步骤

  1. 停止任何引用远程集群的持久任务。
  2. 通过将远程集群设置设置为 null 来删除远程集群定义。
  3. 从迁移期间更新的任何角色中删除 remote_indices 权限。
  4. 在每个节点上,从 elasticsearch.yml 中删除 remote_cluster_client.ssl.* 设置。
  5. 重新启动本地集群以将更改应用于密钥库和 elasticsearch.yml
  6. 在本地集群上,应用原始的远程集群设置。如果已静态配置远程集群连接(使用 elasticsearch.yml 文件),请重新启动集群。
  7. 使用 远程集群信息 API 验证本地集群是否已连接到远程集群。响应应包含 "connected": true 并且不包含 "cluster_credentials": "::es_redacted::"
  8. 重新启动您之前停止的任何持久任务。