Kerberos 身份验证插件
如果您使用 Kerberos 来保护您的网络环境,则可以使用 Kerberos 身份验证插件来保护 Solr 集群。
这允许 Solr 使用 Kerberos 服务主体和 keytab 文件与 ZooKeeper 以及 Solr 集群的节点之间(如果适用)进行身份验证。Admin UI 的用户和所有客户端(例如 SolrJ)也需要在能够使用 UI 或向 Solr 发送请求之前拥有有效的票证。
SolrCloud、用户管理或单节点安装中均支持 Kerberos 身份验证。
如果您正在使用带有 Kerberos 保护的 Hadoop 集群中的 Solr,并打算将 Solr 索引存储在 HDFS 中,请参阅 HDFS 上的 Solr 部分,了解为该目的配置 Solr 的其他步骤。此页面上的说明仅适用于 Solr 将使用 Kerberos 进行保护的场景。如果您只需要将索引存储在 Kerberized HDFS 系统中,请参阅在 HDFS 上运行 Solr 部分。 |
Solr 如何与 Kerberos 协同工作
在设置 Solr 以使用 Kerberos 时,会进行配置,以便 Solr 使用服务主体或 Kerberos 用户名,该用户名在密钥分发中心 (KDC) 注册以验证请求。这些配置定义了服务主体名称和包含凭据的 keytab 文件的位置。
与所有身份验证插件一样,Kerberos 身份验证配置存储在 security.json
中。此文件在 配置 security.json 部分中讨论。
服务主体和 Keytab 文件
每个 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 使用与“客户端主体”相同的服务主体和密钥表进行节点间通信。您可以显式配置不同的客户端主体,但不建议这样做,并且以下示例中不涉及。
启用 Kerberos 的 ZooKeeper
在设置启用 Kerberos 的 SolrCloud 集群时,建议也为 ZooKeeper 启用 Kerberos 安全性。
在这种设置中,用于向 ZooKeeper 验证请求的客户端主体也可以共享用于节点间通信。这样做的好处是不需要单独更新票据授予票据 (TGT),因为 Solr 使用的 ZooKeeper 客户端会处理此问题。为了实现这一点,Kerberos 插件和 ZooKeeper 客户端可以使用单个 JAAS 配置(应用程序名称为 Client)。
有关在 Kerberos 模式下启动 ZooKeeper 的示例,请参见下面的ZooKeeper 配置部分。
Kerberos 身份验证配置
咨询您的 Kerberos 管理员!
在尝试配置 Solr 以使用 Kerberos 身份验证之前,请查看下面概述的每个步骤,并就每个详细信息咨询您当地的 Kerberos 管理员,以确保您知道每个参数的正确值。小错误可能会导致 Solr 无法启动或无法正常运行,并且很难诊断。 |
Kerberos 插件的配置有几个部分
-
创建服务主体和密钥表文件
-
ZooKeeper 配置
-
创建或更新
/security.json
-
定义
jaas-client.conf
-
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 配置文件应包含以下参数。请务必根据需要更改 principal
和 keyTab
路径。该文件必须位于上述步骤中定义的路径中,并指定文件名。
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 中已存在 |
定义 JAAS 配置文件
JAAS 配置文件定义了用于身份验证的属性,例如服务主体和密钥表文件的位置。还可以设置其他属性,以确保票据缓存和其他功能。
可以复制以下示例,并根据您的环境稍作修改。该文件的位置可以在服务器上的任何位置,但是在启动 Solr 时会引用该文件,因此它必须在文件系统上可读。JAAS 文件可能包含多个不同用户的部分,但是每个部分都必须具有唯一的名称,以便可以在每个应用程序中唯一引用它。
在下面的示例中,我们创建了一个 JAAS 配置文件,名称和路径为 /home/foo/jaas-client.conf
。在下一部分中定义 Solr 启动参数时,我们将使用此名称和路径。请注意,此处的客户端 principal
与服务主体相同。这将用于验证节点间请求和对 ZooKeeper 的请求。请确保使用正确的主机名 principal
和 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
参数一起使用。
我们主要关注的属性是 keyTab
和 principal
属性,但是您的环境可能还需要其他属性。Krb5LoginModule 的 javadocs(正在使用并在上面第二行中调用的类)提供了可用属性的良好概述,但是为了方便参考,此处解释了上述示例中正在使用的属性
-
useKeyTab
:此布尔属性定义是否应使用密钥表文件(在本例中为true
)。 -
keyTab
:此 JAAS 配置文件部分所针对的主体的密钥表文件的位置和名称。路径应该用双引号括起来。 -
storeKey
:此布尔属性允许将密钥存储在用户的私有凭据中。 -
useTicketCache
:此布尔属性允许从票据缓存中获取票据。 -
debug
:此布尔属性将输出调试消息以帮助进行故障排除。 -
principal
:要使用的服务主体的名称。
Solr 启动参数
在启动 Solr 时,需要传递以下特定于主机的参数。这些参数可以使用 bin/solr
start 命令在命令行中传递(有关如何传递系统参数的详细信息,请参阅Solr 控制脚本参考),或者在 bin/solr.in.sh
或 bin/solr.in.cmd
中定义,具体取决于您的操作系统。
solr.kerberos.name.rules
-
可选
默认值:
DEFAULT
用于将 Kerberos 主体映射到短名称。名称规则的示例:
RULE:[1:$1@$0](.*EXAMPLE.COM)s/@.*//
。 solr.kerberos.name.rules.mechanism
-
可选
默认值:
hadoop
用于将 Kerberos 主体映射到短名称的机制。可以是
hadoop
或mit
。 solr.kerberos.cookie.domain
-
必需
默认值:无
用于颁发 Cookie,应具有 Solr 节点的主机名。
solr.kerberos.cookie.portaware
-
可选
默认值:
false
设置为
true
时,Cookie 会根据主机和端口进行区分,而不是不感知端口的标准 Cookie。如果同一主机上托管了多个 Solr 节点,则应进行设置。 solr.kerberos.principal
-
必需
默认值:无
服务主体。
solr.kerberos.keytab
-
必需
默认值:无
包含服务主体凭据的密钥表文件路径
solr.kerberos.jaas.appname
-
可选
默认值:
Client
JAAS 配置文件中的应用程序名称(节名称),这是节点间通信所必需的。默认值也用于 ZooKeeper 身份验证。如果 ZooKeeper 和 Solr 使用不同的用户,则它们需要在 JAAS 配置文件中具有单独的部分。
java.security.auth.login.config
-
必需
默认值:无
用于为节点间通信配置 Solr 客户端的 JAAS 配置文件的路径。
以下是一个可以添加到 bin/solr.in.sh
的示例。请务必更改此示例以使用正确的主机名和密钥表文件路径。
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: Encryption type AES256 CTS mode with HMAC SHA1-96 is not supported/enabled”。 对于 Java 1.8,可在此处获取:http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html。 将 |
使用委托令牌
可以配置 Kerberos 插件以使用委托令牌,这允许应用程序重用最终用户或其他应用程序的身份验证。
Solr 中有几种可以使用此功能的场景:
-
使用分布式客户端(例如 MapReduce),每个客户端可能无法访问用户的凭据。
-
当 Kerberos 服务器上的负载很高时。委托令牌可以减少负载,因为它们在第一次请求后不会访问服务器。
-
如果需要将请求或权限委派给另一个用户。
要启用委托令牌,必须定义几个参数。这些参数可以通过 bin/solr
启动命令的命令行传递(请参阅Solr 控制脚本参考),或者在 bin/solr.in.sh
或 bin/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 模式下运行时)工作的 Location。目前没有其他选项可用。 solr.kerberos.delegation.token.signer.secret.provider.zookeper.path
-
可选
默认值:无
存储密钥提供程序信息的 ZooKeeper 路径。其格式为路径 +
/security/token
。该路径可以包含 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:server1:9983,server2:9983,server3:9983/solr/security/zkdtsm
。
启动 Solr
配置完成后,您可以使用 bin/solr
脚本启动 Solr,如下例所示,该示例仅适用于 SolrCloud 模式下的用户。
此示例假设您已使用正确的值修改了 bin/solr.in.sh
或 bin/solr.in.cmd
,但如果您没有修改,则需要将系统参数与启动命令一起传递。请注意,您还需要根据 ZooKeeper 节点的位置自定义 -z
属性。
$ bin/solr start -c -z server1:2181,server2:2181,server3:2181/solr
如果您已在 solr.in.sh /solr.in.cmd 中定义了 ZK_HOST (请参阅更新 Solr 包含文件),则可以从上述命令中省略 -z <zk host string> 。 |
测试配置
-
使用您的用户名执行
kinit
。例如,kinit [email protected]
。 -
尝试使用
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 服务主体和相应的 keytab。此主体应与我们为 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 也支持委托令牌,方式如下:
-
DelegationTokenRequest
和DelegationTokenResponse
可用于获取、取消和续订委托令牌。 -
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("https://127.0.0.1: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 map 格式。 |