[[active-directory]]
=== Using Active Directory to Authenticate Users

You can configure Shield to communicate with Active Directory to authenticate users. To integrate
with Active Directory, you configure an Active Directory realm and assign Active Directory users 
and groups to Shield roles in the <<mapping-roles, role mapping file>>. 

To protect passwords, communications between Shield and the LDAP server should be encrypted 
using SSL/TLS. Clients and nodes that connect via SSL/TLS to the LDAP server need to have the
LDAP server's certificate or the server's root CA certificate installed in their keystore or 
truststore. For more information about installing certificates, see <<active-directory-ssl, 
Encrypting Communications Between Shield and Active Directory with SSL/TLS>>.

==== Configuring an Active Directory Realm

Shield uses LDAP to communicate with Active Directory, so Active Directory realms are similar 
to <<ldap, LDAP realms>>. Like LDAP directories, Active Directory stores users and groups 
hierarchically. The directory's hierarchy is built from containers such as the _organizational 
unit_ (`ou`), _organization_ (`o`), and _domain controller_ (`dc`). 

The path to a entry is a _Distinguished Name_ (DN) that uniquely identifies a user or group. User 
and group  names typically have attributes such as a _common name_ (`cn`) or _unique ID_ (`uid`). 
A DN is specified as a string, for example  `"cn=admin,dc=example,dc=com"`. White space is ignored.
Shield only supports Active Directory security groups. You cannot map distribution groups
to roles.

NOTE: When you use Active Directory for authentication, the username entered by the user is expected 
      to match the `sAMAccountName` or `userPrincipalName`, not the common name. 

To configure an Active Directory realm:

. Add a realm configuration of type `active_directory` to `elasticsearch.yml` in the 
`shield.authc.realms` namespace. At a minimum, you must set the realm 
`type` to `active_directory` and specify the Active Directory `domain_name`. To use SSL/TLS to 
encrypt communications with the Active Directory server, you must also set the `url` attribute and 
specify the LDAPS protocol and secure port number. If you are configuring multiple realms, you 
should also explicitly set the `order` attribute to control the order in which the realms are 
consulted during authentication. See <<ad-settings, Active Directory Realm Settings>>
for all of the options you can set for an Active Directory realm.
+
NOTE: Binding to Active Directory fails if the domain name is not mapped in DNS. If DNS is not 
      being provided by a Windows DNS server, add a mapping for the domain in the local 
      `/etc/hosts` file.
+
For example, the following realm configuration configures Shield to connect to 
`ldaps://example.com:636` to authenticate users through Active Directory. 
+
[source, yaml]
------------------------------------------------------------
shield:
  authc:
    realms:
      active_directory:
        type: active_directory
        order: 0 <1>
        domain_name: ad.example.com
        url: ldaps://ad.example.com:636 <2>
        unmapped_groups_as_roles: true <3>
      ...
------------------------------------------------------------
<1> The realm order controls the order in which the configured realms are checked when 
authenticating a user.
<2> If you don't specify the URL, it defaults to `ldap:<domain_name>:389`.
<3> When this option is enabled, Shield automatically maps Active Directory groups to 
roles of the same name defined in `roles.yml`.

. Restart Elasticsearch.

[[ad-settings]]
===== Active Directory Realm Settings

|=======================
| Setting                    | Required  | Description
| `type`                     | yes       | Indicates the realm type. Must be set to 
                                           `active_directory`.
| `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`.
| `domain_name`              | yes       | Specifies the domain name of the Active Directory. Shield 
                                           uses the domain name to derive the LDAP URL and 
                                           `user_search_dn` if those fields are not  specified.
| `url`                      | no        | Specifies an LDAP URL of the form 
                                           `ldap[s]://<server>:<port>`. Shield attempts to 
                                           authenticate against this URL. If the URL is not 
                                           specified, Shield derives it from the `domain_name`, 
                                           assuming an unencrypted connection to port 389. For 
                                           example, `ldap://<domain_name>:389`. You must specify the 
                                           URL to connect using SSL/TLS or connect to a custom port.
| `user_search.base_dn`      | no        | Specifies the context to search for the user. Defaults to 
                                           the root of the Active Directory domain.
| `user_search.scope`        | no        | Specifies whether the user search should be `sub_tree` 
                                           (default), `one_level`, or `base`.  `sub_tree` searches 
                                           all objects contained under `base_dn`. `one_level` only 
                                           searches users directly contained within the `base_dn`. 
                                           `base` specifies that the `base_dn` is a user object and 
                                           that it is the only user considered.
| `user_search.filter`       | no        | Specifies a filter to use to lookup a user given a 
                                           username.  The default filter looks up `user` objects 
                                           with either `sAMAccountName` or `userPrincipalName`. If 
                                           specified, this must be a proper LDAP user search filter, 
                                           for example `(&(objectClass=user)(sAMAccountName={0}))`. 
                                           For more information, see https://msdn.microsoft.com/en-us/library/aa746475(v=vs.85).aspx[Search Filter Syntax].
| `group_search.base_dn`     | no        | Specifies the context to search for groups in which the 
                                           user has membership. Defaults to the root of the Active 
                                           Directory domain.
| `group_search.scope`       | no        | Specifies whether the group search should be `sub_tree` 
                                           (default), `one_level` or `base`.  `sub_tree` searches 
                                           all objects contained under `base_dn`. `one_level` 
                                           searches for groups directly contained within the 
                                           `base_dn`. `base` specifies that the `base_dn` is a 
                                           group object and that it is the only group considered.
| `unmapped_groups_as_roles` | no        | Specifies whether the names of any unmapped LDAP groups 
                                           should be used as role names and assigned to the user. 
                                           Defaults to `false`.
| `files.role_mapping`       | no        | Specifies the path and file name of the 
                                           <<ad-role-mapping, YAML role  mapping configuration file>>. 
                                           Defaults to `CONF_DIR/shield/users/role_mapping.yml`, 
                                           where `CONF_DIR` is `ES_HOME/config` (zip/tar installations) 
                                           or `/etc/elasticsearch` (package installations).
| `follow_referrals`         | no        | Specifies whether Shield should follow referrals returned 
                                           by the LDAP server. Referrals are URLs returned by the 
                                           server that are to be used to continue the LDAP operation 
                                           (such as `search`). Defaults to `true`.
| `hostname_verification`    | no        | Specifies whether hostname verification is performed when 
                                           connecting to an LDAP server. When `true`, the hostname 
                                           or IP address used in the `url` must match one of the 
                                           names in the certificate or the connection will not be 
                                           allowed. Due to its potential security impact, 
                                           `hostname_verification` is not exposed via the
                                           {ref}/cluster-nodes-info.html#cluster-nodes-info[nodes info API]. 
                                           Defaults to `true`.
| `cache.ttl`                | no        | Specifies the time-to-live for cached user entries. A 
                                           user's credentials are cached for this period of time. 
                                           Specify the time period using the standard Elasticsearch 
                                           {ref}/common-options.html#time-units[time units]. 
                                           Defaults to `20m`.
| `cache.max_users`          | no        | Specifies the maximum number of user entries that can be 
                                           stored in the cache at one time. Defaults to 100,000.
| `cache.hash_algo`          | no        | Specifies the hashing algorithm that is used for the 
                                           cached user credentials. See <<cache-hash-algo, 
                                           Cache hash algorithms>> for the possible values.
                                           (Expert Setting) 
|=======================

[[assigning-roles-ad]]
==== Assigning Active Directory Users and Groups to Roles

To configure privileges for Active Directory users and groups, you assign them to roles in 
the role mapping file stored on each node. You specify users and groups using their distinguished 
names. For example, the following mapping configuration assigns the Active Directory `admins` 
group both the `monitoring` and `user` roles, and assigns the  `user` role to the `users` 
group and `John Doe`. 

[source, yaml]
------------------------------------------------------------
monitoring: <1>
  - "cn=admins,dc=example,dc=com" <2>
user:
  - "cn=users,dc=example,dc=com" <3>
  - "cn=admins,dc=example,dc=com"
  - "cn=John Doe,cn=contractors,dc=example,dc=com" <4>
------------------------------------------------------------
<1> The name of a role defined in <<defining-roles, `roles.yml`>>.
<2> The distinguished name of the `admins` group.
<3> The distinguished name of the `users` group.
<4> The distinguished name of the user `John Doe`.

For more information, see <<mapping-roles, Mapping Users and Groups to Roles>>.

[[active-directory-ssl]]
==== Encrypting Communications Between Shield and Active Directory with SSL/TLS

You should encrypt communications between Shield and Active Directory to protect the user 
credentials that are sent to Active Directory for authentication. Connecting via SSL/TLS 
ensures that the identity of the Active Directory server is authenticated before Shield 
transmits the user credentials, and the user names and passwords are encrypted in transit.

To encrypt communications between Shield and Active Directory:

. Configure each node to trust certificates signed by the CA that signed your Active Directory server
certificates. For example, the following command imports `cacert.pem` 
into node01's keystore.  (For information about using truststores, see <<create-truststore, 
Configuring a Separate Truststore>>.)
+
[source,shell]
--------------------------------------------------
cd CONFIG_DIR/shield
keytool -importcert -keystore node01.jks -file cacert.pem -alias ad_ca
--------------------------------------------------
+
The CA cert must be a PEM encoded certificate. 
+
[NOTE]
===============================
You can also import the individual server certificates rather than the CA certificate, but
this is only recommended if you have a single Active Directory server.
You can fetch the Active Directory server certificate with `openssl`. 
For example, the following command gets the certificate for `ad.example.com` and stores it locally 
in `ldap.crt`.

[source, shell]
----------------------------------------------------------------------------------------------
echo | openssl s_client -connect ad.example.com:636 2>/dev/null | openssl x509 > ldap.crt
----------------------------------------------------------------------------------------------

If you are using an older version of openssl you might need to use use the `-host` and 
`-port` options rather than the `-connect` option.
===============================

. If you haven't already configured the path to the node's keystore or truststore  in 
`elasticsearch.yml`, set the `shield.ssl.keystore.path` or `shield.ssl.truststore.path` 
attributes. For example:
+
[source, yaml]
--------------------------------------------------
shield.ssl.keystore.path:          /home/es/config/shield/node01.jks <1>
shield.ssl.keystore.password:      myPass <2>
shield.ssl.keystore.key_password:  myKeyPass <3>
--------------------------------------------------
<1> The full path to the node keystore file. This must be a location within the Elasticsearch
configuration directory.
<2> The password used to access the keystore.
<3> The password used to access the certificate. This is only required if you specified a separate 
certificate password when generating the certificate.
+
For more information, see <<ssl-tls, Enabling SSL/TLS in the Node Configuration>>. 

. Set the `url` attribute in the realm configuration to specify the LDAPS protocol and 
the secure port number. For example, `url: ldaps://ad.example.com:636`. 

. Restart Elasticsearch to pick up the changes to `elasticsearch.yml`.

NOTE: By default, when you configure Shield to connect to Active Directory using SSL/TLS, 
      Shield attempts to verify the hostname or IP address specified with the `url` attribute in 
      the realm configuration with the values in the certificate. If the values in the certificate 
      and realm configuration do not match, Shield does not allow a connection to the Active 
      Directory server. This is done to protect against man in the middle attacks. If necessary, 
      you can disable this behavior by setting the <<ref-ssl-tls-settings, `hostname_verification`>> 
      property to `false`.