ZooKeeper 访问控制
本节介绍如何在 Solr 中使用 ZooKeeper 访问控制列表 (ACL)。
有关 ZooKeeper ACL 的信息,请参阅ZooKeeper ACL 文档。
关于 ZooKeeper ACL
SolrCloud 使用 ZooKeeper 进行共享信息和协调。
本节介绍如何配置 Solr,以便在其创建的 ZooKeeper 内容中添加更具限制性的 ACL,以及如何告知 Solr 访问 ZooKeeper 中内容所需的凭据。如果您想在 ZooKeeper 节点中使用 ACL,则必须激活此功能;默认情况下,Solr 的行为是对所有地方使用开放式不安全 ACL,并且不使用任何凭据。
存储在 ZooKeeper 中的内容对于 SolrCloud 集群的运行至关重要。开放访问 ZooKeeper 上的 SolrCloud 内容可能会导致各种问题。例如
-
更改配置可能会导致 Solr 失败或以非预期的方式运行。
-
将集群状态信息更改为错误或不一致的内容很可能导致 SolrCloud 集群行为异常。
-
向 Overseer 添加要执行的删除集合作业将导致从集群中删除数据。
如果您向您不信任的实体授予对 ZooKeeper 集群的访问权限,或者如果您想降低因以下原因导致的错误操作的风险,则可能需要启用 Solr 的 ZooKeeper ACL
-
找到进入您系统的恶意软件。
-
其他系统使用相同的 ZooKeeper 集群(可能会意外地完成“不好的事情”)。
如果您认为 ZooKeeper 中存在并非每个人都应该知道的内容,那么您甚至可能想要限制读取访问权限。或者,您可能只是在总体上按需了解情况。
保护 ZooKeeper 本身可能意味着许多不同的事情。**本节是关于保护 ZooKeeper 中的 Solr 内容**。ZooKeeper 内容基本上持久化存储在磁盘上,并(部分)存储在 ZooKeeper 进程的内存中。**本节不是关于保护存储级别或 ZooKeeper 进程级别的 ZooKeeper 数据**——那是 ZooKeeper 要处理的事情。
但是,这些内容也可以通过 ZooKeeper API 提供给“外部”。外部进程可以连接到 ZooKeeper 并创建/更新/删除/读取内容。例如,SolrCloud 集群中的 Solr 节点想要创建/更新/删除/读取,并且 SolrJ 客户端想要从集群读取。创建/更新内容的外部进程有责任在内容上设置 ACL。ACL 描述谁可以读取、更新、删除、创建等。ZooKeeper 中的每条信息(znode/内容)都有自己的一组 ACL,并且不可能继承或共享。Solr 中的默认行为是在其创建的所有内容上添加一个 ACL——一个允许任何人执行任何操作的 ACL(在 ZooKeeper 术语中,这称为“开放式不安全 ACL”)。
Solr 到 Zookeeper ACL 的工作流程
-
Solr 到 Zookeeper 的凭据和 ACL 通过 3 个接口进行控制:
ZkCredentialsInjector
、ZkCredentialsProvider
和ZkACLProvider
。 -
实现这 3 个接口的类通过系统属性传递给 Solr,系统属性的名称在
solr.xml
中定义(详见 配置 solr.xml)。以下是默认的属性名称:zkCredentialsInjector
、zkACLProvider
和zkCredentialsProvider
。详情请参阅以下章节。 -
数据流如下:凭据源 →
ZkCredentialsInjector
→ZkCredentialsProvider/ZkACLProvider
→ Zookeeper。
ZkCredentialsInjector
从某个源获取凭据,然后将其注入到 ZkCredentialsProvider
和 ZkACLProvider
中。“源”可以是系统属性、文件、密钥管理器或任何其他本地或远程源。
-
支持两组角色:
-
ALL
用户:允许执行所有操作的用户(对应于CREATE
、READ
、WRITE
、DELETE
和ADMIN
的所有权限)。 -
READ
用户:只允许执行读取操作的只读用户。
-
-
我们始终通过限制为两个用户(一个管理员用户和一个只读用户)来保护对内容的访问 - 并且我们始终使用与同一管理员用户相对应的凭据进行连接,基本上是为了我们可以对我们自己创建的内容/znode 进行任何操作。
您可以将只读凭据提供给 SolrCloud 集群的“客户端” - 例如,供 SolrJ 客户端使用。他们将能够读取运行功能正常的 SolrJ 客户端所必需的任何内容,但他们将无法修改 ZooKeeper 中的任何内容。
如何启用 ACL
-
我们希望能够:
-
控制 Solr 用于其 ZooKeeper 连接的凭据。凭据用于获取在 ZooKeeper 中执行操作的权限。
-
控制 Solr 将添加到其在 ZooKeeper 中创建的 znode(ZooKeeper 文件/文件夹)的 ACL。
-
从“外部”控制它,这样您就不必修改和/或重新编译 Solr 代码来启用此功能。
-
Solr 节点、客户端和工具(例如 SolrCLI)始终使用名为 SolrZkClient
的 Java 类来处理它们的 ZooKeeper 相关事务。此处描述的解决方案的实现全部是关于更改 SolrZkClient
。如果您在应用程序中使用 SolrZkClient
,则以下描述也适用于您的应用程序。
-
控制凭据和 ACL 分为 3 个步骤:设置一个
ZkCredentialsInjector
,它从某个源读取凭据,然后将它们注入到 Solr 用于连接 Zookeeper 的ZkCredentialsProvider
中。ZkACLProvider
使用相同的凭据来设置 ACL。
我们将在给出一些现成的示例之前详细描述这 3 个步骤。
-
设置
ZkCredentialsInjector
。 -
设置
ZkCredentialsProvider
。 -
设置
ZkACLProvider
。
设置凭据注入器
-
凭据注入器从外部源获取凭据,并将其注入到 Solr 中。
-
您可以通过在
solr.xml
的<solrcloud>
部分中配置zkCredentialsInjector
属性,使其指向实现ZkCredentialsInjector
接口的类(在类路径上)的名称来控制将注入哪些凭据。
Solr 发行版中的server/solr/solr.xml
文件定义了 `zkCredentialsInjector`,使其采用同名的zkCredentialsInjector
系统属性的值(如果已定义,例如,通过取消注释solr.in.sh/.cmd
中的SOLR_ZK_CREDS_AND_ACLS
环境变量定义 - 请参阅下文),否则,默认为DefaultZkCredentialsInjector
实现。
-
开箱即用的凭据注入器实现
-
Solr 附带以下
ZkCredentialsInjectors
:-
org.apache.solr.common.cloud.DefaultZkCredentialsInjector
:其getCredentials()
方法返回长度为零的列表,或“未使用凭据”。这是默认设置。 -
org.apache.solr.common.cloud.VMParamsZkCredentialsInjector
:用户名和密码由系统属性名称定义:`zkDigestUsername` 和zkDigestPassword
。如果同时提供了用户名和密码,则此凭据集将添加到getCredentials()
返回的凭据列表中。-
如果上述凭据集未添加到列表中,则此实现将回退到默认行为,并使用
DefaultZkCredentialsInjector
中的(空)凭据列表。 -
或者,您可以设置
zkDigestCredentialsFile
系统属性以从文件加载zkDigestUsername
和zkDigestPassword
,而不是将凭据公开为系统属性。提供的文件必须是 Java 属性文件,并且包含zkDigestUsername
和zkDigestPassword
属性。 -
用法(请参阅本页后面的完整示例)
-
-
-DzkCredentialsInjector=org.apache.solr.common.cloud.VMParamsZkCredentialsInjector -DzkDigestUsername=admin-user -DzkDigestPassword=CHANGEME-ADMIN-PASSWORD -DzkDigestReadonlyUsername=readonly-user -DzkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD # Or using a Java property file containing the credentials: -DzkCredentialsInjector=org.apache.solr.common.cloud.VMParamsZkCredentialsInjector -DzkDigestCredentialsFile=SOLR_HOME_DIR/server/etc/zookeepercredentials.properties
-
您可以通过实现
ZkCredentialsInjector
并使用zkCredentialsInjector
名称通过系统属性传递它来创建您自己的凭据注入器。
-DzkCredentialsInjector=fully.qualified.class.CustomInjectorClassName
注入凭据后,它们将在 ZkCredentialsProvider
中使用。
设置凭据提供程序
ZkCredentialsProvider
从 ZkCredentialsInjector
获取凭据,并使用它们连接到 Zookeeper。
-
您可以通过在
solr.xml
的<solrcloud>
部分中配置zkCredentialsProvider
属性,使其指向实现ZkCredentialsProvider
接口的类(在类路径上)的名称来控制将使用哪些凭据。
Solr 发行版中的server/solr/solr.xml
文件定义了 `zkCredentialsProvider`,使其采用同名的zkCredentialsProvider
系统属性的值(如果已定义,例如,通过取消注释solr.in.sh/.cmd
中的SOLR_ZK_CREDS_AND_ACLS
环境变量定义 - 请参阅下文),否则,默认为DefaultZkCredentialsProvider
实现。
开箱即用的凭据实现
您始终可以自己实现,但 Solr 提供了两种实现:
-
无凭据
org.apache.solr.common.cloud.DefaultZkCredentialsProvider
:其 getCredentials()
返回长度为零的列表,或“未使用凭据”。这是默认设置。
-
基于
digest
方案的凭据提供程序
org.apache.solr.common.cloud.DigestZkCredentialsProvider
:使用的方案是 digest
,它从指定的 ZkCredentialsInjector
获取 ALL
用户凭据(perms=all)。
如果未定义具有 ALL
用户(提供用户名和密码)的 ZkCredentialsInjector
,它将回退到默认行为,并使用 DefaultZkCredentialsProvider
中的(空)凭据列表。
设置 ACL 提供程序
-
您可以通过在
solr.xml
的<solrcloud>
部分中配置zkACLProvider
属性,使其指向实现ZkACLProvider
接口的类(在类路径上)的名称来控制将添加哪些 ACL。
Solr 发行版中的server/solr/solr.xml
文件定义了 `zkACLProvider`,使其采用同名的zkACLProvider
系统属性的值(如果已定义,例如,通过取消注释solr.in.sh/.cmd
中的SOLR_ZK_CREDS_AND_ACLS
环境变量定义 - 请参阅下文),否则,默认为DefaultZkACLProvider
实现。
开箱即用的 ACL 实现
您始终可以自己实现,但 Solr 附带:
-
org.apache.solr.common.cloud.DefaultZkACLProvider
:它为所有zNodePath
返回长度为 1 的列表。列表中的单个 ACL 条目是“open-unsafe”。这是默认设置。 -
org.apache.solr.common.cloud.DigestZkACLProvider
:这使您可以使用定义的ZkCredentialsInjector
定义 ACL。其getACLsToAdd()
实现将仅将管理员 ACL 应用于由SecurityAwareZkACLProvider
定义的预定义敏感路径(/security.json
和/security/*
),并将管理员和用户 ACL 都应用于其余内容。all
和read
用户通过本页前面描述的ZkCredentialsInjector
注入。 -
org.apache.solr.common.cloud.SaslZkACLProvider
:需要 SASL 身份验证。当使用 SASL 时,为系统属性solr.authorization.superuser
(默认值:`solr`)中指定的用户提供所有权限,并为其他任何人提供读取权限。专为已设置配置且不会修改,或者通过 Solr API 控制配置更改的设置而设计。此提供程序对于在 Kerberos 环境中进行管理非常有用。在这种环境中,管理员希望 Solr 使用 SASL 向 ZooKeeper 进行身份验证,因为这是通过 Kerberos 向 ZooKeeper 进行身份验证的唯一方法。 -
如果上述任何 ACL 都未添加到列表中,则默认情况下将使用
DefaultZkACLProvider
的(空)ACL 列表。
示例
以下示例适用于 digest
方案。
<str name="zkCredentialsInjector">${zkCredentialsInjector:org.apache.solr.common.cloud.DefaultZkCredentialsInjector}</str>
通过系统属性
-
ZK 凭据通过系统属性传递,属性名称为
DzkDigestUsername
、DzkDigestPassword
、DzkDigestReadonlyUsername
和DzkDigestReadonlyPassword
。
-
*nix
-
Windows
# Settings for ZK ACL
SOLR_ZK_CREDS_AND_ACLS="-DzkACLProvider=org.apache.solr.common.cloud.DigestZkACLProvider \
-DzkCredentialsProvider=org.apache.solr.common.cloud.DigestZkCredentialsProvider \
-DzkCredentialsInjector=org.apache.solr.common.cloud.VMParamsZkCredentialsInjector \
-DzkDigestUsername=admin-user -DzkDigestPassword=CHANGEME-ADMIN-PASSWORD \
-DzkDigestReadonlyUsername=readonly-user -DzkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD"
SOLR_OPTS="$SOLR_OPTS $SOLR_ZK_CREDS_AND_ACLS"
REM Settings for ZK ACL
set SOLR_ZK_CREDS_AND_ACLS=-DzkACLProvider=org.apache.solr.common.cloud.DigestZkACLProvider ^
-DzkCredentialsProvider=org.apache.solr.common.cloud.DigestZkCredentialsProvider ^
-DzkCredentialsInjector=org.apache.solr.common.cloud.VMParamsZkCredentialsInjector ^
-DzkDigestUsername=admin-user -DzkDigestPassword=CHANGEME-ADMIN-PASSWORD ^
-DzkDigestReadonlyUsername=readonly-user -DzkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD
set SOLR_OPTS=%SOLR_OPTS% %SOLR_ZK_CREDS_AND_ACLS%
通过文件
-
创建一个 Java 属性文件,例如名为
zookeepercredentials.properties
,其中包含以下格式的凭据:
zkDigestUsername=admin-user zkDigestPassword=CHANGEME-ADMIN-PASSWORD zkDigestReadonlyUsername=readonly-user zkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD
-
通过系统属性传递文件路径
-
*nix
-
Windows
# Settings for ZK ACL
SOLR_ZK_CREDS_AND_ACLS="-DzkACLProvider=org.apache.solr.common.cloud.DigestZkACLProvider \
-DzkCredentialsProvider=org.apache.solr.common.cloud.DigestZkCredentialsProvider \
-DzkCredentialsInjector=org.apache.solr.common.cloud.VMParamsZkCredentialsInjector \
-DzkDigestCredentialsFile=SOLR_HOME_DIR/server/etc/zookeepercredentials.properties"
SOLR_OPTS="$SOLR_OPTS $SOLR_ZK_CREDS_AND_ACLS"
REM Settings for ZK ACL
set SOLR_ZK_CREDS_AND_ACLS=-DzkACLProvider=org.apache.solr.common.cloud.DigestZkACLProvider ^
-DzkCredentialsProvider=org.apache.solr.common.cloud.DigestZkCredentialsProvider ^
-DzkCredentialsInjector=org.apache.solr.common.cloud.VMParamsZkCredentialsInjector ^
-DzkDigestCredentialsFile=SOLR_HOME_DIR/server/etc/zookeepercredentials.properties
set SOLR_OPTS=%SOLR_OPTS% %SOLR_ZK_CREDS_AND_ACLS%
通过自定义凭据注入器
-
或者,您可以通过实现
ZkCredentialsInjector
并使用 DzkCredentialsInjector 变量名通过系统属性传递它来创建您自己的凭据注入器。
-
*nix
-
Windows
# Settings for ZK ACL
SOLR_ZK_CREDS_AND_ACLS="-DzkACLProvider=org.apache.solr.common.cloud.DigestZkACLProvider \
-DzkCredentialsProvider=org.apache.solr.common.cloud.DigestZkCredentialsProvider \
-DzkCredentialsInjector=fully.qualified.class.CustomInjectorClassName"
SOLR_OPTS="$SOLR_OPTS $SOLR_ZK_CREDS_AND_ACLS"
REM Settings for ZK ACL
set SOLR_ZK_CREDS_AND_ACLS=-DzkACLProvider=org.apache.solr.common.cloud.DigestZkACLProvider ^
-DzkCredentialsProvider=org.apache.solr.common.cloud.DigestZkCredentialsProvider ^
-DzkCredentialsInjector=fully.qualified.class.CustomInjectorClassName
set SOLR_OPTS=%SOLR_OPTS% %SOLR_ZK_CREDS_AND_ACLS%
Solr CLI 中的 ZooKeeper ACL
这些 Solr 脚本可以通过设置适当的系统属性来启用 ZooKeeper ACL 的使用。
-
使用 VMParamsZkCredentialsInjector 的示例
取消注释以下内容,并将密码替换为您选择的密码,以便在以下文件中启用参数和 ACL 凭据提供程序
-
*nix
-
Windows
# Settings for ZK ACL
#SOLR_ZK_CREDS_AND_ACLS="-DzkACLProvider=org.apache.solr.common.cloud.DigestZkACLProvider \
# -DzkCredentialsProvider=org.apache.solr.common.cloud.DigestZkCredentialsProvider \
# -DzkCredentialsInjector=org.apache.solr.common.cloud.VMParamsZkCredentialsInjector \
# -DzkDigestUsername=admin-user -DzkDigestPassword=CHANGEME-ADMIN-PASSWORD \
# -DzkDigestReadonlyUsername=readonly-user -DzkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD"
#SOLR_OPTS="$SOLR_OPTS $SOLR_ZK_CREDS_AND_ACLS"
REM Settings for ZK ACL
REM set SOLR_ZK_CREDS_AND_ACLS=-DzkACLProvider=org.apache.solr.common.cloud.DigestZkACLProvider ^
REM -DzkCredentialsProvider=org.apache.solr.common.cloud.DigestZkCredentialsProvider ^
REM -DzkCredentialsInjector=org.apache.solr.common.cloud.VMParamsZkCredentialsInjector ^
REM -DzkDigestUsername=admin-user -DzkDigestPassword=CHANGEME-ADMIN-PASSWORD ^
REM -DzkDigestReadonlyUsername=readonly-user -DzkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD
REM set SOLR_OPTS=%SOLR_OPTS% %SOLR_ZK_CREDS_AND_ACLS%
更改 ACL 方案
在操作 Solr 集群的生命周期中,您可能会决定从不安全的 ZooKeeper 迁移到安全的实例。更改 solr.xml
中的配置的 zkACLProvider
将确保新创建的节点是安全的,但不会保护已存在的数据。
要修改所有现有的 ACL,您可以使用 Solr 的 CLI 的 bin/solr zk updateacls
命令。首先取消注释 solr.in.*
中的 SOLR_ZK_CREDS_AND_ACLS
环境变量定义,并按照上面的 Solr CLI 中的 ZooKeeper ACL 中所述,填写管理员用户和只读用户的密码。
然后运行以下适合您操作系统的命令
-
*nix
-
Windows
$ bin/solr zk updateacls /zk-path
$ bin/solr.cmd zk updateacls /zk-path
只有在您的 SolrCloud 集群停止运行时,才应该在 ZooKeeper 中更改 ACL。在 Solr 运行时尝试这样做可能会导致状态不一致,并且某些节点变得无法访问。
solr.in.*
中 SOLR_ZK_CREDS_AND_ACLS
环境变量中包含的 VM 属性 zkCredentialsInjector
、zkACLProvider
和 zkCredentialsProvider
控制转换
-
凭据注入器读取凭据并将它们传递给凭据提供程序。如果省略,该过程将不使用任何凭据(适用于不安全的配置)。
-
凭据提供程序使用在节点上具有管理员权限的用户的凭据。如果省略,该过程将不使用任何凭据(适用于不安全的配置)。
-
ACL 提供程序将用于计算新的 ACL。如果省略,该过程将设置所有用户的所有权限,从而删除任何安全措施。
solr.in.*
中取消注释的 SOLR_ZK_CREDS_AND_ACLS
环境变量将凭据和 ACL 提供程序设置为 VMParamsZkCredentialsInjector
、DigestZkCredentialsProvider
和 DigestZkACLProvider
实现,如本页前面所述。