Kerberos 身份验证插件

如果您使用 Kerberos 来保护您的网络环境,则可以使用 Kerberos 身份验证插件来保护 Solr 集群。

这允许 Solr 使用 Kerberos 服务主体和密钥表文件来验证 ZooKeeper 和 Solr 集群的节点(如果适用)之间的身份。Admin UI 的用户和所有客户端(如 SolrJ)在使用 UI 或向 Solr 发送请求之前也需要拥有有效票证。

SolrCloud、用户管理或单节点安装中支持 Kerberos 身份验证。

如果您将 Solr 与使用 Kerberos 保护的 Hadoop 集群一起使用,并打算将 Solr 索引存储在 HDFS 中,请参阅部分 Solr on HDFS 以了解为该目的配置 Solr 的其他步骤。本页上的说明仅适用于将使用 Kerberos 保护 Solr 的场景。如果您只需要将索引存储在经过 Kerberos 认证的 HDFS 系统中,请参阅在 HDFS 上运行 Solr 部分。

Solr 如何与 Kerberos 配合使用

在设置 Solr 以使用 Kerberos 时,配置已就绪,以便 Solr 使用服务主体或 Kerberos 用户名,该用户名已在密钥分发中心 (KDC) 中注册,以验证请求。配置定义服务主体名称和包含凭据的密钥表文件的位置。

与所有身份验证插件一样,Kerberos 身份验证配置存储在 security.json 中。此文件在部分 配置 security.json 中讨论。

服务主体和密钥表文件

每个 Solr 节点都必须有一个在密钥分发中心 (KDC) 中注册的服务主体。Kerberos 插件使用 SPNego 协商身份验证。

使用 HTTP/[email protected] 作为服务主体的示例

  • HTTP 指示此服务主体将用于验证的请求类型。服务主体中的 HTTP/ 是 SPNego 通过 HTTP 向 Solr 发送请求的必要条件。

  • host1 是托管 Solr 节点的机器的主机名。

  • YOUR-DOMAIN.ORG 是全组织的 Kerberos 领域。

同一主机上的多个 Solr 节点可能具有相同服务主体,因为主机名对它们来说是通用的。

除了服务主体之外,每个 Solr 节点都需要一个 keytab 文件,其中应包含所用服务主体的凭据。keytab 文件包含加密凭据,以支持在从 KDC 获取 Kerberos 票证时进行无密码登录。对于每个 Solr 节点,keytab 文件应保存在安全位置,并且不应与集群用户共享。

由于 Solr 集群需要节点间通信,因此每个节点还必须能够向其他节点发出启用 Kerberos 的请求。默认情况下,Solr 将相同服务主体和 keytab 用作节点间通信的“客户端主体”。你可以明确配置一个不同的客户端主体,但不建议这样做,并且以下示例中也没有介绍。

Kerberized ZooKeeper

在设置 kerberized SolrCloud 集群时,建议也为 ZooKeeper 启用 Kerberos 安全性。

在这种设置中,用于验证 ZooKeeper 请求的客户端主体也可以用于节点间通信。这样做的好处是不需要单独续订票证授予票证 (TGT),因为 Solr 使用的 ZooKeeper 客户端会负责此操作。要实现此目的,可以将单个 JAAS 配置(应用程序名称为 Client)用于 Kerberos 插件和 ZooKeeper 客户端。

请参阅下面的 ZooKeeper 配置 部分,了解在 Kerberos 模式下启动 ZooKeeper 的示例。

浏览器配置

为了让你的浏览器在启用 Kerberos 认证后能够访问 Solr 管理员 UI,它必须能够与 Kerberos 认证服务进行协商,以允许你访问。每个浏览器对它的支持方式不同,有些浏览器(如 Chrome)根本不支持它。如果你在启用 Kerberos 认证后尝试访问 Solr 管理员 UI 时看到 401 错误,则可能是你的浏览器尚未正确配置,不知道如何或在哪里协商认证请求。

有关如何设置浏览器的详细信息超出了本说明的范围;有关如何配置浏览器的详细信息,请咨询你的 Kerberos 系统管理员。

Kerberos 认证配置

咨询你的 Kerberos 管理员!

在尝试配置 Solr 以使用 Kerberos 认证之前,请查看下面概述的每个步骤,并就每个细节咨询你的本地 Kerberos 管理员,以确保你了解每个参数的正确值。很小的错误都可能导致 Solr 无法启动或无法正常运行,并且出了问题很难诊断。

Kerberos 插件的配置包含多个部分

  • 创建服务主体和密钥表文件

  • ZooKeeper 配置

  • 创建或更新 /security.json

  • 定义 jaas-client.conf

  • Solr 启动参数

我们将在下面介绍每个步骤。

使用主机名

要使用主机名而不是 IP 地址,请在 bin/solr.in.sh 中使用 SOLR_HOST 配置,或在 Solr 启动期间传递 -Dhost=<hostname> 系统参数。本指南使用 IP 地址。如果你指定了一个主机名,请根据需要用 Solr 主机名替换指南中的所有 IP 地址。

获取服务主体和密钥表

在配置 Solr 之前,请确保你在 KDC 服务器中为每个 Solr 主机和 ZooKeeper(如果尚未配置 ZooKeeper)准备了一个 Kerberos 服务主体,并生成一个密钥表文件,如下所示。

此示例假定主机名为 192.168.0.107,你的主目录为 /home/foo/。此示例应针对你自己的环境进行修改。

root@kdc:/# kadmin.local
Authenticating as principal foo/[email protected] with password.

kadmin.local:  addprinc HTTP/192.168.0.107
WARNING: no policy specified for HTTP/[email protected]; defaulting to no policy
Enter password for principal "HTTP/[email protected]":
Re-enter password for principal "HTTP/[email protected]":
Principal "HTTP/[email protected]" created.

kadmin.local:  ktadd -k /tmp/107.keytab HTTP/192.168.0.107
Entry for principal HTTP/192.168.0.107 with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/tmp/107.keytab.
Entry for principal HTTP/192.168.0.107 with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/tmp/107.keytab.
Entry for principal HTTP/192.168.0.107 with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/tmp/108.keytab.
Entry for principal HTTP/192.168.0.107 with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/tmp/107.keytab.

kadmin.local:  quit

将密钥表文件从 KDC 服务器的 /tmp/107.keytab 位置复制到 Solr 主机上的 /keytabs/107.keytab。对每个 Solr 节点重复此步骤。

如果你尚未设置 ZooKeeper 服务主体和密钥表,则可能需要采取类似的步骤。在这种情况下,下面的示例显示了 ZooKeeper 的一个不同的服务主体,因此可以将上述示例重复,其中 zookeeper/host1 作为其中一个节点的服务主体

ZooKeeper 配置

如果你正在使用已配置为使用 Kerberos 的 ZooKeeper,则可以跳过此处所示的与 ZooKeeper 相关的步骤。

由于 ZooKeeper 管理 SolrCloud 集群中节点之间的通信,因此它还必须能够对集群的每个节点进行身份验证。配置需要为 ZooKeeper 设置服务主体,定义 JAAS 配置文件并指示 ZooKeeper 使用这两个项目。

第一步是在 ZooKeeper 的 conf 目录中创建一个文件 java.env,并向其中添加以下内容,如下例所示

export JVMFLAGS="-Djava.security.auth.login.config=/etc/zookeeper/conf/jaas-client.conf"

JAAS 配置文件应包含以下参数。务必根据需要更改 principalkeyTab 路径。该文件必须位于上述步骤中定义的路径中,并使用指定的文件名。

Server {
 com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/keytabs/zkhost1.keytab"
  storeKey=true
  doNotPrompt=true
  useTicketCache=false
  debug=true
  principal="zookeeper/[email protected]";
};

最后,将以下行添加到 ZooKeeper 配置文件 zoo.cfg

authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
jaasLoginRenew=3600000

所有部分就位后,使用指向 JAAS 配置文件的以下参数启动 ZooKeeper

$ bin/zkServer.sh start -Djava.security.auth.login.config=/etc/zookeeper/conf/jaas-client.conf

创建 security.json

创建文件 security.json,其内容如下

{"authentication": {"class": "solr.KerberosPlugin"}}

然后使用 bin/solr zk 命令上传该文件

$ bin/solr zk cp ./security.json zk:security.json -z localhost:2181

如果您在单节点安装中使用 Solr,则需要创建 security.json 文件并将其放入 $SOLR_HOME 目录中。

如果您在 ZooKeeper 中已经有一个 /security.json 文件,请下载该文件,添加或修改身份验证部分,并使用 Solr 中提供的 ZooKeeper 实用程序 将其重新上传到 ZooKeeper。

定义 JAAS 配置文件

JAAS 配置文件定义用于身份验证的属性,例如服务主体和 keytab 文件的位置。还可以设置其他属性以确保票证缓存和其他功能。

可以复制以下示例并根据您的环境稍作修改。该文件的位置可以在服务器上的任何位置,但在启动 Solr 时会引用该文件,因此它必须在文件系统中可读。JAAS 文件可能包含多个部分以供不同的用户使用,但每个部分必须具有唯一名称,以便在每个应用程序中唯一引用它。

在以下示例中,我们创建了一个 JAAS 配置文件,其名称和路径为 /home/foo/jaas-client.conf。我们在下一部分中定义 Solr 启动参数时将使用此名称和路径。请注意,此处的客户端 主体与服务主体相同。这将用于对节点间请求和对 ZooKeeper 的请求进行身份验证。请确保使用正确的 主体主机名和 keyTab 文件路径。

Client {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/keytabs/107.keytab"
  storeKey=true
  useTicketCache=true
  debug=true
  principal="HTTP/[email protected]";
};

此文件的首行定义节名称,该名称将与下面定义的 solr.kerberos.jaas.appname 参数一起使用。

我们关注的主要属性是 keyTabprincipal 属性,但可能还需要其他属性来满足你的环境要求。用于 Krb5LoginModule(正在使用的类,并在上面的第二行中调用)的 javadocs 提供了可用属性的良好概述,但为了参考,上面示例中使用的属性在此处进行了说明

  • useKeyTab:此布尔属性定义我们是否应使用 keytab 文件(在本例中为 true)。

  • keyTab:此 JAAS 配置文件部分所针对的主体的 keytab 文件的位置和名称。路径应包含在双引号中。

  • storeKey:此布尔属性允许将密钥存储在用户的私有凭据中。

  • useTicketCache:此布尔属性允许从票证高速缓存中获取票证。

  • debug:此布尔属性将输出调试消息以帮助进行故障排除。

  • principal:要使用的服务主体的名称。

Solr 启动参数

在启动 Solr 时,需要传递以下特定于主机的参数。这些参数可以通过使用 bin/solr 启动命令在命令行中传递(有关如何传递系统参数的详细信息,请参阅 Solr 控制脚本参考),或根据你的操作系统在 bin/solr.in.shbin/solr.in.cmd 中进行定义。

solr.kerberos.name.rules

可选

默认值:DEFAULT

用于将 Kerberos 主体映射到短名称。名称规则示例:RULE:[1:$1@$0](.*EXAMPLE.COM)s/@.*//

solr.kerberos.name.rules.mechanism

可选

默认值:hadoop

用于将 Kerberos 主体映射到短名称的机制。这可以是 hadoopmit

solr.kerberos.cookie.domain

必需

默认值:无

用于颁发 Cookie,应包含 Solr 节点的主机名。

solr.kerberos.cookie.portaware

可选

默认值:false

当设置为 true 时,Cookie 会根据主机和端口进行区分,而不是根据不区分端口的标准 Cookie。如果同一主机上托管了多个 Solr 节点,则应进行此设置。

solr.kerberos.principal

必需

默认值:无

服务主体。

solr.kerberos.keytab

必需

默认值:无

包含服务主体凭据的 Keytab 文件路径

solr.kerberos.jaas.appname

可选

默认值:Client

JAAS 配置文件中的应用名称(部分名称),用于节点间通信。默认值也用于 ZooKeeper 身份验证。如果 ZooKeeper 和 Solr 使用不同的用户,则它们需要在 JAAS 配置文件中具有单独的部分。

java.security.auth.login.config

必需

默认值:无

用于为 Solr 客户端配置节点间通信的 JAAS 配置文件的路径。

以下是一个可以添加到 bin/solr.in.sh 的示例。请务必更改此示例以使用正确的 hostname 和 keytab 文件路径。

SOLR_AUTH_TYPE="kerberos"
SOLR_AUTHENTICATION_OPTS="-Djava.security.auth.login.config=/home/foo/jaas-client.conf -Dsolr.kerberos.cookie.domain=192.168.0.107 -Dsolr.kerberos.cookie.portaware=true -Dsolr.kerberos.principal=HTTP/[email protected] -Dsolr.kerberos.keytab=/keytabs/107.keytab"
使用 AES-256 加密的 KDC

如果 KDC 使用 AES-256 加密,则需要在 Kerberos 化 Solr 与 KDC 交互之前将 Java 加密扩展 (JCE) 无限强度管辖区策略文件添加到 JRE 中。

当你在 Solr 日志中看到类似以下内容的错误时,你就会知道这一点:“KrbException: 不支持/未启用带有 HMAC SHA1-96 的 AES256 CTS 模式加密类型”。

用下载包中的新 local_policy.jar 替换 JAVA_HOME/jre/lib/security/ 中现有的 local_policy.jar,然后重新启动 Solr 节点。

使用委派令牌

可以将 Kerberos 插件配置为使用委派令牌,这允许应用程序重用最终用户或其他应用程序的身份验证。

有几个 Solr 用例可能对此有帮助

  • 使用分布式客户端(例如 MapReduce),其中每个客户端可能无法访问用户的凭据。

  • 当 Kerberos 服务器上的负载较高时。委派令牌可以减少负载,因为它们在第一次请求后不会访问服务器。

  • 如果需要将请求或权限委派给其他用户。

要启用委派令牌,必须定义几个参数。这些参数可以通过 bin/solr 启动命令 Solr 控制脚本参考 在命令行中传递,或根据你的操作系统在 bin/solr.in.shbin/solr.in.cmd 中定义。

solr.kerberos.delegation.token.enabled

可选

默认值:false

设置为 true 以启用委派令牌。如果你想启用令牌,则需要此参数。

solr.kerberos.delegation.token.kind

可选

默认值:solr-dt

委派令牌的类型。目前,唯一可用的选项是默认值。

solr.kerberos.delegation.token.validity

可选

默认值:36000

委派令牌有效的时间(以秒为单位)。

solr.kerberos.delegation.token.signer.secret.provider

可选

默认值:zookeeper

委派令牌信息在内部存储的位置。默认值为 zookeeper,该值必须是委派令牌在 Solr 服务器之间正常运行(在 SolrCloud 模式下运行时)的位置。目前,没有其他可用的选项。

solr.kerberos.delegation.token.signer.secret.provider.zookeper.path

可选

默认值:无

存储机密提供程序信息的 ZooKeeper 路径。其形式为路径 + /security/token。该路径可以包括 chroot,如果您未使用 chroot,则可以省略 chroot。此示例包括 chroot:server1:9983,server2:9983,server3:9983/solr/security/token

solr.kerberos.delegation.token.secret.manager.znode.working.path

可选

默认值:无

存储令牌信息的 ZooKeeper 路径。其形式为路径 + /security/zkdtsm。该路径可以包括 chroot,如果您未使用 chroot,则可以省略 chroot。此示例包括 chroot:server1:9983,server2:9983,server3:9983/solr/security/zkdtsm

启动 Solr

配置完成后,您可以使用 bin/solr 脚本启动 Solr,如下面的示例所示,该示例仅适用于 SolrCloud 模式中的用户。

此示例假定您已使用适当的值修改了 bin/solr.in.shbin/solr.in.cmd,但如果您未修改,则需要将系统参数与启动命令一起传递。请注意,您还需要根据 ZooKeeper 节点的位置自定义 -z 属性。

$ bin/solr -c -z server1:2181,server2:2181,server3:2181/solr
如果您已在 solr.in.sh/solr.in.cmd 中定义了 ZK_HOST(请参阅 更新 Solr 包含文件),则可以从上述命令中省略 -z <zk 主机字符串>

测试配置

  1. 使用您的用户名执行 kinit。例如,kinit [email protected]

  2. 尝试使用 curl 访问 Solr。您应该会得到一个成功的响应。

    $ curl --negotiate -u : "http://192.168.0.107:8983/solr/"

将 SolrJ 与 Kerberos 化的 Solr 配合使用

要在 SolrJ 应用程序中使用 Kerberos 身份验证,您需要在创建 SolrClient 之前添加以下两行代码

System.setProperty("java.security.auth.login.config", "/home/foo/jaas-client.conf");
HttpClientUtil.setHttpClientBuilder(new Krb5HttpClientBuilder().getBuilder());

您需要在上述 JAAS 客户端配置文件中为客户端指定一个 Kerberos 服务主体和一个对应的密钥表。此主体应与我们为 Solr 创建的服务主体不同。

以下是一个示例

SolrJClient {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/keytabs/foo.keytab"
  storeKey=true
  useTicketCache=true
  debug=true
  principal="[email protected]";
};

使用 SolrJ 的委派令牌

SolrJ 也支持委派令牌,具体方式如下

  • DelegationTokenRequestDelegationTokenResponse 可用于获取、取消和续订委派令牌。

  • HttpSolrClient.Builder 包含一个 withKerberosDelegationToken 函数,用于创建使用委派令牌进行身份验证的 HttpSolrClient。

获取委派令牌的示例代码

private String getDelegationToken(final String renewer, final String user, HttpSolrClient solrClient) throws Exception {
    DelegationTokenRequest.Get get = new DelegationTokenRequest.Get(renewer) {
      @Override
      public SolrParams getParams() {
        ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
        params.set("user", user);
        return params;
      }
    };
    DelegationTokenResponse.Get getResponse = get.process(solrClient);
    return getResponse.getDelegationToken();
  }

要创建一个使用委派令牌的 HttpSolrClient

HttpSolrClient client = new HttpSolrClient.Builder("http://localhost:8983/solr").withKerberosDelegationToken(token).build();

要创建一个使用委派令牌的 CloudSolrClient

CloudSolrClient client = new CloudSolrClient.Builder(Collections.singletonList("localhost:2181"),Optional.empty())
                .withLBHttpSolrClientBuilder(new LBHttpSolrClient.Builder()
                    .withResponseParser(client.getParser())
                    .withHttpSolrClientBuilder(
                        new HttpSolrClient.Builder()
                            .withKerberosDelegationToken(token)
                    ))
                        .build();

Hadoop 的委派令牌响应采用 JSON 映射格式。DelegationTokenResponse 中提供了该响应的解析器。其他响应解析器可能无法很好地处理 Hadoop 响应。