thelabdude commented on a change in pull request #221: URL: https://github.com/apache/lucene-solr-operator/pull/221#discussion_r583859256
########## File path: docs/solr-cloud/solr-cloud-crd.md ########## @@ -543,3 +543,234 @@ spec: ``` The example settings above will result in your Solr pods getting names like: `<ns>-search-solrcloud-0.k8s.solr.cloud` which you can request TLS certificates from LetsEncrypt assuming you own the `k8s.solr.cloud` domain. + +## Solr Security: Authentication and Authorization + +All well-configured Solr clusters should enforce users to authenticate, even for read-only operations. Even if you want +to allow anonymous query requests from unknown users, you should make this explicit using Solr's rule-based authorization +plugin. In other words, always enforce security and then relax constraints as needed for specific endpoints based on your +use case. The Solr operator can bootstrap a default security configuration for your SolrCloud during initialization. As such, +there is no reason to deploy an unsecured SolrCloud cluster when using the Solr operator. In most cases, you'll want to combine +basic authentication with TLS to ensure credentials are never passed in clear text. + +For background on Solr security, please refer to the [Reference Guide](https://lucene.apache.org/solr/guide) for your version of Solr. + +Basic authentication is the only authentication scheme supported by the Solr operator at this time. In general, you have +two basic options for configuring basic authentication with the Solr operator: +1. Let the Solr operator bootstrap the `security.json` to configure *basic authentication* for Solr. +2. Supply your own `security.json` to Solr, which must define a user account that the operator can use to make API requests to secured Solr pods. + +If you choose option 2, then you need to provide the credentials to the Solr operator using a Kubernetes [Basic Authentication Secret](https://kubernetes.io/docs/concepts/configuration/secret/#basic-authentication-secret). +With option 1, the operator creates the Basic Authentication Secret for you. + +### Option 1: Bootstrap Security + +The easiest way to get started with Solr security is to have the operator bootstrap a `security.json` (stored in ZK) as part of the initial deployment process. +To activate this feature, add the following configuration to your SolrCloud CRD definition YAML: +``` +spec: + ... + solrSecurity: + authenticationType: Basic +``` + +Once the cluster is up, you'll need the `admin` user password to login to the Solr Admin UI. +The `admin` user will have a random password generated by the operator during `security.json` bootstrapping. +Use the following command to retrieve the password from the bootstrap secret created by the operator: +``` +kubectl get secret <CLOUD>-solrcloud-security-bootstrap -o jsonpath='{.data.admin}' | base64 --decode +``` +_where `<CLOUD>` is the name of your SolrCloud_ + +Once `security.json` is bootstrapped, the operator will not update it! You're expected to use the `admin` user to access the Security API to make further changes. +In addition to the `admin` user, the operator defines a `solr` user, which has basic read access to Solr resources. You can retrieve the `solr` user password using: +``` +kubectl get secret <CLOUD>-solrcloud-security-bootstrap -o jsonpath='{.data.solr}' | base64 --decode +``` + +The operator makes requests to secured Solr endpoints as the `k8s-oper` user; credentials for the `k8s-oper` user are stored in a separate secret of type `kubernetes.io/basic-auth` +with name `<CLOUD>-solrcloud-basic-auth`. The `k8s-oper` user is configured with read-only access to a minimal set of endpoints, see details in the **Authorization** sub-section below. +Remember, if you change the `k8s-oper` password using the Solr security API, then you **must** update the secret with the new password or the operator will be locked out. +Also, changing the password for the `k8s-oper` user in the K8s secret after bootstrapping will not update Solr! You're responsible for changing the password in both places. + +#### Liveness and Readiness Probes + +We recommend configuring Solr to allow un-authenticated access over HTTP to the probe endpoint(s) and the bootstrapped `security.json` does this for you automatically (see next sub-section). +However, if you want to secure the probe endpoints, then you need to set `probesRequireAuth: true` as shown below: +``` +spec: + ... + solrSecurity: + authenticationType: Basic + probesRequireAuth: true +``` +When `probesRequireAuth` is set to `true`, the liveness and readiness probes execute a command instead of using HTTP. +The operator configures a command instead of setting the `Authorization` header for the HTTP probes, as that would require a restart of all pods if the password changes. +With a command, we can load the username and password from a secret; Kubernetes will +[update the mounted secret files](https://kubernetes.io/docs/concepts/configuration/secret/#mounted-secrets-are-updated-automatically) when the secret changes automatically. + +#### Authorization + +The default `security.json` created by the operator during initialization is shown below; the passwords for each user are randomized for every SolrCloud you create. +In addition to configuring the `solr.BasicAuthPlugin`, the operator initializes a set of authorization rules for the default user accounts: `admin`, `solr`, and `k8s-oper`. +Take a moment to review these authorization rules so that you're aware of the roles and access granted to each user in your cluster. +``` +{ + "authentication": { + "blockUnknown": false, + "class": "solr.BasicAuthPlugin", + "credentials": { + "admin": "...", + "k8s-oper": "...", + "solr": "..." + }, + "realm": "Solr Basic Auth", + "forwardCredentials": false + }, + "authorization": { + "class": "solr.RuleBasedAuthorizationPlugin", + "user-role": { + "admin": [ "admin", "k8s" ], + "k8s-oper": [ "k8s" ], + "solr": [ "users", "k8s" ] + }, + "permissions": [ + { + "name": "k8s-probe-0", + "role": null, + "collection": null, + "path": "/admin/info/system" + }, + { + "name": "k8s-status", + "role": "k8s", + "collection": null, + "path": "/admin/collections" + }, + { + "name": "k8s-metrics", + "role": "k8s", + "collection": null, + "path": "/admin/metrics" + }, + { + "name": "k8s-ping", + "role": "k8s", + "collection": "*", + "path": "/admin/ping" + }, + { + "name": "all", + "role": [ "admin", "users" ] + }, + { + "name": "read", + "role": [ "admin", "users" ] + }, + { + "name": "update", + "role": [ "admin" ] + }, + { + "name": "security-read", + "role": "admin" + }, + { + "name": "security-edit", + "role": "admin" + } + ] + } +} +``` +A few aspects of the default `security.json` configuration warrant a closer look. First, the `probesRequireAuth` setting +(defaults to `false`) governs the value for `blockUnknown` (under `authentication`) and whether the probe endpoint(s) require authentication: +``` + { + "name": "k8s-probe-0", + "role": null, + "collection": null, + "path": "/admin/info/system" Review comment: Re-worked this a bit and improved the docs in this area. Added a check for how custom probe paths are handled to one of the existing unit tests ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@lucene.apache.org For additional commands, e-mail: issues-h...@lucene.apache.org