Until version 5.2, Solr did not include any specific security features. If you wanted to secure your Solr installation, you needed to use external tools and solutions which were proprietary and maybe not so well known by your organization. A security API was introduced in Solr 5.2 and Solr 5.3 will have full-featured authentication and authorization plugins that use Basic authentication and “permission rules” which are completely driven from ZooKeeper.

Caveats

  • Basic authentication sends credentials in plain text. If the communication channels are not secure, attackers can know the password. You should still secure your communications with SSL.
  • ZooKeeper is the weakest link in this security. Ensure that write permissions to ZooKeeper is granted only to appropriate users.
  • It is still not safe to expose your Solr servers to an unprotected network.

 

Enabling Basic Authentication

Step 1 : Save the following JSON to a file called security.json:

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

The above configuration does the following:

  • Enable authentication and authorization
  • A user called 'solr' is created with a password 'SolrRocks'
  • The user 'solr' is assigned a role 'admin'
  • The permissions to edit security is now restricted to the role 'admin'. All other resources are unprotected and the user should configure more rules to secure them.
  • This does not block any unauthenticated access to paths other than security-edit operations. However, it is possible to block all unauthenticated access by adding the attribute blockUnknown=true to the authentication section

Step 2: Upload to ZooKeeper

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

All solr nodes watch the /security.json and this change is immediately reflected in the nodes behavior. You can verify the operation with the following commands.

curl http://localhost:8983/solr/admin/authentication
curl http://localhost:8983/solr/admin/authorization

These calls should return with the corresponding sections in the json we uploaded.

BasicAuthPlugin

The BasicAuthPlugin authenticates users using HTTP’s Basic authentication mechanism. Authentication is done against the user name and salted sha256 hash of the password stored in ZooKeeper.

Editing credentials

There is an API to add, edit or remove users. Please note that the commands shown below are tied to this specific Basic authentication implementation and the same set of commands are not valid if the implementation class is not solr.BasicAuthPlugin.

Example 1: Add a user and/or edit a password

curl --user solr:SolrRocks http://localhost:8983/solr/admin/authentication -H 'Content-type:application/json'-d '{ 
  "set-user": {"tom" : "TomIsCool" , 
               "harry":"HarrysSecret"}}'

Example 2: Delete a user

curl --user solr:SolrRocks http://localhost:8983/solr/admin/authentication -H 'Content-type:application/json'-d  '{
 "delete-user": ["tom","harry"]}'

RuleBasedAuthorizationPlugin

This plugin relies on the configuration stored in ZooKeeper to determine if a particular user is allowed to make a request. The configuration has two sections:

  • A mapping of users to roles. A role can be any user defined string.
  • A set of permissions and the rules on who can access what.

What is a Permission?

A permission is a white-list roles that can access a resource. Most well-known resources have predefined names.

How is a Permission Matched?

For an incoming request, the permissions are tested in the order in which they appear in the configuration. The first permission to match is applied. If you have multiple permissions that can match a given request, put the strictest permissions first. For example, if there is a generic permission that says anyone with a 'dev' role can perform write operations to any collection and you wish to restrict write operations to .system collection to admin only, add the permission for the latter before the more generic permission.

If there is no permission matching a given request, then it is accessible to all

Well Known Permissions

There are a few convenience permissions which are commonly used. They have fixed default values for certain attributes. If you use one of the following permissions just specify the roles who can  access these. Trying to specify other attributes  for the following will give an error.

  • security-edit : Edit security configuration
  • security-read : Read security configuration
  • schema-edit : Edit schema of any collection
  • schema-read :  Read schema of any collection
  • config-read : Read solrconfig of any collection
  • config-edit : Edit config of any collection
  • collection-admin-read : Read operations performed on /admin/collections such as LIST, CLUSTERSTATUS
  • collection-admin-edit : All operations on /admin/collections which can modify the state of the system
  • core-admin-read : Read operations on the core admin API
  • core-admin-edit : Core admin commands that can mutate the system state
  • update : Update operation on any collection
  • read : Any read handler such as /select, /get in any collection
  • all :  Any request coming to Solr

 

User-defined permissions

It is possible to create a permission by specifying the attributes of a request and the roles that are allowed to make such a request. The attributes are all multivalued. The attributes of request are:

  • collection: The name of the collection for which this rule should be applied to. If this value is not specified, it is applicable to all collections.
  • path: This is the handler name for the request. It can support wild card prefixes  as well.For example, /update/* will apply to all handlers under /update/.
  • method: HTTP methods valid for this permission. Allowed values are GET, POST, PUT, DELETE, and HEAD.
  • params: These are the names and values of request parameters. For example, "params":{"action":["LIST","CLUSTERSTATUS"]} restricts the rule to be matched only when the values of the parameter "action" is one of "LIST" or "CLUSTERSTATUS".

Editing permissions

There is an API to edit the permissions. Please note that the following commands are valid only for the RulesBasedAuthorizationPlugin.

The commands for managing permissions are:

  • set-permission: create a new permission, overwrite an existing permission definition, or assign a pre-defined permission to a role.
  • update-permission: update some attributes of an existing permission definition.
  • delete-permission: remove a permission definition.

Example 1: add or remove roles

curl --user solr:SolrRocks http://localhost:8983/solr/admin/authorization -H 'Content-type:application/json' -d '{ 
  "set-user-role": {"tom":["admin","dev"},
  "set-user-role": {"harry":null}
}'

Example 2: add a well-known permission

curl --user solr:SolrRocks http://localhost:8983/solr/admin/authorization -H 'Content-type:application/json'-d '{ 
  "set-permission": { "name":"update","role": "dev"}
 }'

Example 3: add or remove a user-defined permission

 

curl --user solr:SolrRocks http://localhost:8983/solr/admin/authorization -H 'Content-type:application/json'-d '{ 
  "set-permission": { "name":"a-custom-permission-name",
                      "collection":"gettingstarted",
                      "path":"/handler-name"
                      "role": "dev"
   },
 "delete-permission":"permission-name"
}'

Please note that the "set-permission" replaces your permission fully. Use the "update-permission" operation to partially update a permission.  Use the 'before' property to re-order your permissions

Example 4: Restrict collection admin operations (writes only) to be performed by an admin only

curl --user solr:SolrRocks http://localhost:8983/solr/admin/authorization -H 'Content-type:application/json' -d '{
"set-permission" : {"name":"collection-admin-edit", "role":"admin"}}'

 This ensures that the write operations can be performed by admin only. Trying to perform a secure operation without credentials with a browser will now prompt for user-name and password:

Screen Shot 2015-07-22 at 7.51.19 PM

Example 5: Restrict all writes to all collections to dev role

curl --user solr:SolrRocks http://localhost:8983/solr/admin/authorization -H 'Content-type:application/json' -d '{
"set-permission" : {"name":"update", "role":"dev"}}'

Example 6 : Restrict writes to .system collection to admin only

curl --user solr:SolrRocks http://localhost:8983/solr/admin/authorization -H 'Content-type:application/json' -d '{
"set-permission" : {"name":"system-coll-write",
                     "collection": ".system"
                     "path":"/update/*",
                     "before":3,
                     "role":"admin"}}'

 

Please note the 'before' attribute, this ensures that this permission is inserted right before the  permission at index 3.

Example 7 : Update the above permission to  add the /blob* path

curl --user solr:SolrRocks http://localhost:8983/solr/admin/authorization -H 'Content-type:application/json' -d '{
"update-permission" : {"name":"system-coll-write", 
                    "path": ["/update/*","/blob/*"]}}'

Securing Inter-node calls

BasicAuthPlugin uses Solr’s own mechanism for securing inter-node calls using PKI infrastructure.  (That is topic for another blog)