diff --git a/README.asciidoc b/README.asciidoc index eb5bb3ea592..cccc9f0a480 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -51,12 +51,12 @@ When running the build in offline mode (`--offline`), it will not required to ha Machine Learning requires platform specific binaries, build from https://github.com/elastic/machine-learning-cpp via CI servers. -The native artifacts are stored in S3. To retrieve them infra's team Vault service is utilized, which -requires a github token. Please setup a github token as documented: +The native artifacts are stored in S3. To retrieve them infra's team Vault service is utilized, which +requires a github token. Please setup a github token as documented: https://github.com/elastic/infra/blob/master/docs/vault.md#github-auth -The github token has to be put into ~/.elastic/github.token, while the file rights must be set to 0600. +The github token has to be put into ~/.elastic/github.token, while the file rights must be set to 0600. = Build @@ -97,50 +97,31 @@ gradle clean install = Building documentation -The source files in this repository can be included in either the X-Pack Reference or the Elasticsearch Reference. +The source files in this repository can be included in either the X-Pack +Reference or the Elasticsearch Reference. -NOTE: In 5.5 and later, the Elasticsearch Reference includes X-Pack-specific content when it is built from this repo. +NOTE: In 5.4 and later, the Elasticsearch Reference includes X-Pack-specific +content that is pulled from this repo. -To build the Elasticsearch Reference on your local machine: - -* Use the `index.asciidoc` file in the docs/en directory. -* Specify the location of the `elasticsearch/docs` directory with the `--resource` option when you run `build_docs.pl`. - -For example: - -[source, txt] ------ -./docs/build_docs.pl --doc elasticsearch-extra/x-pack-elasticsearch/docs/en/index.asciidoc --resource=elasticsearch/docs --chunk 1 ------ - -For information about building the X-Pack Reference, see the README in the x-pack repo. - -To build a release notes page for the pull requests in this repository: - -* Use the dev-tools/xes-release-notes.pl script to pull PRs from the x-pack-elasticsearch repo. Alternatively, use the dev-tools/xescpp_release_notes.pl script to pull PRs from both the x-pack-elasticsearch and machine-learning-cpp repos. -* Specify the version label for which you want the release notes. -* Redirect the output to a new local file. - -NOTE: You must have a personal access token called ~/.github_auth with "repo" scope. Use steps similar to "Vault Secret" to create this file. - -For example: -[source, txt] ------ -./dev-tools/xes_release_notes.pl v5.5.2 > ~/tmp/5.5.2.asciidoc ------ +To build the Elasticsearch Reference on your local machine, use the `docbldes` +or `docbldesx` build commands defined in +https://github.com/elastic/docs/blob/master/doc_build_aliases.sh == Adding Images -When you include an image in the documentation, specify the path relative to the location of the asciidoc file. By convention, we put images in an `images` subdirectory. +When you include an image in the documentation, specify the path relative to the +location of the asciidoc file. By convention, we put images in an `images` +subdirectory. For example to insert `watcher-ui-edit-watch.png` in `watcher/limitations.asciidoc`: -. Add an `images` subdirectory to the watcher directory if it doesn't already exist. +. Add an `images` subdirectory to the watcher directory if it doesn't already exist. . In `limitations.asciidoc` specify: + [source, txt] ----- image::images/watcher-ui-edit-watch.png["Editing a watch"] ----- - -Please note that image names and anchor IDs must be unique within the book, so do not use generic identifiers. + +Please note that image names and anchor IDs must be unique within the book, so +do not use generic identifiers. diff --git a/docs/en/commands/index.asciidoc b/docs/en/commands/index.asciidoc index e839a54935f..164d2fc0e84 100644 --- a/docs/en/commands/index.asciidoc +++ b/docs/en/commands/index.asciidoc @@ -10,6 +10,7 @@ * <> * <> * <> +* <> * <> * <> * <> @@ -19,6 +20,7 @@ include::certgen.asciidoc[] include::certutil.asciidoc[] include::migrate-tool.asciidoc[] +include::saml-metadata.asciidoc[] include::setup-passwords.asciidoc[] include::syskeygen.asciidoc[] include::users-command.asciidoc[] diff --git a/docs/en/commands/saml-metadata.asciidoc b/docs/en/commands/saml-metadata.asciidoc new file mode 100644 index 00000000000..b348d223a03 --- /dev/null +++ b/docs/en/commands/saml-metadata.asciidoc @@ -0,0 +1,108 @@ +[role="xpack"] +[[saml-metadata]] +== saml-metadata + +The `saml-metadata` command can be used to generate a SAML 2.0 Service Provider +Metadata file. + +[float] +=== Synopsis + +[source,shell] +-------------------------------------------------- +bin/x-pack/saml-metadata +[--realm ] +[--out ] [--batch] +[--attribute ] [--service-name ] +[--locale ] [--contacts] +([--organisation-name ] [--organisation-display-name ] [--organisation-url ]) +[-E ] +[-h, --help] ([-s, --silent] | [-v, --verbose]) +-------------------------------------------------- + +[float] +=== Description + +The SAML 2.0 specification provides a mechanism for Service Providers to +describe their capabilities and configuration using a _metadata file_. + +The `saml-metadata` command generates such a file, based on the configuration of +a SAML realm in {es}. + +Some SAML Identity Providers will allow you to automatically import a metadata +file when you configure the Elastic Stack as a Service Provider. + +[float] +=== Parameters + +`--attribute `:: Specifies a SAML attribute that should be +included as a `` element in the metadata. Any attribute +configured in the {es} realm is automatically included and does not need to be +specified as a commandline option. + +`--batch`:: Do not prompt for user input. + +`--contacts`:: Specifies that the metadata should include one or more +`` elements. The user will be prompted to enter the details for +each person. + +`-E `:: Configures an {es} setting. + +`-h, --help`:: Returns all of the command parameters. + +`--locale `:: Specifies the locale to use for metadata elements such as +``. Defaults to the JVM's default system locale. + +`--organisation-display-name ` element. +Only valid if `--organisation-name` is also specified. + +`--organisation-name `:: Specifies that an `` element should +be included in the metadata and provides the value for the ``. +If this is specified, then `--organisation-url` must also be specified. + +`--organisation-url `:: Specifies the value of the `` +element. This is required if `--organisation-name` is specified. + +`--out `:: Specifies a path for the output files. +Defaults to `saml-elasticsearch-metadata.xml` + +`--service-name `:: Specifies the value for the `` element in +the metadata. Defaults to `elasticsearch`. + +`--realm `:: Specifies the name of the realm for which the metadata +should be generated. This parameter is required if there is more than 1 `saml` +realm in your {es} configuration. + +`-s, --silent`:: Shows minimal output. + +`-v, --verbose`:: Shows verbose output. + +[float] +=== Examples + +The following command generates a default metadata file for the `saml1` realm: + +[source, sh] +-------------------------------------------------- +bin/x-pack/saml-metadata --realm saml1 +-------------------------------------------------- + +The file will be written to `saml-elasticsearch-metadata.xml`. +You may be prompted to provide the "friendlyName" value for any attributes that +are used by the realm. + +The following command generates a metadata file for the `saml2` realm, with a +`` of `kibana-finance`, a locale of `en-GB` and includes +`` elements and an `` element: + +[source, sh] +-------------------------------------------------- +bin/x-pack/saml-metadata --realm saml2 \ + --service-name kibana-finance \ + --locale en-GB \ + --contacts \ + --organisation-name "Mega Corp. Finance Team" \ + --organisation-url "http://mega.example.com/finance/" +-------------------------------------------------- + diff --git a/docs/en/security/authentication.asciidoc b/docs/en/security/authentication.asciidoc index e15f22eec56..6bf3c1bde75 100644 --- a/docs/en/security/authentication.asciidoc +++ b/docs/en/security/authentication.asciidoc @@ -170,6 +170,7 @@ is no password to manage or reset. From time-to-time you may find a reference to one of these users inside your logs, including <>. +[[how-authc-works]] === How Authentication Works Authentication in {security} is handled by one or more authentication services @@ -203,6 +204,13 @@ An internal realm where users are defined in files stored on each node in the Elasticsearch cluster. This realm supports an authentication token in the form of username and password, and is always available. See <>. +_saml_:: +A realm that facilitates authentication using the SAML 2.0 Web SSO protocol. +This realm is designed to support authentication through {kib}, and is non +intended for use in the REST API. See <>. + + + {security} also supports custom realms. If you need to integrate with another authentication system, you can build a custom realm plugin. For more information, see <>. @@ -321,6 +329,10 @@ include::authentication/pki-realm.asciidoc[] include::authentication/file-realm.asciidoc[] +include::authentication/saml-realm.asciidoc[] + include::authentication/custom-realm.asciidoc[] include::authentication/user-cache.asciidoc[] + +include::authentication/saml-guide.asciidoc[] diff --git a/docs/en/security/authentication/saml-guide.asciidoc b/docs/en/security/authentication/saml-guide.asciidoc new file mode 100644 index 00000000000..742e891d8a3 --- /dev/null +++ b/docs/en/security/authentication/saml-guide.asciidoc @@ -0,0 +1,815 @@ +[[saml-guide]] + +== Configuring SAML Single-Sign-On on the Elastic Stack + +The Elastic Stack supports SAML single-sign-on (SSO) into {kib}, using {es} as +a backend service. In SAML terminology, the Elastic Stack is operating as a +_Service Provider_. + +The other component that is needed to enable SAML single-sign-on is the +_Identity Provider_, which is a service that handles your credentials and +performs that actual authentication of users. + +If you are interested in configuring SSO into {kib}, then you will need to +provide {es} with information about your _Identity Provider_, and you will need +to register the Elastic Stack as a known _Service Provider_ within that +Identity Provider. There are also a few configuration changes that are +required in {kib} to activate the SAML authentication provider. + +NOTE: The SAML support in {kib} is designed on the expectation that it will be +the primary (or sole) authentication method for users of that {kib} instance. +Once you enable SAML authentication in {kib} it will affect all users who try +to login. The <> section provides more detail about how this works. + +=== The Identity Provider + +The Elastic Stack supports the SAML 2.0 _Web Browser SSO_ and the SAML +2.0 _Single Logout_ profiles and can integrate with any Identity Provider (IdP) +that supports at least the SAML 2.0 _Web Browser SSO Profile_. +It has been tested with a number of popular IdP implementations. + +This guide assumes that you have an existing IdP and wish to add {kib} as a +Service Provider. + +The Elastic Stack uses a standard SAML _metadata_ document, in XML format that +defines the capabilities and features of your IdP. You should be able to +download or generate such a document within your IdP administration interface. + +Download the IdP metadata document and store it within the `config` directory on +each {es} node. For the purposes of this guide, we will assume that you are +storing it as `config/saml/idp-metadata.xml`. + +The IdP will have been assigned an identifier (_EntityID_ in SAML terminology) +which is most commonly expressed in _Uniform Resource Identifier_ (URI) form. +Your admin interface may tell you what this is, or you might need to +read the metadata document to find it - look for the `entityID` attribute on the +`EntityDescriptor` element. + +Most IdPs will provide an appropriate metadata file with all the features that +the Elastic Stack requires, and should only require the configuration steps +described below. For completeness sake, the minimum requirements that the Elastic +Stack has for the IdP's metadata are: + +- An `` with an `entityID` that matches the {es} + <> +- An `` that supports the SAML 2.0 protocol + (`urn:oasis:names:tc:SAML:2.0:protocol`). +- At least one `` that is configured for _signing_ (that is, it + has `use="signing"` or leaves the `use` unspecified) +- A `` with binding of HTTP-Redirect + (`urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect`) +- If you wish to support <>, a `` + with binding of HTTP-Redirect + (`urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect`) + +The Elastic Stack requires that all messages from the IdP are signed. +For authentication `` messages, the signature may be applied to either +the response itself, or to the individual assertions. +For `` messages, the message itself must be signed, and the +signature should be provided as a URL parameter, as required by the HTTP-Redirect +binding. + +=== Configure {es} for SAML Authentication + +There are five configuration steps to enable SAML authentication in {es}: + +. Enable SSL/TLS for HTTP +. Enable the Token Service +. Create one or more SAML realms +. Configure role mappings +. Generate a SAML Metadata file for use by your Identity Provider _(optional)_ + +==== Enable TLS for HTTP + +If your {es} cluster is operating in production mode, then you must +configure the HTTP interface to use SSL/TLS before you can enable SAML +authentication. + +See <> for instructions on how to do this. + +==== Enable the Token Service + +The {es} SAML implementation makes use of the {es} Token Service. This service +is automatically enabled if you configure TLS on the HTTP interface, and can be +explicitly configured by including the following in your `elasticsearch.yml` file: + +[source, yaml] +------------------------------------------------------------ +xpack.security.authc.token.enabled: true +------------------------------------------------------------ + +[[saml-create-realm]] +==== Create a SAML Realm + +SAML authentication is enabled by configuring a SAML realm within the +authentication chain for {es}. + +This realm has a few mandatory settings, and a number of optional settings. +The available settings are described in detail in the +<>, this guide will walk you through +the most common settings. + +Create a realm by adding the following to your `elasticsearch.yml` +configuration file. Each configuration value is explained below. + +[source, yaml] +------------------------------------------------------------ +xpack.security.authc.realms.saml1: + type: saml + order: 2 + idp.metadata.path: saml/idp-metadata.xml + idp.entity_id: "https://sso.example.com/" + sp.entity_id: "https://kibana.example.com/" + sp.acs: "https://kibana.example.com/api/security/v1/saml" + sp.logout: "https://kibana.example.com/logout" + attributes.principal: "urn:oid:0.9.2342.19200300.100.1.1" + attributes.groups: "urn:oid:1.3.6.1.4.1.5923.1.5.1." +------------------------------------------------------------ + +IMPORTANT: SAML is used when authenticating via {kib}, but it is not an +effective means of authenticating directly to the {es} REST API. For this reason +we recommend that you include at least one additional realm such as the +<> in your authentication chain for use by API +clients. + +The configuration values used in the example above are: + +xpack.security.authc.realms.saml:: + This defines a new authentication realm named "saml1". + See <> for more explanation of realms. + +type:: The `type` must be `saml` +order:: + You should define a unique order on each realm in your authentication chain. + It is recommended that the SAML realm be at the bottom of your authentication + chain (that is, that it has the _highest_ order). + +idp.metadata.path:: + This is the path to the metadata file that you saved for your Identity Provider. + The path that you enter here is relative to your `config/` directory. + {security} will automatically monitor this file for changes and will + reload the configuration whenever it is updated. + +idp.entity_id:: + This is the identifier (SAML EntityID) that your IdP uses. + It should match the `entityID` attribute within the metadata file. + +sp.entity_id:: + This is a unique identifier for your {kib} instance, expressed as a URI. + You will use this value when you add {kib} as a service provider within your IdP. + We recommend that you use the base URL for your {kib} instance as the entity ID. + +sp.acs:: + The _Assertion Consumer Service_ (ACS) endpoint is the URL within {kib} that accepts + authentication messages from the IdP. + This ACS endpoint supports the SAML HTTP-POST binding only. + It must be a URL that is accessible from the web browser of the user who is + attempting to login to {kib}, it does not need to be directly accessible by {es} + or the IdP. + The correct value may vary depending on how you have installed {kib} and + whether there are any proxies involved, but it will typically be + `${kibana-url}/api/security/v1/saml` where _${kibana-url}_ is the base URL for + your {kib} instance. + +sp.logout:: + This is the URL within {kib} that accepts logout messages from the IdP. + Like the `sp.acs` URL, it must be accessible from the web browser, but does + not need to be directly accessible by {es} or the IdP. The correct value may + vary depending on how you have installed {kib} and whether there are any + proxies involved, but it will typically be `${kibana-url}/logout` where + _${kibana-url}_ is the base URL for your {kib} instance. + +attribute.principal:: See <>. +attribute.groups:: See <>. + +[[saml-attribute-mapping]] +==== Attribute Mapping + +When a user connects to {kib} through your Identity Provider, the Identity +Provider will supply a SAML Assertion about the user. The assertion will contain +an _Authentication Statement_ indicating that the user has successfully +authenticated to the IdP and one ore more _Attribute Statements_ that will +include _Attributes_ for the user. + +These attributes may include such things as: + +- the user's username +- the user's email address +- the user's groups or roles + +Attributes in SAML are named using a URI such as +`urn:oid:0.9.2342.19200300.100.1.1` or +`http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn`, and have one or +more values associated with them. + +These attribute identifiers vary between IdPs, and most IdPs offer ways to +customise the URIs and their associated value. + +{es} uses these attributes to infer information about the user who has +logged in, and they can be used for role mapping (below). + +In order for these attributes to be useful, {es} and the IdP need to have a +common via for the names of the attributes. This is done manually, by +configuring the IdP and the {security} SAML realm to use the same URI name for +each logical user attribute. + +The recommended steps for configuring these SAML attributes are as follows: + +. Consult your IdP to see what user attributes it can provide. + This varies greatly between providers, but you should be able to obtain a list + from the documentation, or from your local admin. + +. Read through the list of <> that {es} + supports, and decide which of them are useful to you, and can be provided by + your IdP. At a _minimum_, the `principal` attribute is required. + +. Configure your IdP to "release" those attributes to your {kib} SAML service + provider. This process varies by provider - some will provide a user interface + for this, while others may require that you edit configuration files. + Usually the IdP (or your local administrator) will have suggestions about what + URI to use for each attribute. You can simply accept those suggestions, as the + {es} service is entirely configurable and does not require that any specific + URIs are used. + +. Configure the SAML realm in {es} to associate the {es} user properties (see + <> below), to the URIs that you configured + in your IdP. In the example above, we have configured the `principal` and + `groups` attributes. + +===== Special Attribute Names + +In general, {es} expects that the configured value for an attribute will be a +URI such as `urn:oid:0.9.2342.19200300.100.1.1`, however there are some +additional names that can be used: + +`nameid`:: + This uses the SAML `NamedID` value instead of a SAML attribute. SAML + `NameID` elements are an optional, but frequently provided, field within a + SAML Assertion that the IdP may use to identify the Subject of that + Assertion. In some cases the `NameID` will relate to the user's login + identifier (username) wihin the IdP, but in many cases they will be + internally generated identifiers that have no obvious meaning outside + of the IdP. + +`nameid:persistent`:: + This uses the SAML `NameID` value, but only if the NameID format is + `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent`. + A SAML `NameID` element has an optional `Format` attribute that indicates + the semantics of the provided name. It is common for IdPs to be configured + with "transient" NameIDs that present a new identifier for each session. + Since it is rarely useful to use a transient NameID as part of an attribute + mapping, the "nameid:persistent" attribute name can be used as a safety + mechanism that will cause an error if you attempt to map from a `NameID` + that does not have a persistent value. + +_friendlyName_:: + A SAML attribute may have a _friendlyName_ in addition to its URI based name. + For example the attribute with a name of `urn:oid:0.9.2342.19200300.100.1.1` + might also have a friendlyName of `uid`. + You may use these friendly names within an attribute mapping, but it is + recommended that you use the URI based names, as friendlyNames are neither + standardized or mandatory. + +The example below configures a realm to use a persistent nameid for the principal, +and the attribute with the friendlyName "roles" for the user's groups. + +[source, yaml] +------------------------------------------------------------ +xpack.security.authc.realms.saml1: + type: saml + order: 2 + idp.metadata.path: saml/idp-metadata.xml + idp.entity_id: "https://sso.example.com/" + sp.entity_id: "https://kibana.example.com/" + sp.acs: "https://kibana.example.com/api/security/v1/saml" + attributes.principal: "nameid:persistent" + attributes.groups: "roles" +------------------------------------------------------------ + +[[saml-user-properties]] +===== {es} User Properties + +The {es} SAML realm can be configured to map SAML `attributes` to the +following properties on the authenticated user: + +principal:: _(Required)_ + This is the _username_ that will be applied to a user that authenticates + against this realm. + The `principal` appears in places such as the {es} audit logs. + +groups:: _(Recommended)_ + If you wish to use your IdP's concept of groups or roles as the basis for a + user's {es} privileges, you should map them with this attribute. + The `groups` are passed directly to your + <> + +name:: _(Optional)_ The user's full name. +mail:: _(Optional)_ The user's email address. +dn:: _(Optional)_ The user's X.500 _Distinguished Name_. + +===== Extracting partial values from SAML Attributes + +There are some occasions where the IdP's attribute may contain more information +than you wish to use within {es}. A common example of this is one where the +IdP works exclusively with email addresses, but you would like the user's +`principal` to use the _local-name_ part of the email address. +For example if their email address was `james.wong@staff.example.com`, then you +would like their principal to simply be `james.wong`. + +This can be achieved using the `attribute_patterns` setting in the {es} +realm, as demonstrated in the realm configuration below: + +[source, yaml] +------------------------------------------------------------ +xpack.security.authc.realms.saml1: + type: saml + order: 2 + idp.metadata.path: saml/idp-metadata.xml + idp.entity_id: "https://sso.example.com/" + sp.entity_id: "https://kibana.example.com/" + sp.acs: "https://kibana.example.com/api/security/v1/saml" + attributes.principal: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" + attribute_patterns.principal: "^([^@]+)@staff.example.com$" +------------------------------------------------------------ + +In this case, the user's `principal` is mapped from an email attribute, but a +regular expression is applied to the value before it is assigned to the user. +If the regular expression matches, then the result of the first group is used as +effective value. If the regular expression does not match then the attribute +mapping fails. + +In this example, the email address must belong to the `staff.example.com` domain, +and then the local-part (anything before the `@`) is used as the principal. +Any users who try to login using a different email domain will fail because the +regular expression will not match against their email address, and thus their +principal attribute - which is mandatory - will not be populated. + +IMPORTANT: Small mistakes in these regular expressions can have significant +security consequences. For example, if we accidentally left off the trailing +`$` from the example above, then we would match any email address where the +domain starts with `staff.example.com`, and this would accept an email +address such as `admin@staff.example.com.attacker.net`. It is important that +you make sure your regular expressions are as precise as possible so that +you do not inadvertently open an avenue for user impersonation attacks. + +[[saml-logout]] +==== SAML Logout + +The SAML protocol supports the concept of Single Logout (SLO). +The level of support for SLO varies between Identity Providers. +You should consult the documentation for your IdP to determine what Logout +services it offers. + +By default the Elastic Stack will support SAML SLO if the following are true: + +- Your IdP metadata specifies that the IdP offers a SLO service +- You configure `sp.logout` +- The setting `idp.use_single_logout` is not `false` + +===== IdP SLO Service + +One of the values that {es} reads from the IdP's SAML metadata is the +``. In order for Single Logout to work with the Elastic +stack, {es} requires that this exist and support a binding of +`urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect`. + +The Elastic Stack will send both `` and `` +messages to this service as appropriate. + +===== The sp.logout setting + +The {es} realm setting `sp.logout` specifies a URL in {kib} to which the IdP can +send both `` and `` messages. This service uses +the SAML HTTP-Redirect binding. + +{es} will process `` messages, and perform a global signout that +invalidates any existing {es} security tokens that are associated with the +provided SAML session. + +If you do not configure a value for `sp.logout`, {es} will refuse all +`` messages. + +NOTE: It is common for IdPs to require that `LogoutRequest` messages be signed, +so you may need to configure <>. + +===== The idp.use_single_logout setting + +If your IdP provides a `` but you do not wish to use it, +you can configure `idp.use_single_logout: false` in your SAML realm, and {es} +will ignore the SLO service that your IdP provides. In this case, when a user +logs out of {kib} it will invalidate their {es} session (security token), but +will not perform any logout at the IdP. + +===== Using {kib} without Single Logout + +If your IdP does not support Single Logout, or you choose not to use it, then +{kib} will perform a "local logout" only. + +This means that {kib} will invalidate the session token it is using to +communicate with {es}, but will not be able to perform any sort of invalidation +of the Identity Provider session. In most cases this will mean that {kib} users +are still considered to be logged in to the IdP. Consequently, if the user +navigates to the {kib} landing page, they will be automatically reauthenticated, +and will commence a new {kib} session without needing to enter any credentials. + +The possible solutions to this problem are: + +- Ask your IdP administrator or vendor to provide a Single Logout service +- If your Idp does provide a Single Logout Service, make sure it is included in + the IdP metadata file, and do _not_ set `idp.use_single_logout` to `false`. +- Advise your users to close their browser after logging out of {kib} +- Enable the `force_authn` setting on your SAML realm. This setting causes the + Elastic Stack to request fresh authentication from the IdP every time a user + attempts to log into {kib}. + This setting defaults to `false` because it can be a more cumbersome user + experience, but it can also be an effective protection to stop users + piggy-backing on existing IdP sessions. + + +[[saml-enc-sign]] +==== Encryption and Signing + +The Elastic Stack supports generating signed SAML messages (for authentication +and/or logout), verifying signed SAML messages from the IdP (for both +authentication and logout) and can process encrypted content. + +You can configure {es} for signing, encryption or both, with the same +or separate keys used for each of those. + +The Elastic Stack uses X.509 certificates with RSA private keys for SAML +cryptography. These keys can be generated using any standard SSL tool, including +the `certutil` tool that ships with X-Pack. + +Your IdP may require that the Elastic Stack have a cryptographic key for signing +SAML messages, and that you provide the corresponding signing certificate within +the Service Provider configuration (either within the Elastic Stack SAML +metadata file or manually configured within the IdP administration interface). +While most IdPs do not expected authentication requests to be signed, it is +commonly the case that signatures are required for logout requests. Your IdP +will validate these signatures against the signing certificate that has been +configured for the Elastic Stack Service Provider. + +Encryption certificates are rarely needed, but the Elastic Stack supports them +for cases where IdPs or local policies mandate their use. + +===== Generating certificates and keys. + +{es} supports certificates and keys in either PEM, PKCS#12 or JKS format. +Some Identity Providers are more restrictive in the formats they support, and +will require you to provide the certificates as a file in a particular format. +You should consult the documentation for your IdP to determine what formats they +support. Since PEM format is the most commonly supported format, the examples +below will generate certificates in that format. + +Using the {ref}/certutil.html[`certutil`] tool, you can generate a signing +certificate with the following command: + +[source, sh] +-------------------------------------------------- +bin/x-pack/certutil cert -pem -days 1100 -name saml-sign -out saml-sign.zip +-------------------------------------------------- + +This will + +- generate a certificate and key pair (the `cert` subcommand) +- create the files in PEM format (`-pem` option) +- generate a certificate that is valid for 3 years (`-days 1100`) +- name the certificate `saml-sign` (`-name` option) +- save the certificate and key in the `saml-sign.zip` file (`-out` option) + +The generated zip archive will contain 3 files: + +- `saml-sign.crt`, the public certificate to be used for signing +- `saml-sign.key`, the private key for the certificate +- `ca.crt`, a CA certificate that is not need, and can be ignored. + +Encryption certificates can be generated with the same process. + +===== Configuring {es} for Signing + +By default, {security} will sign _all_ outgoing SAML messages if a signing +key has been configured. + +If you wish to use *PEM formatted* keys and certificates for signing, then +you should configure the following settings on the SAML realm: + +`signing.certificate`:: +The path to the PEM formatted certificate file. e.g. `saml/saml-sign.crt` + +`signing.key`:: +The path to the PEM formatted key file. e.g. `saml/saml-sign.key` + +`signing.secure_key_passphrase`:: +The passphrase for the key, if the file is encypted. This is a +{ref}/secure-settings.html[secure setting] that must be set with the +`elasticsearch-keystore` tool. + +If you wish to use *PKCS#12 formatted* files or a *Java Keystore* for +signing, then you should configure the following settings on the SAML realm: + +`signing.keystore.path`:: +The path to the PKCS#12 or JKS keystore. e.g. `saml/saml-sign.p12` + +`signing.keystore.alias`:: +The alias of the key within the keystore. e.g. `signing-key` + +`signing.keystore.secure_password`:: +The passphrase for the keystore, if the file is encypted. This is a +{ref}/secure-settings.html[secure setting] that must be set with the +`elasticsearch-keystore` tool. + +If you wish to sign some, but not all outgoing *SAML messages*, then you +should configure the following setting on the SAML realm: + +`signing.saml_messages`:: +A list of message types to sign. A message type is identified by the +_local name_ of the XML element used for the message. Supported values +are: `AuthnRequest`, `LogoutRequest` and `LogoutResponse`. + +===== Configuring {es} for Encrypted Messages + +{security} supports a single key for message decryption. If a key is +configured, then {security} will attempt to use it to decrypt +`EncryptedAssertion` and `EncryptedAttribute` elements in Authentication +responses, and `EncryptedID` elements in Logout requests. + +{security} will reject any SAML message that contains an `EncryptedAssertion` +that cannot be decrypted. + +If an `Assertion` contains both encrypted and plain-text attributes, then +failure to decrypt the encrypted attributes will not cause an automatic +rejection. Rather, {security} will process the available plain-text attributes +(and any `EncryptedAttributes` that could be decrypted). + +If you wish to use *PEM formatted* keys and certificates for SAML encryption, +then you should configure the following settings on the SAML realm: + +`encryption.certificate`:: +The path to the PEM formatted certificate file. e.g. `saml/saml-crypt.crt` + +`encryption.key`:: +The path to the PEM formatted key file. e.g. `saml/saml-crypt.key` + +`encryption.secure_key_passphrase`:: +The passphrase for the key, if the file is encypted. This is a +{ref}/secure-settings.html[secure setting] that must be set with the +`elasticsearch-keystore` tool. + +If you wish to use *PKCS#12 formatted* files or a *Java Keystore* for SAML +encryption, then you should configure the following settings on the SAML realm: + +`encryption.keystore.path`:: +The path to the PKCS#12 or JKS keystore. e.g. `saml/saml-crypt.p12` + +`encryption.keystore.alias`:: +The alias of the key within the keystore. e.g. `encryption-key` + +`encryption.keystore.secure_password`:: +The passphrase for the keystore, if the file is encypted. This is a +{ref}/secure-settings.html[secure setting] that must be set with the +`elasticsearch-keystore` tool. + +=== Generating SP metadata + +Some Identity Providers support importing a metadata file from the Service +Provider. This will automatically configure many of the integration options +between the IdP and the SP. + +The Elastic Stack supports generating such a metadata file using the +`bin/x-pack/saml-metadata` command in your {es} directory. + +The {ref}/saml-metadata.html[documentation for the saml-metadata utility] +describes how to run it, and the available command line options. + +[[saml-role-mapping]] +=== Configuring Role Mappings + +When a user authenticates using SAML, they are identified to the Elastic Stack, +but this does not automatically grant them access to perform any actions or +access any data. + +Your SAML users cannot do anything until they are mapped to X-Pack Security +roles. This mapping is performed through the +{ref}/security-api-role-mapping.html[role-mapping API] + +This is an example of a simple role mapping that grants the `kibana_user` role +to any user who authenticates against the `saml1` realm: + +[source,js] +-------------------------------------------------- +PUT /_xpack/security/role_mapping/saml-kibana +{ + "roles": [ "kibana_user" ], + "enabled": true, + "rules": { + "field": { "realm.name": "saml1" } + } +} +-------------------------------------------------- +// CONSOLE +// TEST + + +The attributes that are mapped via the realm configuration are used to process +role mapping rules, and these rules determine which roles a user is granted. + +The <> that are provided to the role +mapping are derived from the SAML attributes as follows: + +- `username`: The `principal` attribute +- `dn`: The `dn` attribute +- `groups`: The `groups` attribute +- `metadata`: See <> + +If your IdP has the ability to provide groups or roles to Service Providers, +then you should map this SAML attribute to the `attributes.groups` setting in +the {es} realm, and then make use of it in a role mapping as per the example +below. + +This mapping grants the {es} `finance_data` role, to any users who authenticate +via the `saml1` realm with the `finance-team` group. + +[source,js] +-------------------------------------------------- +PUT /_xpack/security/role_mapping/saml-finance +{ + "roles": [ "finance_data" ], + "enabled": true, + "rules": { "all": [ + { "field": { "realm.name": "saml1" } }, + { "field": { "groups": "finance-team" } } + ] } +} +-------------------------------------------------- +// CONSOLE +// TEST + +[[saml-user-metadata]] +=== User Metadata + +By default users who authenticate via SAML will have some additional metadata +fields. + +- `saml_nameid` will be set to the value of the `NameID` element in the SAML + authentication response +- `saml_nameid_format` will be set to the full URI of the NameID's `format` + attribute +- Every SAML Attribute that is provided in the authentication response + (regardless of whether it is mapped to an {es} user property), will be added + as the metadata field `saml(name)` where "name" is the full URI name of the + attribute. For example `saml(urn:oid:0.9.2342.19200300.100.1.3)`. +- For every SAML Attribute that has a _friendlyName_, will also be added as the + metadata field `saml_friendlyName` where "name" is the full URI name of the + attribute. For example `saml_mail`. + +This behaviour can be disabled by adding `populate_user_metadata: false` to as +a setting in the saml realm. + +[[saml-kibana]] +=== Configuring {kib} + +SAML authentication in {kib} requires a small number of additional settings +in addition to the standard {kib} security configuration. The +{kibana-ref}/using-kibana-with-security.html[{kib} security documentation] +provides details on the available configuration options that you can apply. + +In particular, since your {es} nodes have been configured to use TLS on the HTTP +interface, you must configure {kib} to use a `https` URL to connect to {es}, and +you may need to configure `elasticsearch.ssl.certificateAuthorities` to trust +the certificates that {es} has been configured to use. + +SAML authentication in {kib} is also subject to the +`xpack.security.sessionTimeout` setting that is described in the {kib} security +documentation, and you may wish to adjst this timeout to meet your local needs. + +The two additional settings that are required for SAML support are shown below: + +[source, yaml] +------------------------------------------------------------ +xpack.security.authProviders: [saml] +server.xsrf.whitelist: [/api/security/v1/saml] +------------------------------------------------------------ + +The configuration values used in the example above are: + +`xpack.security.authProviders`:: +Set this to `[ saml ]` to instruct {kib} to use SAML SSO as the authentication +method. + +`server.xsrf.whitelist`:: +{kib} has in-built protection against _Cross Site Request Forgery_ attacks which +are designed to prevent the {kib} server from processing requests that +originated from outside the {kib} application. +In order to support SAML authentication messages that originate from your +Identity Provider, we need to explicitly _whitelist_ the SAML authentication URL +within {kib}, so that the {kib} server will not reject these external messages. + +If your {kib} instance is behind a proxy, you may also need to add configuration +to tell {kib} how to form its public URL. This is needed because all SAML +messages are exchanged via the user's web browser, so {kib} needs to know what +URLs are used within the browser. In this case, the following settings should be +added to your `kibana.yml` configuration file: + +[source, yaml] +------------------------------------------------------------ +xpack.security.public: + protocol: https + hostname: kibana.proxy.com + port: 443 +------------------------------------------------------------ + +`xpack.security.public.protocol`:: +This is the protocol that the user's web browser uses to connect to the proxy. +Must be one of `http` or `https`. It is strongly recommended that you use the +`https` protocol for all access to {kib}. + +`xpack.security.public.hostname`:: +The fully qualified hostname that your users use to connect to the proxy server. + +`xpack.security.public.port`:: +The port number that your users use to connect to the proxy server (e.g. `80` +for `http` or `443` for `https`). + +These values must be aligned with the URLs used in the {es} configuration for +`sp.acs` and `sp.logout`. + +==== Supporting SAML and Basic authentication in {kib} + +The SAML support in {kib} is designed on the expectation that it will be the +primary (or sole) authentication method for users of that {kib} instance. +However, it is possible to support both SAML and Basic authentication within a +single {kib} instance by setting `xpack.security.authProviders` as per the +example below: + +[source, yaml] +------------------------------------------------------------ +xpack.security.authProviders: [saml, basic] +------------------------------------------------------------ + +The order is important - this will _initiate_ SAML authentication for +unauthenticated users, but will _accept_ basic authentication. + +If {kib} is configured in this way, then users who wish to login with a +username and password, can do so by directly accessing the `/login` page in +{kib}. This login will not use SAML credentials, and will rely on one of the +other security realms within {es}. Only users who have a username and password +for a configured {es} authentication realm will be able to login via this page. + +Alternatively, when the `basic` authentication provider is enabled, you can +place a reverse proxy in front of {kib}, and configure it to send a basic +authentication header (`Authorization: Basic ....`) for each request. +If this header is present and valid, {kib} will not initiate the SAML +authentication process. + +==== Operating multiple {kib} instances + +If you wish to have multiple {kib} instances that authenticate against the same +{es} cluster, then each {kib} instance that is configured for SAML authentication, +requires its own SAML realm. + +Each SAML realm must have its own unique Entity ID (`sp.entity_id`), and its own +_Assertion Consumer Service_ (`sp.acs`). Each {kib} instance will be mapped to +the correct realm by looking up the matching `sp.acs` value. + +These realms may use the same Identity Provider, but are not required to. + +The following is example of having 3 difference {kib} instances, 2 of which +use the same internal IdP, and another which uses a different IdP. + +[source, yaml] +------------------------------------------------------------ +xpack.security.authc.realms.saml_finance: + type: saml + order: 2 + idp.metadata.path: saml/idp-metadata.xml + idp.entity_id: "https://sso.example.com/" + sp.entity_id: "https://kibana.finance.example.com/" + sp.acs: "https://kibana.finance.example.com/api/security/v1/saml" + sp.logout: "https://kibana.finance.example.com/logout" + attributes.principal: "urn:oid:0.9.2342.19200300.100.1.1" + attributes.groups: "urn:oid:1.3.6.1.4.1.5923.1.5.1." +xpack.security.authc.realms.saml_sales: + type: saml + order: 3 + idp.metadata.path: saml/idp-metadata.xml + idp.entity_id: "https://sso.example.com/" + sp.entity_id: "https://kibana.sales.example.com/" + sp.acs: "https://kibana.sales.example.com/api/security/v1/saml" + sp.logout: "https://kibana.sales.example.com/logout" + attributes.principal: "urn:oid:0.9.2342.19200300.100.1.1" + attributes.groups: "urn:oid:1.3.6.1.4.1.5923.1.5.1." +xpack.security.authc.realms.saml_eng: + type: saml + order: 4 + idp.metadata.path: saml/idp-external.xml + idp.entity_id: "https://engineering.sso.example.net/" + sp.entity_id: "https://kibana.engineering.example.com/" + sp.acs: "https://kibana.engineering.example.com/api/security/v1/saml" + sp.logout: "https://kibana.engineering.example.com/logout" + attributes.principal: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" +------------------------------------------------------------ + +It is possible to have one or more {kib} instances that use SAML, while other +instances use basic authentication against another realm type (e.g. +<> or <>). + diff --git a/docs/en/security/authentication/saml-realm.asciidoc b/docs/en/security/authentication/saml-realm.asciidoc new file mode 100644 index 00000000000..2f40b300931 --- /dev/null +++ b/docs/en/security/authentication/saml-realm.asciidoc @@ -0,0 +1,244 @@ +[[saml-realm]] +=== SAML Authentication +{security} supports user authentication using SAML Single Sign On. +{security} provides this support using the Web Browser SSO profile of the SAML +2.0 protocol. + +This protocol is specifically designed to support authentication via an +interactive web browser, so it does not operate as a standard authentication +realm. Instead, {security} provides features in {kib} and {es} that work +together to enable interactive SAML sessions. + +This means that the SAML realm is not suitable for use by standard REST clients. +If you configure a SAML realm for use in {kib}, you should also configure +another realm, such as the <> in your authentication +chain. + +In order to simplify the process of configuring SAML authentication within the +Elastic Stack, there is a step-by-step guide to +<>. + +The remainder of this document will describe {es} specific configuration options +for SAML realms. + + +[[saml-settings]] +==== SAML Realm Settings + +[cols="4,^3,10"] +|======================= +| Setting | Required | Description +| `type` | yes | Indicates the realm type. Must be set to `saml`. +| `order` | no | Indicates the priority of this realm within the realm chain. + Realms with a lower order are consulted first. Although not + required, we recommend explicitly setting this value when + you configure multiple realms. Defaults to `Integer.MAX_VALUE`. +| `enabled` | no | Indicates whether this realm is enabled or disabled. Enables + you to disable a realm without removing its configuration. + Defaults to `true`. +| `idp.entity_id` | yes | The Entity ID of the SAML Identity Provider +| `idp.metadata.path` | yes | The path (_recommended_) or URL to a SAML 2.0 metadata file + describing the capabilities and configuration of the Identity + Provider. + If a path is provided, then it is resolved relative to the + {es} config directory. + If a URL is provided, then it must be either a `file` URL or + a `https` URL. + {security} will automatically poll this metadata resource and + will reload the IdP configuration when changes are detected. + File based resources are polled at a frequency determined by + the global {es} `resource.reload.interval.high` setting, which + defaults to 5 seconds. + HTTPS resources are polled at a frequency determined by + the realm's `idp.metadata.http.refresh` setting. +| `idp.metadata.http.refresh` | no | Controls the frequency with which `https` metadata is checked + for changes. Defaults to 1 hour. +| `idp.use_single_logout` | no | Indicates whether to utilise the Identity Provider's Single + Logout service (if one exists in the IdP metadata file). + Defaults to `true`. +| `sp.entity_id` | yes | The Entity ID to use for this SAML Service Provider. + This should be entered as a URI. We recommend that you use the + base URL of your {kib} instance, + e.g. `https://kibana.example.com/` +| `sp.acs` | yes | The URL of the Assertion Consumer Service within {kib}. + Typically this will be the "api/security/v1/saml" endpoint of + your {kib} server, + e.g. `https://kibana.example.com/api/security/v1/saml` +| `sp.logout` | no | The URL of the Single Logout service within {kib}. + Typically this will be the "logout" endpoint of + your {kib} server, + e.g. `https://kibana.example.com/logout` +| `attributes.principal` | yes | The Name of the SAML attribute that should be used as the + {security} user's principal (username) +| `attributes.groups` | no | The Name of the SAML attribute that should be used to populate + {security} user's groups +| `attributes.name` | no | The Name of the SAML attribute that should be used to populate + {security} user's full name +| `attributes.mail` | no | The Name of the SAML attribute that should be used to populate + {security} user's email address +| `attributes.dn` | no | The Name of the SAML attribute that should be used to populate + {security} user's X.500 _Distinguished Name_ +| `attribute_patterns.principal` | no | A java regular expression that is matched against the SAML attribute + specified by `attributes.pattern` before it is applied to the user's + _principal_ property. + The attribute value must match the pattern, and the value of the + first _capturing group_ is used as the principal. + e.g. `^([^@]+)@example.com$` matches email addresses from the + "example.com" domain and uses the local-part as the principal. +| `attribute_patterns.groups` | no | As per `attribute_patterns.principal`, but for the _group_ property. +| `attribute_patterns.name` | no | As per `attribute_patterns.principal`, but for the _name_ property. +| `attribute_patterns.mail` | no | As per `attribute_patterns.principal`, but for the _mail_ property. +| `attribute_patterns.dn` | no | As per `attribute_patterns.principal`, but for the _dn_ property. +| `nameid_format` | no | The NameID format that should be requested when asking the IdP + to authenticate the current user. + Defaults to requesting _transient_ names + (`urn:oasis:names:tc:SAML:2.0:nameid-format:transient`) +| `force_authn` | no | Whether to set the `ForceAuthn` attribute when requesting that the + IdP authenticate the current user. If this is set to `true`, the + IdP will be required to freshly establish the user's identity, + irrespective of any exiting sessions they may have. + Defaults to `false`. +| `populate_user_metadata` | no | Whether to populate the {es} user's metadata with the values that + are provided by the SAML attributes. Defaults to `true`. +| `allowed_clock_skew` | no | The maximum amount of skew that can be tolerated between the + IdP's clock and the {es} node's clock. Defaults to 3 minutes. +|======================= + +===== SAML Realm Signing Settings + +If a signing key is configured (i.e. is one of `signing.key` or `signing.keystore.path` has been set), then +{security} will sign outgoing SAML messages. Signing can be configured using the following settings. + +|======================= +| Setting | Required | Description +| `signing.saml_messages` | no | A list of SAML message types that should be signed, or `*` to + sign all messages. Each element in the list should be the + local name of a SAML XML Element. Supported element types are + `AuthnRequest`, `LogoutRequest` and `LogoutResponse`. + Defaults to `*`. +| `signing.key` | no | Specifies the path to the PEM encoded private key to use for + SAML message signing. + `signing.key` and `signing.keystore.path` may not be used at + the same time. +| `signing.secure_key_passphrase` | no | ({ref}/secure-settings.html[Secure]) + Specifies the passphrase to decrypt the PEM encoded private key if + it is encrypted. +| `signing.certificate` | no | Specifies the path to the PEM encoded certificate (or certificate + chain) that corresponds to the `signing.key`. This certificate + must also be included in the Service Provider metadata, or + manually configured within the IdP to allow for signature + validation. + May only be used if `signing.key` is set. +| `signing.keystore.path` | no | The path to the keystore that contains a private key and + certificate. + Must be either a Java Keystore (jks) or a PKCS#12 file. + `signing.key` and `signing.keystore.path` may not be used at the + same time. +| `signing.keystore.type` | no | The type of the keystore. Must be one of "jks" or "PKCS12". + Defaults to "PKCS12" if the keystore path ends in ".p12", ".pfx" or + "pkcs12", otherwise uses "jks" +| `signing.keystore.alias` | no | Specifies the alias of the key within the keystore that should be + used for SAML message signing. Defaults to `key`. +| `signing.keystore.secure_password` | no | ({ref}/secure-settings.html[Secure]) The password to the keystore. +| `signing.keystore.secure_key_password` | no | ({ref}/secure-settings.html[Secure]) + The password for the key in the keystore. + Defaults to the keystore password. +|======================= + +===== SAML Realm Encryption Settings + +If an encryption key is configured (i.e. is one of `encryption.key` or +`encryption.keystore.path` has been set), then {security} will publish +an encryption certificate when generating metadata, and will attempt to +decrypt incoming SAML content. +Encryption can be configured using the following settings. + +|======================= +| Setting | Required | Description +| `encryption.key` | no | Specifies the path to the PEM encoded private key to use for + SAML message descryption. + `encryption.key` and `encryption.keystore.path` may not be used at + the same time. +| `encryption.secure_key_passphrase` | no | ({ref}/secure-settings.html[Secure]) + Specifies the passphrase to decrypt the PEM encoded private key if + it is encrypted. +| `encryption.certificate` | no | Specifies the path to the PEM encoded certificate (or certificate + chain) that is associated with the `encryption.key`. This + certificate must also be included in the Service Provider metadata, + or manually configured within the IdP to enable message encryption. + May only be used if `encryption.key` is set. +| `encryption.keystore.path` | no | The path to the keystore that contains a private key and + certificate. + Must be either a Java Keystore (jks) or a PKCS#12 file. + `encryption.key` and `encryption.keystore.path` may not be used at + the same time. +| `encryption.keystore.type` | no | The type of the keystore. Must be one of "jks" or "PKCS12". + Defaults to "PKCS12" if the keystore path ends in ".p12", ".pfx" or + "pkcs12", otherwise uses "jks" +| `encryption.keystore.alias` | no | Specifies the alias of the key within the keystore that should be + used for SAML message encryption. Defaults to `key`. +| `encryption.keystore.secure_password` | no | ({ref}/secure-settings.html[Secure]) The password to the keystore. +| `encryption.keystore.secure_key_password` | no | ({ref}/secure-settings.html[Secure]) + The password for the key in the keystore. +|======================= + +===== SAML Realm SSL Settings + +If you are loading the IdP metadata over SSL/TLS (that is, `idp.metadata.path` is a URL using the `https` protocol) +Then the following settings may be used to configure SSL. If these are not specified, then the {xpack} +{ref}/security-settings.html#ssl-tls-settings[default SSL settings] are used. + +These settings are not used for any purpose other than loading metadata over https. + +|======================= +| Setting | Required | Description +| `ssl.key` | no | Specifies the path to the PEM encoded private key to use for http + client authentication. + `ssl.key` and `ssl.keystore.path` may not be used at the same time. +| `ssl.key_passphrase` | no | Specifies the passphrase to decrypt the PEM encoded private key if + it is encrypted. May not be used with `ssl.secure_key_passphrase` +| `ssl.secure_key_passphrase` | no | ({ref}/secure-settings.html[Secure]) + Specifies the passphrase to decrypt the PEM encoded private key if + it is encrypted. May not be used with `ssl.key_passphrase` +| `ssl.certificate` | no | Specifies the path to the PEM encoded certificate (or certificate + chain) that goes with the key. May only be used if `ssl.key` is set. +| `ssl.certificate_authorities` | no | Specifies the paths to the PEM encoded certificate authority + certificates that should be trusted. + `ssl.certificate_authorities` and `ssl.truststore.path` may not be + used at the same time. +| `ssl.keystore.path` | no | The path to the keystore that contains a private key and + certificate. + Must be either a Java Keystore (jks) or a PKCS#12 file. + `ssl.key` and `ssl.keystore.path` may not be used at the same time. +| `ssl.keystore.type` | no | The type of the keystore. Must be one of "jks" or "PKCS12". + Defaults to "PKCS12" if the keystore path ends in ".p12", ".pfx" or + "pkcs12", otherwise uses "jks" +| `ssl.keystore.password` | no | The password to the keystore. + May not be used with `ssl.keystore.secure_password`. +| `ssl.keystore.secure_password` | no | ({ref}/secure-settings.html[Secure]) The password to the keystore. + May not be used with `ssl.keystore.password`. +| `ssl.keystore.key_password` | no | The password for the key in the keystore. + Defaults to the keystore password. + May not be used with `ssl.keystore.secure_key_password`. +| `ssl.keystore.secure_key_password` | no | ({ref}/secure-settings.html[Secure]) + The password for the key in the keystore. + Defaults to the keystore password. + May not be used with `ssl.keystore.key_password`. +| `ssl.truststore.path` | no | The path to the keystore that contains the certificates to trust. + Must be either a Java Keystore (jks) or a PKCS#12 file. + `ssl.certificate_authorities` and `ssl.truststore.path` may not be + used at the same time. +| `ssl.truststore.type` | no | The type of the truststore. Must be one of "jks" or "PKCS12". + Defaults to "PKCS12" if the keystore path ends in ".p12", ".pfx" or + "pkcs12", otherwise uses "jks" +| `ssl.truststore.password` | no | The password to the truststore. + May not be used with `ssl.truststore.secure_password`. +| `ssl.truststore.secure_password` | no | ({ref}/secure-settings.html[Secure]) The password to the truststore. + May not be used with `ssl.truststore.password`. +| `ssl.verification_mode` | no | One of `full` (verify the hostname and the certicate path), + `certificate` (verify the certificate path, but not the hostname) + or `none` (perform no verification). Defaults to `full`. +| `ssl.supported_protocols` | no | Specifies the supported protocols for TLS/SSL. +| `ssl.cipher_suites` | no | Specifies the cipher suites that should be supported. +|======================= + diff --git a/docs/en/security/how-security-works.asciidoc b/docs/en/security/how-security-works.asciidoc index 7eba901747b..8cd7befc642 100644 --- a/docs/en/security/how-security-works.asciidoc +++ b/docs/en/security/how-security-works.asciidoc @@ -49,6 +49,9 @@ _realms_. {security} provides the following built-in realms: With this realm, users are authenticated by usernames and passwords. The users are managed via dedicated tools that are provided by {xpack} on installation. + +| `saml` | | | A realm that uses SAML 2.0 Web SSO. This realm is + designed to be used with {kib}. |====== If none of the built-in realms meets your needs, you can also build your own diff --git a/docs/en/settings/security-settings.asciidoc b/docs/en/settings/security-settings.asciidoc index 2e152cf6add..da68c594dbf 100644 --- a/docs/en/settings/security-settings.asciidoc +++ b/docs/en/settings/security-settings.asciidoc @@ -622,6 +622,263 @@ Specifies the {xpack-ref}/security-files.html[location] of the {xpack-ref}/mapping-roles.html[YAML role mapping configuration file]. Defaults to `CONFIG_DIR/x-pack/role_mapping.yml`. +[[ref-saml-settings]] +[float] +===== SAML Realm Settings +`idp.entity_id`:: +The Entity ID of the SAML Identity Provider + +`idp.metadata.path`:: +The path _(recommended)_ or URL to a SAML 2.0 metadata file describing the +capabilities and configuration of the Identity Provider. +If a path is provided, then it is resolved relative to the {es} config +directory. +If a URL is provided, then it must be either a `file` URL or a `https` URL. +{security} will automatically poll this metadata resource and will reload +the IdP configuration when changes are detected. +File based resources are polled at a frequency determined by the global {es} +`resource.reload.interval.high` setting, which defaults to 5 seconds. +HTTPS resources are polled at a frequency determined by the realm's +`idp.metadata.http.refresh` setting. + +`idp.metadata.http.refresh`:: +Controls the frequency with which `https` metadata is checked for changes. +Defaults to `1h` (1 hour). + +`idp.use_single_logout`:: +Indicates whether to utilise the Identity Provider's Single Logout service +(if one exists in the IdP metadata file). +Defaults to `true`. + +`sp.entity_id`:: +The Entity ID to use for this SAML Service Provider, entered as a URI. + +`sp.acs`:: +The URL of the Assertion Consumer Service within {kib}. + +`sp.logout`:: +The URL of the Single Logout service within {kib}. + +`attributes.principal`:: +The Name of the SAML attribute that should be used as the {security} user's +principal (username) + +`attributes.groups`:: +The Name of the SAML attribute that should be used to populate {security} +user's groups + +`attributes.name`:: +The Name of the SAML attribute that should be used to populate {security} +user's full name + +`attributes.mail`:: +The Name of the SAML attribute that should be used to populate {security} +user's email address + +`attributes.dn`:: +The Name of the SAML attribute that should be used to populate {security} +user's X.500 _Distinguished Name_ + +`attribute_patterns.principal`:: +A java regular expression that is matched against the SAML attribute specified +by `attributes.pattern` before it is applied to the user's _principal_ property. +The attribute value must match the pattern, and the value of the first +_capturing group_ is used as the principal. + +`attribute_patterns.groups`:: +As per `attribute_patterns.principal`, but for the _group_ property. + +`attribute_patterns.name`:: +As per `attribute_patterns.principal`, but for the _name_ property. + +`attribute_patterns.mail`:: +As per `attribute_patterns.principal`, but for the _mail_ property. + +`attribute_patterns.dn`:: +As per `attribute_patterns.principal`, but for the _dn_ property. + +`nameid_format`:: +The NameID format that should be requested when asking the IdP to authenticate +the current user. +Defaults to `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` + +`force_authn`:: +Whether to set the `ForceAuthn` attribute when requesting that the IdP +authenticate the current user. +Defaults to `false`. + +`populate_user_metadata`:: +Whether to populate the {es} user's metadata with the values that are provided +by the SAML attributes. +Defaults to `true`. + +`allowed_clock_skew`:: +The maximum amount of skew that can be tolerated between the IdP's clock and the +{es} node's clock. +Defaults to `3m` (3 minutes). + +`signing.saml_messages`:: +A list of SAML message types that should be signed, or `*` to sign all messages. +Each element in the list should be the local name of a SAML XML Element. +Supported element types are `AuthnRequest`, `LogoutRequest` and `LogoutResponse`. +Only valid if `signing.key` or `signing.keystore.path` is also specified. +Defaults to `*`. + +`signing.key`:: +Specifies the path to the PEM encoded private key to use for SAML message signing. +`signing.key` and `signing.keystore.path` may not be used at the same time. + +`signing.secure_key_passphrase` (<>):: +Specifies the passphrase to decrypt the PEM encoded private key (`signing.key`) +if it is encrypted. + +`signing.certificate`:: +Specifies the path to the PEM encoded certificate that corresponds to the +`signing.key`. May only be used if `signing.key` is set. + +`signing.keystore.path`:: +The path to the keystore that contains a private key and certificate. +Must be either a Java Keystore (jks) or a PKCS#12 file. +`signing.key` and `signing.keystore.path` may not be used at the same time. + +`signing.keystore.type`:: +The type of the keystore (`signing.keystore.path`). +Must be one of "jks" or "PKCS12". Defaults to "PKCS12" if the keystore path +ends in ".p12", ".pfx" or "pkcs12", otherwise uses "jks". + +`signing.keystore.alias`:: +Specifies the alias of the key within the keystore that should be +used for SAML message signing. Defaults to `key`. + +`signing.keystore.secure_password` (<>):: +The password to the keystore (`signing.keystore.path`). + +`signing.keystore.secure_key_password` (<>):: +The password for the key in the keystore (`signing.keystore.path`). +Defaults to the keystore password. + +`encryption.key`:: +Specifies the path to the PEM encoded private key to use for SAML message +decryption. +`encryption.key` and `encryption.keystore.path` may not be used at the same time. + +`encryption.secure_key_passphrase` (<>):: +Specifies the passphrase to decrypt the PEM encoded private key +(`encryption.key`) if it is encrypted. + +`encryption.certificate`:: +Specifies the path to the PEM encoded certificate chain that is associated with +the `encryption.key`. May only be used if `encryption.key` is set. + +`encryption.keystore.path`:: +The path to the keystore that contains a private key and certificate. +Must be either a Java Keystore (jks) or a PKCS#12 file. +`encryption.key` and `encryption.keystore.path` may not be used at the same time. + +`encryption.keystore.type`:: +The type of the keystore (`encryption.keystore.path`). +Must be one of "jks" or "PKCS12". Defaults to "PKCS12" if the keystore path +ends in ".p12", ".pfx" or "pkcs12", otherwise uses "jks". + +`encryption.keystore.alias`:: +Specifies the alias of the key within the keystore (`encryption.keystore.path`) +that should be used for SAML message decryption. Defaults to `key`. + +`encryption.keystore.secure_password` (<>):: +The password to the keystore (`encryption.keystore.path`). + +`encryption.keystore.secure_key_password` (<>):: +The password for the key in the keystore (`encryption.keystore.path`) . + +`ssl.key`:: +If retrieving IDP metadata via https (see `idp.metadata.path`), specifies the +path to the PEM encoded private key to use for http client authentication (if +required). `ssl.key` and `ssl.keystore.path` may not be used at the same time. + +`ssl.key_passphrase`:: +If retrieving IDP metadata via https (see `idp.metadata.path`), specifies the +passphrase to decrypt the PEM encoded private key (`ssl.key`) if it is +encrypted. May not be used with `ssl.secure_key_passphrase` + +`ssl.secure_key_passphrase` (<>):: +If retrieving IDP metadata via https (see `idp.metadata.path`), specifies the +passphrase to decrypt the PEM encoded private key (`ssl.key`) if it is +encrypted. May not be used with `ssl.key_passphrase` + +`ssl.certificate`:: +If retrieving IDP metadata via https (see `idp.metadata.path`), specifies the +path to the PEM encoded certificate (or certificate chain) that is associated +with the key (`ssl.key`). May only be used if `ssl.key` is set. + +`ssl.certificate_authorities`:: +If retrieving IDP metadata via https (see `idp.metadata.path`), specifies the +paths to the PEM encoded certificate authority certificates that should be +trusted. `ssl.certificate_authorities` and `ssl.truststore.path` may not be +used at the same time. + +`ssl.keystore.path`:: +If retrieving IDP metadata via https (see `idp.metadata.path`), the path to +the keystore that contains a private key and certificate. +Must be either a Java Keystore (jks) or a PKCS#12 file. +`ssl.key` and `ssl.keystore.path` may not be used at the same time. + +`ssl.keystore.type`:: +The type of the keystore (`ssl.keystore.path`). Must be one of "jks" or "PKCS12". +Defaults to "PKCS12" if the keystore path ends in ".p12", ".pfx" or "pkcs12", +otherwise uses "jks" + +`ssl.keystore.password`:: +The password to the keystore (`ssl.keystore.path`). +May not be used with `ssl.keystore.secure_password`. + +`ssl.keystore.secure_password` (<>):: +The password to the keystore (`ssl.keystore.path`). +May not be used with `ssl.keystore.password`. + +`ssl.keystore.key_password`:: +The password for the key in the keystore (`ssl.keystore.path`). +Defaults to the keystore password. +May not be used with `ssl.keystore.secure_key_password`. + +`ssl.keystore.secure_key_password` (<>):: +The password for the key in the keystore (`ssl.keystore.path`). +Defaults to the keystore password. +May not be used with `ssl.keystore.key_password`. + +`ssl.truststore.path`:: +If retrieving IDP metadata via https (see `idp.metadata.path`), the path to the +keystore that contains the certificates to trust. +Must be either a Java Keystore (jks) or a PKCS#12 file. +`ssl.certificate_authorities` and `ssl.truststore.path` may not be used at the +same time. + +`ssl.truststore.type`:: +The type of the truststore (`ssl.truststore.path`). Must be one of "jks" or "PKCS12". +Defaults to "PKCS12" if the keystore path ends in ".p12", ".pfx" or "pkcs12", +otherwise uses "jks" + +`ssl.truststore.password`:: +The password to the truststore (`ssl.truststore.path`). +May not be used with `ssl.truststore.secure_password`. + +`ssl.truststore.secure_password` (<>):: +The password to the truststore (`ssl.truststore.path`). +May not be used with `ssl.truststore.password`. + +`ssl.verification_mode`:: +If retrieving IDP metadata via https (see `idp.metadata.path`), one of `full` +(verify the hostname and the certicate path), `certificate` (verify the +certificate path, but not the hostname) or `none` (perform no verification). +Defaults to `full`. + +`ssl.supported_protocols`:: +If retrieving IDP metadata via https (see `idp.metadata.path`), specifies the +supported protocols for TLS/SSL. + +`ssl.cipher_suites`:: +If retrieving IDP metadata via https (see `idp.metadata.path`), specifies the +cipher suites that should be supported. + [float] [[ssl-tls-settings]] ==== Default TLS/SSL Settings diff --git a/docs/en/setup/docker.asciidoc b/docs/en/setup/docker.asciidoc index ccd536a8eaa..c245f9f181c 100644 --- a/docs/en/setup/docker.asciidoc +++ b/docs/en/setup/docker.asciidoc @@ -269,7 +269,7 @@ accomplished with the parameter: -------------------------------------------- IMPORTANT: The container **runs {es} as user `elasticsearch` using uid:gid `1000:1000`**. Bind mounted host directories and files, such as -`custom_elasticsearch.yml` above, **need to be accessible by this user**. For the https://www.elastic.co/guide/en/elasticsearch/reference/current/important-settings.html#path-settings[data and log dirs], +`custom_elasticsearch.yml` above, **need to be accessible by this user**. For the <>, such as `/usr/share/elasticsearch/data`, write access is required as well. Also see note 1 below. diff --git a/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/integration/MlDistributedFailureIT.java b/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/integration/MlDistributedFailureIT.java index 6e777c174a2..f372bff5c7d 100644 --- a/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/integration/MlDistributedFailureIT.java +++ b/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/integration/MlDistributedFailureIT.java @@ -12,6 +12,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.CheckedRunnable; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.DeprecationHandler; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; @@ -247,7 +248,8 @@ public class MlDistributedFailureIT extends BaseMlIntegTestCase { } BytesReference source = searchResponse.getHits().getHits()[0].getSourceRef(); - try (XContentParser parser = XContentHelper.createParser(NamedXContentRegistry.EMPTY, source, XContentType.JSON)) { + try (XContentParser parser = XContentHelper.createParser(NamedXContentRegistry.EMPTY, + DeprecationHandler.THROW_UNSUPPORTED_OPERATION, source, XContentType.JSON)) { return DataCounts.PARSER.apply(parser, null); } catch (IOException e) { throw new RuntimeException(e); diff --git a/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UserRoleMapper.java b/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UserRoleMapper.java index 8c5e27ec2a9..ffdab15e3b5 100644 --- a/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UserRoleMapper.java +++ b/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UserRoleMapper.java @@ -7,9 +7,13 @@ package org.elasticsearch.xpack.security.authc.support; import com.unboundid.ldap.sdk.DN; import com.unboundid.ldap.sdk.LDAPException; +import com.unboundid.util.LDAPSDKUsageException; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.message.ParameterizedMessage; import org.apache.lucene.util.automaton.CharacterRunAutomaton; import org.elasticsearch.action.ActionListener; import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.xpack.core.security.authc.RealmConfig; import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.ExpressionModel; import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.FieldExpression; @@ -78,7 +82,7 @@ public interface UserRoleMapper { model.defineField("dn", dn, new DistinguishedNamePredicate(dn)); model.defineField("groups", groups, groups.stream() .>map(DistinguishedNamePredicate::new) - .reduce((a, b) -> a.or(b)) + .reduce(Predicate::or) .orElse(fieldValue -> false) ); metadata.keySet().forEach(k -> model.defineField("metadata." + k, metadata.get(k))); @@ -155,6 +159,8 @@ public interface UserRoleMapper { * */ class DistinguishedNamePredicate implements Predicate { + private static final Logger LOGGER = Loggers.getLogger(DistinguishedNamePredicate.class); + private final String string; private final DN dn; @@ -164,10 +170,17 @@ public interface UserRoleMapper { } private static DN parseDn(String string) { - try { - return new DN(string); - } catch (LDAPException e) { + if (string == null) { return null; + } else { + try { + return new DN(string); + } catch (LDAPException | LDAPSDKUsageException e) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace(new ParameterizedMessage("failed to parse [{}] as a DN", string), e); + } + return null; + } } } @@ -227,7 +240,7 @@ public interface UserRoleMapper { } return testString.equalsIgnoreCase(dn.toNormalizedString()); } - return false; + return string == null && fieldValue.getValue() == null; } } } diff --git a/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/DistinguishedNamePredicateTests.java b/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/DistinguishedNamePredicateTests.java index b771ab21ae8..d04f0ad7f93 100644 --- a/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/DistinguishedNamePredicateTests.java +++ b/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/DistinguishedNamePredicateTests.java @@ -48,6 +48,30 @@ public class DistinguishedNamePredicateTests extends ESTestCase { assertPredicate(predicate, null, false); } + public void testParsingMalformedInput() { + Predicate predicate = new UserRoleMapper.DistinguishedNamePredicate(null); + assertPredicate(predicate, null, true); + assertPredicate(predicate, "", false); + assertPredicate(predicate, randomAlphaOfLengthBetween(1, 8), false); + + predicate = new UserRoleMapper.DistinguishedNamePredicate(""); + assertPredicate(predicate, null, false); + assertPredicate(predicate, "", true); + assertPredicate(predicate, randomAlphaOfLengthBetween(1, 8), false); + + predicate = new UserRoleMapper.DistinguishedNamePredicate("foo="); + assertPredicate(predicate, null, false); + assertPredicate(predicate, "foo", false); + assertPredicate(predicate, "foo=", true); + assertPredicate(predicate, randomAlphaOfLengthBetween(5, 12), false); + + predicate = new UserRoleMapper.DistinguishedNamePredicate("=bar"); + assertPredicate(predicate, null, false); + assertPredicate(predicate, "bar", false); + assertPredicate(predicate, "=bar", true); + assertPredicate(predicate, randomAlphaOfLengthBetween(5, 12), false); + } + private void assertPredicate(Predicate predicate, Object value, boolean expected) { assertThat("Predicate [" + predicate + "] match [" + value + "]", predicate.test(new FieldValue(value)), equalTo(expected)); }