启用 SSL
Solr 可以使用安全套接字层加密 (SSL) 加密与客户端之间以及在 SolrCloud 模式下节点之间的通信。
本节介绍如何使用自签名证书启用 SSL。
有关 SSL 证书和密钥的背景信息,请参阅 http://www.tldp.org/HOWTO/SSL-Certificates-HOWTO/。
配置 Solr 以使用 SSL
生成自签名证书和密钥
要生成自签名证书和用于验证服务器和客户端的单个密钥,我们将使用 JDK keytool
命令并创建一个单独的密钥库。此密钥库也将在下面用作信任库。可以使用 JDK 附带的密钥库用于这些目的,并使用单独的信任库,但此处未介绍这些选项。
在二进制 Solr 发行版的 server/etc/
目录中运行以下命令。假设您的 PATH
上有 JDK keytool
实用程序,并且 openssl
也在您的 PATH
上。有关 Windows 和 Solaris 的 OpenSSL 二进制文件,请参阅 https://wiki.openssl.org/index.php/Binaries。
-ext SAN=…
keytool
选项允许您指定在选择要求主机名验证时将允许的所有 DNS 名称和/或 IP 地址。
除了 localhost
和 127.0.0.1
之外,此示例还包括运行 Solr 节点的计算机的 LAN IP 地址 192.168.1.3
$ keytool -genkeypair -alias solr-ssl -keyalg RSA -keysize 2048 -keypass secret -storepass secret -validity 9999 -keystore solr-ssl.keystore.p12 -storetype PKCS12 -ext SAN=DNS:localhost,IP:192.168.1.3,IP:127.0.0.1 -dname "CN=localhost, OU=Organizational Unit, O=Organization, L=Location, ST=State, C=Country"
上面的命令将在当前目录中创建一个名为 solr-ssl.keystore.p12
的密钥库文件。
将证书和密钥转换为 PEM 格式以便与 curl 一起使用
使用 openssl
命令将包含证书和密钥的 PKCS12 格式密钥库转换为 PEM 格式。
$ openssl pkcs12 -in solr-ssl.keystore.p12 -out solr-ssl.pem
如果要在 OS X Yosemite (10.10) 上使用 curl,则需要创建 PEM 格式的仅包含证书的版本,如下所示:
$ openssl pkcs12 -nokeys -in solr-ssl.keystore.p12 -out solr-ssl.cacert.pem
设置通用的 SSL 相关系统属性
Solr 控制脚本已设置为将 SSL 相关的 Java 系统属性传递给 JVM。要激活 SSL 设置,请在 *nix 系统上的 bin/solr.in.sh
或 Windows 上的 bin\solr.in.cmd
中取消注释并更新以 SOLR_SSL_*
开头的一组属性。
-
*nix
-
Windows
如果您按照将 Solr 用于生产环境中所述的步骤在 Linux 上将 Solr 设置为服务,则在 /var/solr/solr.in.sh 中进行这些更改。 |
# Enables HTTPS. It is implicitly true if you set SOLR_SSL_KEY_STORE. Use this config
# to enable https module with custom jetty configuration.
SOLR_SSL_ENABLED=true
# Uncomment to set SSL-related system properties
# Be sure to update the paths to the correct keystore for your environment
SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.p12
SOLR_SSL_KEY_STORE_PASSWORD=secret
SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.p12
SOLR_SSL_TRUST_STORE_PASSWORD=secret
# Require clients to authenticate
SOLR_SSL_NEED_CLIENT_AUTH=false
# Enable clients to authenticate (but not require)
SOLR_SSL_WANT_CLIENT_AUTH=false
# SSL Certificates contain host/ip "peer name" information that is validated by default. Setting
# this to false can be useful to disable these checks when re-using a certificate on many hosts.
# This will also be used for the default value of whether SNI Host checking should be enabled.
SOLR_SSL_CHECK_PEER_NAME=true
REM Enables HTTPS. It is implicitly true if you set SOLR_SSL_KEY_STORE. Use this config
REM to enable https module with custom jetty configuration.
set SOLR_SSL_ENABLED=true
REM Uncomment to set SSL-related system properties
REM Be sure to update the paths to the correct keystore for your environment
set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.p12
set SOLR_SSL_KEY_STORE_PASSWORD=secret
set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.p12
set SOLR_SSL_TRUST_STORE_PASSWORD=secret
REM Require clients to authenticate
set SOLR_SSL_NEED_CLIENT_AUTH=false
REM Enable clients to authenticate (but not require)
set SOLR_SSL_WANT_CLIENT_AUTH=false
REM SSL Certificates contain host/ip "peer name" information that is validated by default. Setting
REM this to false can be useful to disable these checks when re-using a certificate on many hosts.
REM This will also be used for the default value of whether SNI Host checking should be enabled.
set SOLR_SSL_CHECK_PEER_NAME=true
客户端身份验证设置 启用 SOLR_SSL_NEED_CLIENT_AUTH 或 SOLR_SSL_WANT_CLIENT_AUTH 中的一个,但不能同时启用两者。它们是互斥的,Jetty 将选择其中一个,这可能不是您所期望的。如果要禁用客户端证书的主机名验证,应将 SOLR_SSL_CLIENT_HOSTNAME_VERIFICATION 设置为 false。 |
当您启动 Solr 时,bin/solr
脚本会包含这些设置,并将它们作为系统属性传递给 JVM。
如果您在用户管理的集群或单节点安装中运行 Solr,则可以跳到启动用户管理的集群或单节点 Solr。
但是,如果您正在使用 SolrCloud,则需要在启动 Solr 之前配置 ZooKeeper。
通过 Hadoop 凭据存储进行密码分发
Solr 支持从 Hadoop 凭据存储读取密钥库和信任库密码。如果密码轮换和分发已由凭据存储处理,则此方法可能很有益。
如果您未使用 Hadoop 凭据存储,则可以跳过此步骤。
可以使用以下两个步骤将 Hadoop 凭据存储与 Solr 一起使用。
提供 Hadoop 凭据存储
创建一个 Hadoop 凭据存储文件,并使用实际的密钥库密码定义以下条目。
solr.jetty.keystore.password
solr.jetty.truststore.password
javax.net.ssl.keyStorePassword
javax.net.ssl.trustStorePassword
请注意,如果未设置 javax.net.ssl.*
配置,它们将回退到相应的 solr.jetty.*
配置。
配置 Solr 以使用 Hadoop 凭据存储
Solr 需要配置三个参数才能使用凭据存储文件来获取密钥库密码。
solr.ssl.credential.provider.chain
-
必需
默认值:无
凭据提供程序链。应设置为
hadoop
。 SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH
-
必需
默认值:无
凭据存储文件的路径。
HADOOP_CREDSTORE_PASSWORD
-
必需
默认值:无
凭据存储的密码。
-
*nix
-
Windows
SOLR_OPTS=" -Dsolr.ssl.credential.provider.chain=hadoop"
SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH=localjceks://file/home/solr/hadoop-credential-provider.jceks
HADOOP_CREDSTORE_PASSWORD="credStorePass123"
set SOLR_OPTS=" -Dsolr.ssl.credential.provider.chain=hadoop"
set SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH=localjceks://file/home/solr/hadoop-credential-provider.jceks
set HADOOP_CREDSTORE_PASSWORD="credStorePass123"
配置 ZooKeeper
在创建上述密钥库并启动任何 SolrCloud 节点之前,您必须在 ZooKeeper 中配置您的 Solr 集群属性,以便 Solr 节点知道通过 SSL 进行通信。
本节假设您已创建并启动了一个外部 ZooKeeper。有关更多信息,请参阅ZooKeeper 集群配置。
在任何 Solr 节点启动之前,需要将集群范围的 urlScheme
属性设置为 https
。下面的示例使用 Solr 附带的 zkcli
工具来执行此操作。
-
*nix
-
Windows
$ bin/solr cluster --property urlSchema --value https -z server1:2181,server2:2181,server3:2181
C:\> bin/solr.cmd --property urlSchema --value https -z server1:2181,server2:2181,server3:2181
请确保使用适合您系统的正确 zkhost
值。如果您已将 ZooKeeper 集群设置为使用用于 Solr 的 chroot,请确保将其包含在 zkHost
字符串中,例如 --zk-host server1:2181,server2:2181,server3:2181/solr
。
更新现有集合的集群属性
如果您正在使用 SolrCloud 并且在启用 SSL 之前创建了集合,则需要更新集群属性以使用 HTTPS。
如果您没有现有集合或者未使用 SolrCloud,则可以跳过此步骤并启动 Solr。
可以使用 Collections API 的 CLUSTERPROP 命令更新集群属性,如本示例所示(根据您的系统更新主机名和端口):
$ https://127.0.0.1:8983/solr/admin/collections?action=CLUSTERPROP&name=urlScheme&val=https
此命令只需要在集群的一个节点上运行,更改将应用于所有节点。
完成此步骤和所有其他步骤后,您可以继续启动 Solr。
启用 SSL 后启动 Solr
启动用户管理的集群或单节点 Solr
使用如下示例中所示的 Solr 控制脚本启动 Solr。根据需要自定义所示参数的值,并添加系统中使用的任何参数。
-
*nix
-
Windows
$ bin/solr start -p 8984
C:\> bin\solr.cmd -p 8984
启动 SolrCloud
如果您在 solr.in.sh /solr.in.cmd 中定义了 ZK_HOST (请参阅更新 Solr 包含文件),则可以从以下所有 bin/solr /bin\solr.cmd 命令中省略 -z <zk host string> 。 |
使用如下示例中所示的 Solr 控制脚本启动每个 Solr 节点。根据需要自定义所示参数的值,并添加系统中使用的任何参数。
如果您创建 SSL 密钥时未包含运行 Solr 节点的所有 DNS 名称或 IP 地址,则可以通过设置 -Dsolr.ssl.checkPeerName=false
系统属性来告知 Solr 跳过节点间通信的主机名验证。
-
*nix
-
Windows
$ bin/solr start --cloud -s cloud/node1 -z server1:2181,server2:2181,server3:2181 -p 8984
C:\> bin\solr.cmd --cloud -s cloud\node1 -z server1:2181,server2:2181,server3:2181
自动重新加载密钥库/信任库
Solr 服务器
当证书更新时,Solr 可以自动重新加载密钥库/信任库,而无需重新启动。默认情况下,在使用 SSL 时启用此功能,但可以通过将环境变量 SOLR_SSL_RELOAD_ENABLED
设置为 false
来禁用此功能。默认情况下,Solr 将每 30 秒检查一次密钥库中的更新,但可以通过在启动时传递系统属性 solr.jetty.sslContext.reload.scanInterval
(以秒为单位的新间隔)来更新此间隔。请注意,信任库文件不会被主动监视,因此如果您需要将更改应用于信任库,则需要更新它,然后触摸密钥库以触发重新加载。
SolrJ 客户端
Http2SolrClient 构建器有一个方法 withKeyStoreReloadInterval(long interval, TimeUnit unit)
来初始化一个扫描器,该扫描器将监视和更新密钥库和信任库的更改。如果您正在使用 CloudHttp2SolrClient,则可以使用 withInternalClientBuilder(Http2SolrClient.Builder internalClientBuilder)
来配置具有密钥库重新加载间隔的内部 http 客户端。最小重新加载间隔为 1 秒。如果未设置(或设置为 0 或负值),则不会在客户端中更新密钥库/信任库。
示例客户端操作
OS X Mavericks (10.9) 上的 curl 具有降级的 SSL 支持。有关更多信息以及允许单向 SSL 的解决方法,请参阅https://curl.se/mail/archive-2013-10/0036.html。OS X Yosemite (10.10) 上的 curl 已得到改进 - 可以进行双向 SSL - 请参阅https://curl.se/mail/archive-2014-10/0053.html。 以下部分中的 curl 命令在 OS X Yosemite (10.10) 上无法与系统
|
如果您的操作系统不包含 curl,您可以在此处下载二进制文件:https://curl.se/download.html |
使用 bin/solr 创建 SolrCloud 集合
使用 _default
配置集创建名为 mycollection 的 2 分片、replicationFactor=1 的集合
-
*nix
-
Windows
bin/solr create -c mycollection --shards 2
bin\solr.cmd create -c mycollection --shards 2
create
操作会将 include 文件中设置的 SOLR_SSL_*
属性传递给用于创建集合的 SolrJ 代码。
使用 curl 检索 SolrCloud 集群状态
要获取生成的集群状态(同样,如果您未启用客户端身份验证,请删除 -E solr-ssl.pem:secret
选项)
$ curl -E solr-ssl.pem:secret --cacert solr-ssl.pem "https://127.0.0.1:8984/solr/admin/collections?action=CLUSTERSTATUS&indent=on"
您应该获得如下所示的响应
{
"responseHeader":{
"status":0,
"QTime":2041},
"cluster":{
"collections":{
"mycollection":{
"shards":{
"shard1":{
"range":"80000000-ffffffff",
"state":"active",
"replicas":{"core_node1":{
"state":"active",
"base_url":"https://127.0.0.1:8984/solr",
"core":"mycollection_shard1_replica1",
"node_name":"127.0.0.1:8984_solr",
"leader":"true"}}},
"shard2":{
"range":"0-7fffffff",
"state":"active",
"replicas":{"core_node2":{
"state":"active",
"base_url":"https://127.0.0.1:7574/solr",
"core":"mycollection_shard2_replica1",
"node_name":"127.0.0.1:7574_solr",
"leader":"true"}}}},
"router":{"name":"compositeId"},
"replicationFactor":"1"}},
"properties":{"urlScheme":"https"}}}
使用 bin/solr post 索引文档
使用 bin/solr post
将一些示例文档索引到上面创建的 SolrCloud 集合中
$ bin/solr post --solr-update-url https://127.0.0.1:8984/solr/mycollection/update example/exampledocs/*.xml
使用 curl 查询
使用 curl 查询上面创建的 SolrCloud 集合,从包含上面创建的 PEM 格式证书和密钥的目录(例如,example/etc/
)中进行查询。如果您未启用客户端身份验证(系统属性 -Djetty.ssl.clientAuth=true)
),则可以删除 -E solr-ssl.pem:secret
选项
$ curl -E solr-ssl.pem:secret --cacert solr-ssl.pem "https://127.0.0.1:8984/solr/mycollection/select?q=*:*"
使用 CloudSolrClient 索引文档
从使用 SolrJ 的 java 客户端索引文档。在下面的代码中,javax.net.ssl.*
系统属性是以编程方式设置的,但您也可以在 java 命令行中指定它们,如上面的 post.jar
示例中所示
System.setProperty("javax.net.ssl.keyStore", "/path/to/solr-ssl.keystore.p12");
System.setProperty("javax.net.ssl.keyStorePassword", "secret");
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
System.setProperty("javax.net.ssl.trustStore", "/path/to/solr-ssl.keystore.p12");
System.setProperty("javax.net.ssl.trustStorePassword", "secret");
System.setProperty("javax.net.ssl.trustStoreType", "pkcs12");
String zkHost = "127.0.0.1:2181";
CloudSolrClient client = new CloudSolrClient.Builder(Collections.singletonList(zkHost),Optional.empty()).withDefaultCollection("mycollection").build();
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", "1234");
doc.addField("name", "A lovely summer holiday");
client.add(doc);
client.commit();