From b2b4a8bce4b1ce45c91eff4e8667830406d20c35 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Mon, 13 Jun 2016 16:35:01 -0500 Subject: [PATCH] Add LDAP EE Docs [ci skip] --- doc/administration/auth/ldap-ee.md | 198 +++++++++++++++++++++++++++++ doc/administration/auth/ldap.md | 96 +++++++------- doc/install/README.md | 1 - doc/install/ldap.md | 61 +-------- 4 files changed, 253 insertions(+), 103 deletions(-) create mode 100644 doc/administration/auth/ldap-ee.md diff --git a/doc/administration/auth/ldap-ee.md b/doc/administration/auth/ldap-ee.md new file mode 100644 index 00000000000000..b040607e12529b --- /dev/null +++ b/doc/administration/auth/ldap-ee.md @@ -0,0 +1,198 @@ +# LDAP Additions in GitLab EE + +This is a continuation of the main [LDAP documentation](ldap.md), detailing LDAP +features specific to GitLab Enterprise Edition. + +## User Sync + +Once per day, GitLab will run a worker to check and update GitLab +users against LDAP. + +The process will execute the following access checks: + +1. Ensure the user is still present in LDAP +1. If the LDAP server is Active Directory, ensure the user is active (not + blocked/disabled state). This will only be checked if + `active_directory: true` is set in the LDAP configuration [^1] + +The user will be set to `ldap_blocked` state in GitLab if the above conditions +fail. This means the user will not be able to login or push/pull code. + +The process will also update the following user information: + +1. Email address +1. If `sync_ssh_keys` is set, SSH public keys +1. If Kerberos is enabled, Kerberos identity + +> **Note:** The LDAP sync process updates existing users while new users will + be created on first sign in. + +## Group Sync + +If `group_base` is set in LDAP configuration, a group sync process will run +every hour, on the hour. This allows GitLab group membership to be automatically +updated based on LDAP group members. + +The `group_base` configuration should be a base LDAP 'container', such as an +'organization' or 'organizational unit', that contains LDAP groups that should +be available to GitLab. For example, `group_base` could be +`ou=groups,dc=example,dc=com`. In the config file it will look like the +following. + +**Omnibus configuration** + +Edit `/etc/gitlab/gitlab.rb`: + +```ruby +gitlab_rails['ldap_servers'] = YAML.load <<-EOS +main: + # snip... + group_base: ou=groups,dc=example,dc=com +EOS +``` + +[Reconfigure GitLab][reconfigure] for the changes to take effect. + +**Source configuration** + +Edit `/home/git/gitlab/config/gitlab.yml`: + +```yaml +production: + ldap: + servers: + main: + # snip... + group_base: ou=groups,dc=example,dc=com +``` + +[Restart GitLab][restart] for the changes to take effect. + +--- + +To take advantage of group sync, group owners or masters will need to create an +LDAP group link in their group **Settings -> LDAP Groups** page. Multiple LDAP +groups can be linked with a single GitLab group. When the link is created, an +access level/role is specified (Guest, Reporter, Developer, Master, or Owner). + +## Administrator Sync + +As an extension of group sync, you can automatically manage your global GitLab +administrators. Specify a group CN for `admin_group` and all members of the +LDAP group will be given administrator privileges. The configuration will look +like the following. + +> **Note:** Administrators will not be synced unless `group_base` is also + specified alongside `admin_group`. Also, only specify the CN of the admin + group, as opposed to the full DN. + +**Omnibus configuration** + +Edit `/etc/gitlab/gitlab.rb`: + +```ruby +gitlab_rails['ldap_servers'] = YAML.load <<-EOS +main: + # snip... + group_base: ou=groups,dc=example,dc=com + admin_group: my_admin_group +EOS +``` + +[Reconfigure GitLab][reconfigure] for the changes to take effect. + +**Source configuration** + +Edit `/home/git/gitlab/config/gitlab.yml`: + +```yaml +production: + ldap: + servers: + main: + # snip... + group_base: ou=groups,dc=example,dc=com + admin_group: my_admin_group +``` + +[Restart GitLab][restart] for the changes to take effect. + +## Group Sync Technical Details + +There is a lot going on with group sync 'under the hood'. This section +outlines what LDAP queries are executed and what behavior you can expect +from group sync. + +Group member access will be downgraded from a higher level if their LDAP group +membership changes. For example, if a user has 'Owner' rights in a group and the +next group sync reveals they should only have 'Developer' privileges, their +access will be adjusted accordingly. The only exception is if the user is the +*last* owner in a group. Groups need at least one owner to fulfill +administrative duties. + +### Supported LDAP Group Types/Attributes + +GitLab supports LDAP groups that use member attributes `member`, `submember`, +`uniquemember`, `memberof` and `memberuid`. This means group sync supports, at +least, LDAP groups with object class `groupOfNames`, `posixGroup`, and +`groupOfUniqueName`. Other object classes should work fine as long as members +are defined as one of the mentioned attributes. This also means GitLab supports +Microsoft Active Directory, Apple Open Directory, Open LDAP, and 389 Server. +Other LDAP servers should work, too. + +Active Directory also supports nested groups. Group sync will recursively +resolve membership if `active_directory: true` is set in the configuration file. + +### Queries + +- Each LDAP group is queried a maximum of one time with base `group_base` and + filter `(cn=)`. +- If the LDAP group has the `memberuid` attribute, GitLab will execute another + LDAP query per member to obtain each user's full DN. These queries are + executed with base `base`, scope 'base object', and a filter depending on + whether `user_filter` is set. Filter may be `(uid=)` or a + joining of `user_filter`. + +### Benchmarks + +Group sync was written to be as performant as possible. Data is cached, database +queries are optimized, and LDAP queries are minimized. The last benchmark run +revealed the following metrics: + +For 20,000 LDAP users, 11,000 LDAP groups and 1,000 GitLab groups with 10 +LDAP group links each: + +- Initial sync (no existing members assigned in GitLab) took 1.8 hours +- Subsequent syncs (checking membership, no writes) took 15 minutes + +These metrics are meant to provide a baseline and performance may vary based on +any number of factors. This was a pretty extreme benchmark and most instances will +not have near this many users or groups. Disk speed, database performance, +network and LDAP server response time will affect these metrics. + +## Troubleshooting + +If you see `LDAP search error: Referral` in the logs, or when troubleshooting +LDAP Group Sync, this error may indicate a configuration problem. The LDAP +configuration `/etc/gitlab/gitlab.rb` (Omnibus) or `config/gitlab.yml` (source) +is in YAML format and is sensitive to indentation. Check that `group_base` and +`admin_group` configuration keys are indented 2 spaces past the server +identifier. The default identifier is `main` and an example snippet looks like +the following: + +```yaml +main: # 'main' is the GitLab 'provider ID' of this LDAP server + label: 'LDAP' + host: 'ldap.example.com' + ... + group_base: 'cn=my_group,ou=groups,dc=example,dc=com' + admin_group: 'my_admin_group' +``` + +[reconfigure]: ../restart_gitlab.md#omnibus-gitlab-reconfigure +[restart]: ../restart_gitlab.md#installations-from-source + +[^1]: In Active Directory, a user is marked as disabled/blocked if the user + account control attribute (`userAccountControl:1.2.840.113556.1.4.803`) + has bit 2 set. See https://ctogonewild.com/2009/09/03/bitmask-searches-in-ldap/ + for more information. diff --git a/doc/administration/auth/ldap.md b/doc/administration/auth/ldap.md index 989623d4c6f57d..59cdc328693edf 100644 --- a/doc/administration/auth/ldap.md +++ b/doc/administration/auth/ldap.md @@ -6,6 +6,11 @@ servers, including Microsoft Active Directory, Apple Open Directory, Open LDAP, and 389 Server. GitLab EE includes enhanced integration, including group membership syncing. +## GitLab EE + +The information on this page is relevent for both GitLab CE and EE. For more +details about EE-specific LDAP features, see [LDAP EE Documentation](ldap-ee.md). + ## Security GitLab assumes that LDAP users are not able to change their LDAP 'mail', 'email' @@ -48,6 +53,11 @@ The configuration inside `gitlab_rails['ldap_servers']` below is sensitive to incorrect indentation. Be sure to retain the indentation given in the example. Copy/paste can sometimes cause problems. +> **Note:** The `method` value `ssl` corresponds to 'Simple TLS' in the LDAP + library. `tls` corresponds to StartTLS, not to be confused with regular TLS. + Normally, if you specify `ssl` is will be on port 636 while `tls` (StartTLS) + would be on port 389. `plain` also operates on port 389. + **Omnibus configuration** ```ruby @@ -130,35 +140,35 @@ main: # 'main' is the GitLab 'provider ID' of this LDAP server first_name: 'givenName' last_name: 'sn' - ## EE only - - # Base where we can search for groups - # - # Ex. ou=groups,dc=gitlab,dc=example - # - group_base: '' - - # The CN of a group containing GitLab administrators - # - # Ex. administrators - # - # Note: Not `cn=administrators` or the full DN - # - admin_group: '' - - # An array of CNs of groups containing users that should be considered external - # - # Ex. ['interns', 'contractors'] - # - # Note: Not `cn=interns` or the full DN - # - external_groups: [] - - # The LDAP attribute containing a user's public SSH key - # - # Ex. ssh_public_key - # - sync_ssh_keys: false + ## EE only + + # Base where we can search for groups + # + # Ex. ou=groups,dc=gitlab,dc=example + # + group_base: '' + + # The CN of a group containing GitLab administrators + # + # Ex. administrators + # + # Note: Not `cn=administrators` or the full DN + # + admin_group: '' + + # An array of CNs of groups containing users that should be considered external + # + # Ex. ['interns', 'contractors'] + # + # Note: Not `cn=interns` or the full DN + # + external_groups: [] + + # The LDAP attribute containing a user's public SSH key + # + # Ex. ssh_public_key + # + sync_ssh_keys: false # GitLab EE only: add more LDAP servers # Choose an ID made of a-z and 0-9 . This ID will be stored in the database @@ -264,24 +274,24 @@ In other words, if an existing GitLab user wants to enable LDAP sign-in for themselves, they should check that their GitLab email address matches their LDAP email address, and then sign into GitLab via their LDAP credentials. -## Limitations - -### TLS Client Authentication +## Troubleshooting -Not implemented by `Net::LDAP`. -You should disable anonymous LDAP authentication and enable simple or SASL -authentication. The TLS client authentication setting in your LDAP server cannot -be mandatory and clients cannot be authenticated with the TLS protocol. +### Debug LDAP user filter with ldapsearch -### TLS Server Authentication +This example uses ldapsearch and assumes you are using ActiveDirectory. The +following query returns the login names of the users that will be allowed to +log in to GitLab if you configure your own user_filter. -Not supported by GitLab's configuration options. -When setting `method: ssl`, the underlying authentication method used by -`omniauth-ldap` is `simple_tls`. This method establishes TLS encryption with -the LDAP server before any LDAP-protocol data is exchanged but no validation of -the LDAP server's SSL certificate is performed. +``` +ldapsearch -H ldaps://$host:$port -D "$bind_dn" -y bind_dn_password.txt -b "$base" "(&(ObjectClass=User)($user_filter))" sAMAccountName +``` -## Troubleshooting +- Variables beginning with a `$` refer to a variable from the LDAP section of + your configuration file. +- Replace ldaps:// with ldap:// if you are using the plain authentication method. + Port `389` is the default `ldap://` port and `636` is the default `ldaps://` + port. +- We are assuming the password for the bind_dn user is in bind_dn_password.txt. ### Invalid credentials when logging in diff --git a/doc/install/README.md b/doc/install/README.md index 79ee751955cdad..239f5f301ec209 100644 --- a/doc/install/README.md +++ b/doc/install/README.md @@ -4,4 +4,3 @@ - [Requirements](requirements.md) - [Structure](structure.md) - [Database MySQL](database_mysql.md) -- [LDAP](ldap.md) diff --git a/doc/install/ldap.md b/doc/install/ldap.md index 8236d61ba14d72..30f0c15daccf9d 100644 --- a/doc/install/ldap.md +++ b/doc/install/ldap.md @@ -1,60 +1,3 @@ -# Link LDAP Groups -You can link LDAP groups with GitLab groups. -It gives you ability to automatically add/remove users from GitLab groups based on LDAP groups membership. +# GitLab LDAP integration -How it works: -1. We retrieve user ldap groups -2. We find corresponding GitLab groups -3. We add user to GitLab groups -4. We remove user from GitLab groups if user has no membership in LDAP groups - -In order to use LDAP groups feature: - -1. Edit gitlab.yml config LDAP sections. -2. Visit group settings -> LDAP tab -3. Edit LDAP cn and access level for gitlab group -4. Setup LDAP group members - - -Example of LDAP section from gitlab.yml - -``` - # - # 2. Auth settings - # ========================== - - ## LDAP settings - ldap: - enabled: true - host: 'localhost' - base: 'ou=People,dc=gitlab,dc=local' - group_base: 'ou=Groups,dc=gitlab,dc=local' - port: 389 - uid: 'uid' -``` - - -# Test whether LDAP group functionality is configured correctly - -You need a non-LDAP admin user (such as the default admin@local.host), an LDAP user (e.g. Mary) and an LDAP group to which Mary belongs (e.g. Developers). - -1. As the admin, create a new group 'Developers' in GitLab and associate it with the Developers LDAP group at gitlab.example.com/admin/groups/developers/edit . -2. Log in as Mary. -3. Verify that Mary is now a member of the Developers group in GitLab. - -If you get an error message when logging in as Mary, double-check your `group_base` setting in `config/gitlab.yml`. - - -# Debug LDAP user filter with ldapsearch - -This example uses [ldapsearch](http://www.openldap.org/software/man.cgi?query=ldapsearch&apropos=0&sektion=0&manpath=OpenLDAP+2.0-Release&format=html) and assumes you are using ActiveDirectory. - -The following query returns the login names of the users that will be allowed to log in to GitLab if you configure your own `user_filter`. - -```bash -ldapsearch -H ldaps://$host:$port -D "$bind_dn" -y bind_dn_password.txt -b "$base" "(&(ObjectClass=User)($user_filter))" sAMAccountName -``` - -- `$var` refers to a variable from the `ldap` section of your `config/gitlab.yml` https://gitlab.com/gitlab-org/gitlab-ee/blob/master/config/gitlab.yml.example#L100; -- Replace `ldaps://` with `ldap://` if you are using the `plain` authentication method; -- We are assuming the password for the `bind_dn` user is in `bind_dn_password.txt`. +This document was moved under [`administration/auth/ldap`](../administration/auth/ldap.md). -- GitLab