Solr 安全: 提示、技巧及需要知道的事情

本贴最后更新于 2507 天前,其中的信息可能已经东海扬尘

随着 solr5.2 的发行,Solr 有了认证和授权的 API。让你能使用 RuleBasedAuthorizationPlugin 和 BasicAuthPlugin 这两个插件来定义用户、角色和权限。但美中不足的是,这些插件虽然很强大,但是配置起来却不那么直观。因此,我花了好一些时间来研究 Solr 的安全架构,搞清楚了两件事情,它的架构是怎样工作的以及它有哪些特性。最后,我总结了一个在配置和管理 Solr 安全时需要注意的清单。
使用 Solr 认证和授权的第一步是要开通 solr security 功能。当你开通了 solr security 功能,你就能用 api 来更新你的安全配置了。你需要用 zookeeper 来上传 security.json 文件。首先你要打开命令行,cd 到你 solr 安装目录。然后启动 solr,执行

bin/solr start -cloud

在那里,先要确保 security.son 文件在安装根目录,然后执行命令:

server/scripts/cloud-scripts/zkcli.sh -zkhost localhost:9983 -cmd putfile /security.json security.json 

这样会安装 security.json 到 zookeeper 和所有可用节点,并且会使 solr 安全框架启动起来。

security.json 例子


{
"authentication":{
   "class":"solr.BasicAuthPlugin",
   "credentials":{"solr":"IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c="}
},
"authorization":{
   "class":"solr.RuleBasedAuthorizationPlugin",
   "permissions":[{"name":"security-edit",
      "role":"admin"}]
   "user-role":{"solr":"admin"}
}}

一个 security.json 文件的解析

在上面的例子中,我们看到两个顶层的属性声明:authentication 和 authorization。它们分别代表要传给两个 api 的组合数据。“class”属性定义用于处理这些 api 的处理类。BasicAuthPlugin 和 RuleBasedAuthorizationPlugin 都打包到 solr 中了,你也可以定义自己的处理类。
在这个例子中,自定义鉴权,你需要这样做

extend AuthenticationPlugin implements ConfigEditorPlugin, SpecProvider

在这个例子中,自定义授权,你需要这样做

implements AuthorizationPlugin,ConfigEditablePlugin,SpecProvider

继续,在 authentication 对象中,有一个“credential”属性定义。它包含了一个列表,列表中是授权了的用户和 SHA-256 加密的密码。用户管理会在这篇文章的后面讨论。

在 authorization 对象中,有一个“permissions"属性定义和一个用户角色列表,用 username:role 来定义。在这里,你能关联你的环境中用到的角色和在 authentication 定义的用户。你想创建多少用户角色就能创建多少,但是,需要记住

  • 所有用户必须是系统中注册的用户。
  • 用户角色定义得越多,权限矩阵就越复杂。

权限数组是安全定义的最小粒度。它使用先前定义的用户角色来绑定单独的权限。这是很重要的,也是为什么人们觉得 solr 安全设置不大方便的原因。权限和角色是一对一的关系。唯一例外的是通配符“”,能用在所有的角色定义中,意味着所有的角色都拥有该权限。有重叠定义的情况下,可以使用“before”关键字,来使一个权限优先于其他权限。其他情况下,一个权限只限制在一个角色中。这意味着,你要仔细考虑怎样构造你权限矩阵。举个例子,如果你要给系统中的所有用户“读”权限,你需要不仅仅是定义{“name”: “read”, “role”: “”}。乍一看,或直观上,你会觉得,这样就覆盖了所有需要读的东西。但事实上不是这样的。给所有角色赋予读权限,你需要这样做

{"name":"read","role":""},{"name":"schema-read","role":""},{"name":"config-read","role":""},{"name":"collection-admin-read","role":""},{"name":"metrics-read","role":""},{"name":"core-admin-read","role":""}

这样,你的所有用户就能没有限制的访问 solr 管理控制台所能看到的所有东西了。

一个真实运行的例子

最近,我们有一个客户咨询了关于实现 solr 文档级别的安全的问题。Solr 的权限框架允许你在控制台配置 collection 级别的安全,但是,如果你要实现文档级别的安全,则需要编写自己的服务来对每个文档进行 ACP(access control policy)控制。如上所述,你能从控制台配置到 collection 级别的安全。那要创建怎样的 collection 级别的权限矩阵呢?


{"authentication":{
"class":"solr.BasicAuthPlugin",
"credentials":{"solr":"IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c=","devuser":"IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c="}
},
"authorization":{
"class":"solr.RuleBasedAuthorizationPlugin",
"user-role":{"solr":"admin","devuser":"dev"},
"permissions":[{"name":"read","role":"*"},{"name":"schema-read","role":"*"},{"name":"config-read","role":"*"},{"name":"collection-admin-read","role":"*"},{"name":"metrics-read","role":"*"},{"name":"core-admin-read","role":"*"},{ "name":"secure-collection1-permission",
                      "collection":"securecollection",
                      "path":"/select",
                      "before": "collection-admin-read",
                      "role": "admin"
   }]
}}

从上面的例子所看到的,我定义了两个用户(solr/devuser)和两个角色(admin/dev),然后我分配了完全可读的权限给所有用户,除了一个 collection,它只能通过 admin 角色访问。按照配置,这个权限定义优先于 collection-admin-read 角色。这意味着,只有 admin 角色能看到名为“securecollection”的 collection。我定义了授权路径“/select",这意味着用户可以查询 collection。权限的名字是任意的,只限制不能和内置的权限重名(比如”read"、"update"等)。在这个例子中,我将它命名为“secure-collection1-permission”。
预先定义的权限名,从 PermissionNameProvider 这个类里可以看到:


COLL_EDIT_PERM("collection-admin-edit", null),  
COLL_READ_PERM("collection-admin-read", null),  
CORE_READ_PERM("core-admin-read", null),  
CORE_EDIT_PERM("core-admin-edit", null),  
READ_PERM("read", ""), UPDATE_PERM("update", ""),  
CONFIG_EDIT_PERM("config-edit", ""),  
CONFIG_READ_PERM("config-read", ""),  
SCHEMA_READ_PERM("schema-read", ""),  
SCHEMA_EDIT_PERM("schema-edit", ""),  
SECURITY_EDIT_PERM("security-edit", null),  
SECURITY_READ_PERM("security-read", null),  
METRICS_READ_PERM("metrics-read", null),  
ALL("all", unmodifiableSet(new HashSet<>(asList("*", null))))  

  • collection-admin-edit: 允许该角色的用户更新 collection.
  • collection-admin-read: 允许该角色的用户读取 collection.
  • core-admin-edit: 允许该角色的用户编辑管理接口的特定方面(不安全)。
  • core-admin-read: 允许该角色的用户在管理控制台读取特定的条目。
  • read: 提供的基本的‘read'权限给用户。注意:该权限不是给角色完全的读权限。
  • config-read: 允许已鉴权用户读取配置信息。
  • config-edit: 允许已鉴权用户编辑 Solr 配置信息。
  • schema-read: 允许该角色的用户读取 collection schema 信息.
  • schema-edit: 允许该角色的用户编辑 collection schema 信息.
  • metics-read: 允许该角色的用户 Solr metric 数据.
  • all: 提供相关角色所有权限。

权限属性包括

"collection", "role", "params", "path", "method", "name","index","before" 

  • ‘collection‘是你环境中的 collection 的名字
  • ‘role‘ 是你预先定义的角色
  • ‘params‘ 说明允许的查询参数(比如&wt=json)
  • ‘path‘ 说明要允许的 url(比如 ‘/select). Solr 中有效的 path 是:
    /admin/mbeans,/browse,/update/json/docs,/admin/luke,/export,/get,/admin/properties,/elevate,/update/json,/admin/threads,/query,/analysis/field,/analysis/+ document,/spell,/update/csv,/sql,/graph,/tvrh,/select,/admin/segments,/admin/system,/replication,/config,/stream,/schema,/admin/plugins,/admin/logging,/+ admin/ping,/update,/admin/file,/terms,/debug/dump,/update/extract
  • ‘method‘ 指的是 HTTP 协议的方法, 支持的方法: GET,PUT,POST,DELETE,HEAD. 注意 ‘OPTIONS’ 不是一个支持的方法, 还有 ‘TRACE’, ‘CONNECT’ 和 ‘PATCH’也不是。
  • ‘name‘ 权限的名称,可以是内置的,也可以是自定义的。
  • ‘index‘ 指的是权限的索引,权限一旦在系统中定义了,就会赋予一个索引。 注意: + 一些老的说明文档中使用权限名称来限定‘delete-permission’行为,然而,你需要使用权限索引(一个整数)而不是一个名称(字符串)。你可以调用授权 api 获取权限的索引。
  • ‘before’ 表明这个权限会比指定的权限优先。

管理用户

Solr 的用户管理 api 是很简练的,且由于缺少必要的操作而备受争议。你能增加、修改、删除用户密码,然而,一旦你上传了 security.json 文件,开始使用 api,你初始的 security.json 文件就过期了,而如果你重新上传 security.json 文件,它会覆盖你之前的任何修改操作。这就是为什么保持 security.json 为最新版本是个好主意。这样,如果您需要迁移节点集群,就不必担心需要从头建立用户权限。你只需要上传你的文件 security.json,然后其他都不需要做了。
最后,让我们看一下一个用户管理流程的最佳实践。
1.上传 security.json
2.增加一个用户:

curl –user solr:SolrRocks http://localhost:8983/solr/admin/authentication -H 'Content-type:application/json' -d '{ 

"set-user": {"tom" : "TomIsCool"}'
3.现在,然我们获取 tom 的密码 SHA-256 哈希码:

curl –user solr:SolrRocks http://localhost:8983/solr/admin/authentication

应答大概是这样:


{ 
  "responseHeader":{ 
    "status":0, 
    "QTime":3}, 
  "authentication.enabled":true, 
  "authentication":{ 
    "class":"solr.BasicAuthPlugin", 
    "credentials":{ 
      "solr":"IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c=", 
      "tom":"IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c="}}}

4.现在,拷贝‘tom’的条目,加到你的 security.json 文件中。 这样,你维护了一个授权用户的最新列表,而如果你需要改变一个权限,改变你的 security.json 文件,或迁移你的环境,你也不需要重新创建它。 不可否认,这样做是有点绕,但这会节省你的时间,且很多时候,是非常有效的。

权限的故障排除

权限的故障排除往往是非常困难的。往往权限系统不会提供足够的错误信息,甚至,一点错误信息都没有。但 Solr 不是这样的。Solr 在未授权的情况下会返回 403 错误。然而,如果你上传了一个 security.json 文件,但它的表现并非如你所愿,试下找到 solr.log 文件,查看一下里面的错误信息。这是你调试 Solr 的权限矩阵的最好的朋友。这是一些常见的错误

  • 没有授权用户:

    2017-03-08 15:47:55.876 INFO (qtp1348949648-16) [ ] o.a.s.s.HttpSolrCall USER_REQUIRED auth header null context : [FAILED toString()]

  • 无效角色:

    “role”:”admin”}, The principal [principal: devuser] does not have the right role

这些是用户权限最常见的错误。

简而言之:使用 Solr 安全时的重要的提示和技巧

  • 你的 Solr 安装在防火墙里面会比较安全。
  • 启动 Solr 的用户只有 Solr home 目录的写权限。(Solr home 目录(默认是 $SOLR_INSTALL/server/solr )
  • 权限是先进先出的。就是说,他们按照声明的顺序进行计算。
  • 角色和权限的关系是一对一的。一个权限(比如‘read')只会被计算一次,就是在它第一次在列表中出现的时候。如果你有第二个’read‘在下面的行中定义,它会被忽略掉。
  • 你可以用星号()来分配所有权限给所有用户。 { “name”: “read”, “role”: “”}
  • ‘role’属性可以传递(*)或一个角色名称字符串作为参数。你不能传递一个数组或逗号分隔的字符串。
  • 你可以使用‘all’权限来分配所有权限给给定角色{ “name”: “all”, “role”: “admin”}
  • 你应该尽量分配少点权限以免犯错。只分配你所需要的。 “少即是多.” 就是说,所需之间保持平衡,避免走向极端。
  • 当删除权限时,你必须使用权限下标而不是权限名称。
  • 通配符要好好利用。
  • 如果你分配控制台的普通读权限,你还需要同时分配 collection-admin-read and core-admin-read 这两个权限。类似的,分配‘update'权限,也需要同时分配 core-admin-edit and + collection-admin-edit 给相同的角色。
  • 定义一个权限,只有’role'参数是必须的。
  • 使用库比如 Solrj 来和 ZooKeeper 通讯。
  • 当使用一个预定义的权限,可选的参数只有 name, role, collection, index.

英文链接

  • Solr
    16 引用 • 22 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...