diff options
Diffstat (limited to 'doc/administration/auth/ldap')
-rw-r--r-- | doc/administration/auth/ldap/google_secure_ldap.md | 2 | ||||
-rw-r--r-- | doc/administration/auth/ldap/index.md | 444 | ||||
-rw-r--r-- | doc/administration/auth/ldap/ldap-troubleshooting.md | 51 | ||||
-rw-r--r-- | doc/administration/auth/ldap/ldap_synchronization.md | 349 |
4 files changed, 442 insertions, 404 deletions
diff --git a/doc/administration/auth/ldap/google_secure_ldap.md b/doc/administration/auth/ldap/google_secure_ldap.md index e5af8e8256a..69f0bfdce4c 100644 --- a/doc/administration/auth/ldap/google_secure_ldap.md +++ b/doc/administration/auth/ldap/google_secure_ldap.md @@ -35,7 +35,7 @@ The steps below cover: credentials' and 'Read user information'. Select 'Add LDAP Client' NOTE: - If you plan to use GitLab [LDAP Group Sync](index.md#group-sync) + If you plan to use GitLab [LDAP Group Sync](ldap_synchronization.md#group-sync) , turn on 'Read group information'. ![Add LDAP Client Step 2](img/google_secure_ldap_add_step_2.png) diff --git a/doc/administration/auth/ldap/index.md b/doc/administration/auth/ldap/index.md index 92815f10b92..9047cfae1e9 100644 --- a/doc/administration/auth/ldap/index.md +++ b/doc/administration/auth/ldap/index.md @@ -19,58 +19,52 @@ This integration works with most LDAP-compliant directory servers, including: - Open LDAP. - 389 Server. -Users added through LDAP take a [licensed seat](../../../subscriptions/self_managed/index.md#billable-users). +Users added through LDAP: -## Security +- Take a [licensed seat](../../../subscriptions/self_managed/index.md#billable-users). +- Can authenticate with Git using either their GitLab username or their email and LDAP password, + even if password authentication for Git + [is disabled](../../../user/admin_area/settings/sign_in_restrictions.md#password-authentication-enabled). -GitLab assumes that LDAP users: +The LDAP DN is associated with existing GitLab users when: -- Are not able to change their LDAP `mail`, `email`, or `userPrincipalName` attributes. - An LDAP user allowed to change their email on the LDAP server can potentially - [take over any account](#enable-ldap-sign-in-for-existing-gitlab-users) - on your GitLab server. -- Have unique email addresses. If not, it's possible for LDAP users with the same - email address to share the same GitLab account. +- The existing user signs in to GitLab with LDAP for the first time. +- The LDAP email address is the primary email address of an existing GitLab user. If the LDAP email + attribute isn't found in the GitLab user database, a new user is created. -We recommend against using LDAP integration if your LDAP users are -allowed to change their `mail`, `email` or `userPrincipalName` attributes on -the LDAP server, or share email addresses. +If an existing GitLab user wants to enable LDAP sign-in for themselves, they should: -### User deletion +1. Check that their GitLab email address matches their LDAP email address. +1. Sign in to GitLab by using their LDAP credentials. -Users deleted from the LDAP server are immediately blocked from signing in -to GitLab and [no longer consumes a -license](../../../user/admin_area/moderate_users.md). -However, there's an LDAP check cache time of one hour (which is -[configurable](#adjust-ldap-user-sync-schedule) for GitLab Premium users). -This means users already signed-in or who are using Git over SSH can access -GitLab for up to one hour. Manually block the user in the GitLab Admin Area -to immediately block all access. +## Security -## Git password authentication +GitLab has multiple mechanisms to verify a user is still active in LDAP. If the user is no longer active in +LDAP, they are placed in an `ldap_blocked` status and are signed out. They are unable to sign in using any authentication provider until they are +reactivated in LDAP. -LDAP-enabled users can authenticate with Git using their GitLab username or -email and LDAP password, even if password authentication for Git is disabled -in the application settings. +Users are considered inactive in LDAP when they: -## Enable LDAP sign-in for existing GitLab users +- Are removed from the directory completely. +- Reside outside the configured `base` DN or `user_filter` search. +- Are marked as disabled or deactivated in Active Directory through the user account control attribute. This means attribute + `userAccountControl:1.2.840.113556.1.4.803` has bit 2 set. -When a user signs in to GitLab with LDAP for the first time and their LDAP -email address is the primary email address of an existing GitLab user, the -LDAP DN is associated with the existing user. If the LDAP email attribute -isn't found in the GitLab user database, a new user is created. +Status is checked for all LDAP users: -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 by using their LDAP credentials. +- When signing in using any authentication provider. +- Once per hour for active web sessions or Git requests using tokens or SSH keys. +- When performing Git over HTTP requests using LDAP username and password. +- Once per day during [User Sync](ldap_synchronization.md#user-sync). -## Google Secure LDAP +### Security risks -> Introduced in GitLab 11.9. +You should only use LDAP integration if your LDAP users cannot: -[Google Cloud Identity](https://cloud.google.com/identity/) provides a Secure -LDAP service that can be configured with GitLab for authentication and group sync. -See [Google Secure LDAP](google_secure_ldap.md) for detailed configuration instructions. +- Change their `mail`, `email` or `userPrincipalName` attributes on the LDAP server. These + users can potentially take over any account on your GitLab server. +- Share email addresses. LDAP users with the same email address can share the same GitLab + account. ## Configure LDAP @@ -109,7 +103,6 @@ gitlab_rails['ldap_servers'] = { 'verify_certificates' => true, 'bind_dn' => '_the_full_dn_of_the_user_you_will_bind_with', 'password' => '_the_password_of_the_bind_user', - 'verify_certificates' => true, 'tls_options' => { 'ca_file' => '', 'ssl_version' => '', @@ -170,7 +163,7 @@ These configuration settings are available: | `bind_dn` | The full DN of the user you bind with. | **{dotted-circle}** No | `'america\momo'` or `'CN=Gitlab,OU=Users,DC=domain,DC=com'` | | `password` | The password of the bind user. | **{dotted-circle}** No | `'your_great_password'` | | `encryption` | Encryption method. The `method` key is deprecated in favor of `encryption`. | **{check-circle}** Yes | `'start_tls'` or `'simple_tls'` or `'plain'` | -| `verify_certificates` | Enables SSL certificate verification if encryption method is `start_tls` or `simple_tls`. Defaults to true. | **{dotted-circle}** No | boolean | +| `verify_certificates` | Enables SSL certificate verification if encryption method is `start_tls` or `simple_tls`. If set to false, no validation of the LDAP server's SSL certificate is performed. Defaults to true. | **{dotted-circle}** No | boolean | | `timeout` | Set a timeout, in seconds, for LDAP queries. This helps avoid blocking a request if the LDAP server becomes unresponsive. A value of `0` means there is no timeout. (default: `10`) | **{dotted-circle}** No | `10` or `30` | | `active_directory` | This setting specifies if LDAP server is Active Directory LDAP server. For non-AD servers it skips the AD specific queries. If your LDAP server is not AD, set this to false. | **{dotted-circle}** No | boolean | | `allow_username_or_email_login` | If enabled, GitLab ignores everything after the first `@` in the LDAP username submitted by the user on sign-in. If you are using `uid: 'userPrincipalName'` on ActiveDirectory you must disable this setting, because the userPrincipalName contains an `@`. | **{dotted-circle}** No | boolean | @@ -266,7 +259,7 @@ For more information about `LDAP_MATCHING_RULE_IN_CHAIN` filters, see [Search Filter Syntax](https://docs.microsoft.com/en-us/windows/win32/adsi/search-filter-syntax). Support for nested members in the user filter shouldn't be confused with -[group sync nested groups](#supported-ldap-group-typesattributes) support. +[group sync nested groups](ldap_synchronization.md#supported-ldap-group-typesattributes) support. GitLab does not support the custom filter syntax used by OmniAuth LDAP. @@ -347,7 +340,7 @@ sync, while also allowing your SAML identity provider to handle additional checks like custom 2FA. When LDAP web sign in is disabled, users don't see an **LDAP** tab on the sign-in page. -This does not disable [using LDAP credentials for Git access](#git-password-authentication). +This does not disable using LDAP credentials for Git access. **Omnibus configuration** @@ -458,26 +451,6 @@ If initially your LDAP configuration looked like: 1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. -## Encryption - -### TLS server authentication - -`simple_tls` and `start_tls` are the two available encryption methods. - -For either encryption method, if setting `verify_certificates: false`, TLS -encryption is established with the LDAP server before any LDAP-protocol data is -exchanged but no validation of the LDAP server's SSL certificate is performed. - -### Limitations - -#### TLS client authentication - -Not implemented by `Net::LDAP`. - -You should disable anonymous LDAP authentication and enable simple or Simple Authentication -and Security Layer (SASL) authentication. The TLS client authentication setting in your LDAP server -cannot be mandatory and clients cannot be authenticated with the TLS protocol. - ## Multiple LDAP servers **(PREMIUM SELF)** With GitLab, you can configure multiple LDAP servers that your GitLab instance @@ -528,342 +501,43 @@ If you configure multiple LDAP servers, use a unique naming convention for the `label` section of each entry. That label is used as the display name of the tab shown on the sign-in page. -## User sync **(PREMIUM SELF)** - -Once per day, GitLab runs a worker to check and update GitLab -users against LDAP. - -The process executes the following access checks: - -- Ensure the user is still present in LDAP. -- If the LDAP server is Active Directory, ensure the user is active (not - blocked/disabled state). This check is performed only if - `active_directory: true` is set in the LDAP configuration. - -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. - -<!-- vale gitlab.Spelling = NO --> - -For more information, see [Bitmask Searches in LDAP](https://ctovswild.com/2009/09/03/bitmask-searches-in-ldap/). - -<!-- vale gitlab.Spelling = YES --> +## Disable anonymous LDAP authentication -The user is set to an `ldap_blocked` state in GitLab if the previous conditions -fail. This means the user cannot sign in or push or pull code. +GitLab doesn't support TLS client authentication. Complete these steps on your LDAP server. -The process also updates the following user information: - -- Email address -- SSH public keys (if `sync_ssh_keys` is set) -- Kerberos identity (if Kerberos is enabled) - -The LDAP sync process: - -- Updates existing users. -- Creates new users on first sign in. - -### Adjust LDAP user sync schedule **(PREMIUM SELF)** - -By default, GitLab runs a worker once per day at 01:30 a.m. server time to -check and update GitLab users against LDAP. - -You can manually configure LDAP user sync times by setting the -following configuration values, in cron format. If needed, you can -use a [crontab generator](http://www.crontabgenerator.com). -The example below shows how to set LDAP user -sync to run once every 12 hours at the top of the hour. - -**Omnibus installations** - -1. Edit `/etc/gitlab/gitlab.rb`: - - ```ruby - gitlab_rails['ldap_sync_worker_cron'] = "0 */12 * * *" - ``` - -1. [Reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect. - -**Source installations** - -1. Edit `config/gitlab.yaml`: - - ```yaml - cron_jobs: - ldap_sync_worker_cron: - "0 */12 * * *" - ``` - -1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. +1. Disable anonymous authentication. +1. Enable one of the following authentication types: + - Simple authentication. + - Simple Authentication and Security Layer (SASL) authentication. -## Group Sync **(PREMIUM SELF)** +The TLS client authentication setting in your LDAP server cannot be mandatory and clients cannot be +authenticated with the TLS protocol. -If your LDAP supports the `memberof` property, when the user signs in for the -first time GitLab triggers a sync for groups the user should be a member of. -That way they don't have to wait for the hourly sync to be granted -access to their groups and projects. +## Deleting users -A group sync process runs every hour on the hour, and `group_base` must be set -in LDAP configuration for LDAP synchronizations based on group CN to work. This allows -GitLab group membership to be automatically updated based on LDAP group members. +Users deleted from the LDAP server: -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 configuration file it looks like the -following. +- Are immediately blocked from signing in to GitLab. +- [No longer consume a license](../../../user/admin_area/moderate_users.md). -**Omnibus configuration** - -1. Edit `/etc/gitlab/gitlab.rb`: - - ```ruby - gitlab_rails['ldap_servers'] = { - 'main' => { - # snip... - 'group_base' => 'ou=groups,dc=example,dc=com', - } - } - ``` - -1. [Apply your changes to GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure). - -**Source configuration** - -1. Edit `/home/git/gitlab/config/gitlab.yml`: - - ```yaml - production: - ldap: - servers: - main: - # snip... - group_base: ou=groups,dc=example,dc=com - ``` - -1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. - -To take advantage of group sync, group owners or maintainers must [create one -or more LDAP group links](#add-group-links). - -### Add group links **(PREMIUM SELF)** - -For information on adding group links by using CNs and filters, refer to the -[GitLab groups documentation](../../../user/group/index.md#manage-group-memberships-via-ldap). - -### Administrator sync **(PREMIUM SELF)** - -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 are given administrator privileges. The configuration looks -like the following. - -NOTE: -Administrators are not 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. -Additionally, if an LDAP user has an `admin` role, but is not a member of the `admin_group` -group, GitLab revokes their `admin` role when syncing. - -**Omnibus configuration** - -1. Edit `/etc/gitlab/gitlab.rb`: - - ```ruby - gitlab_rails['ldap_servers'] = { - 'main' => { - # snip... - 'group_base' => 'ou=groups,dc=example,dc=com', - 'admin_group' => 'my_admin_group', - } - } - ``` +However, these users can continue to use Git with SSH until the next time the +[LDAP check cache runs](ldap_synchronization.md#adjust-ldap-user-sync-schedule). -1. [Apply your changes to GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure). +To delete the account immediately, you can manually +[block the user](../../../user/admin_area/moderate_users.md#block-a-user). -**Source configuration** - -1. 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 - ``` - -1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. - -### Global group memberships lock **(PREMIUM SELF)** - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1793) in GitLab 12.0. - -"Lock memberships to LDAP synchronization" setting allows instance administrators -to lock down user abilities to invite new members to a group. - -When enabled, the following applies: - -- Only administrator can manage memberships of any group including access levels. -- Users are not allowed to share project with other groups or invite members to - a project created in a group. - -To enable it, you must: - -1. [Configure LDAP](#configure-ldap). -1. On the top bar, select **Menu > Admin**. -1. On the left sidebar, select **Settings > General**. -1. Expand the **Visibility and access controls** section. -1. Ensure the **Lock memberships to LDAP synchronization** checkbox is selected. - -### Adjust LDAP group sync schedule **(PREMIUM SELF)** - -By default, GitLab runs a group sync process every hour, on the hour. -The values shown are in cron format. If needed, you can use a -[Crontab Generator](http://www.crontabgenerator.com). - -WARNING: -Do not start the sync process too frequently as this -could lead to multiple syncs running concurrently. This concern is primarily -for installations with a large number of LDAP users. Review the -[LDAP group sync benchmark metrics](#benchmarks) to see how -your installation compares before proceeding. - -You can manually configure LDAP group sync times by setting the -following configuration values. The example below shows how to set group -sync to run once every two hours at the top of the hour. - -**Omnibus installations** - -1. Edit `/etc/gitlab/gitlab.rb`: - - ```ruby - gitlab_rails['ldap_group_sync_worker_cron'] = "0 */2 * * * *" - ``` - -1. [Reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect. - -**Source installations** - -1. Edit `config/gitlab.yaml`: - - ```yaml - cron_jobs: - ldap_group_sync_worker_cron: - "*/30 * * * *" - ``` - -1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. - -### External groups **(PREMIUM SELF)** - -Using the `external_groups` setting allows you to mark all users belonging -to these groups as [external users](../../../user/permissions.md#external-users). -Group membership is checked periodically through the `LdapGroupSync` background -task. - -**Omnibus configuration** - -1. Edit `/etc/gitlab/gitlab.rb`: - - ```ruby - gitlab_rails['ldap_servers'] = { - 'main' => { - # snip... - 'external_groups' => ['interns', 'contractors'], - } - } - ``` - -1. [Apply your changes to GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure). - -**Source configuration** - -1. Edit `config/gitlab.yaml`: - - ```yaml - production: - ldap: - servers: - main: - # snip... - external_groups: ['interns', 'contractors'] - ``` - -1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. - -### Group sync technical details - -This section outlines what LDAP queries are executed and what behavior you -can expect from group sync. - -Group member access are downgraded from a higher level if their LDAP group -membership changes. For example, if a user the Owner role in a group and the -next group sync reveals they should only have the Developer role, their -access is 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` -- `memberuid` - -This means group sync supports (at least) LDAP groups with the following object -classes: - -- `groupOfNames` -- `posixGroup` -- `groupOfUniqueNames` - -Other object classes should work if members are defined as one of the -mentioned attributes. - -Active Directory supports nested groups. Group sync recursively resolves -membership if `active_directory: true` is set in the configuration file. - -##### Nested group memberships - -Nested group memberships are resolved only if the nested group -is found in the configured `group_base`. For example, if GitLab sees a -nested group with DN `cn=nested_group,ou=special_groups,dc=example,dc=com` but -the configured `group_base` is `ou=groups,dc=example,dc=com`, `cn=nested_group` -is ignored. - -#### Queries - -- Each LDAP group is queried a maximum of one time with base `group_base` and - filter `(cn=<cn_from_group_link>)`. -- If the LDAP group has the `memberuid` attribute, GitLab executes 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=<uid_from_group>)` or a - joining of `user_filter`. - -#### Benchmarks +## Google Secure LDAP -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: +> Introduced in GitLab 11.9. -For 20,000 LDAP users, 11,000 LDAP groups, and 1,000 GitLab groups with 10 -LDAP group links each: +[Google Cloud Identity](https://cloud.google.com/identity/) provides a Secure +LDAP service that can be configured with GitLab for authentication and group sync. +See [Google Secure LDAP](google_secure_ldap.md) for detailed configuration instructions. -- Initial sync (no existing members assigned in GitLab) took 1.8 hours -- Subsequent syncs (checking membership, no writes) took 15 minutes +## Synchronize users and groups -These metrics are meant to provide a baseline and performance may vary based on -any number of factors. This benchmark was extreme and most instances don't -have near this many users or groups. Disk speed, database performance, -network and LDAP server response time affects these metrics. +For more information on synchronizing users and groups between LDAP and GitLab, see +[LDAP synchronization](ldap_synchronization.md). ## Troubleshooting diff --git a/doc/administration/auth/ldap/ldap-troubleshooting.md b/doc/administration/auth/ldap/ldap-troubleshooting.md index 4757725d0bd..aa40060c4c1 100644 --- a/doc/administration/auth/ldap/ldap-troubleshooting.md +++ b/doc/administration/auth/ldap/ldap-troubleshooting.md @@ -229,7 +229,7 @@ ldapsearch -H ldaps://$host:$port -D "$bind_dn" -y bind_dn_password.txt -b "$ba #### Sync all users **(PREMIUM SELF)** -The output from a manual [user sync](index.md#user-sync) can show you what happens when +The output from a manual [user sync](ldap_synchronization.md#user-sync) can show you what happens when GitLab tries to sync its users against LDAP. Enter the [rails console](#rails-console) and then run: @@ -239,8 +239,7 @@ Rails.logger.level = Logger::DEBUG LdapSyncWorker.new.perform ``` -Next, [learn how to read the -output](#example-console-output-after-a-user-sync). +Next, [learn how to read the output](#example-console-output-after-a-user-sync). ##### Example console output after a user sync **(PREMIUM SELF)** @@ -342,9 +341,8 @@ LDAP group sync, but for some reason it's not happening. There are several things to check to debug the situation. - Ensure LDAP configuration has a `group_base` specified. - [This configuration](index.md#group-sync) is required for group sync to work properly. -- Ensure the correct [LDAP group link is added to the GitLab - group](index.md#add-group-links). + [This configuration](ldap_synchronization.md#group-sync) is required for group sync to work properly. +- Ensure the correct [LDAP group link is added to the GitLab group](ldap_synchronization.md#add-group-links). - Check that the user has an LDAP identity: 1. Sign in to GitLab as an administrator user. 1. On the top bar, select **Menu > Admin**. @@ -354,7 +352,7 @@ things to check to debug the situation. 1. Select the **Identities** tab. There should be an LDAP identity with an LDAP DN as the 'Identifier'. If not, this user hasn't signed in with LDAP yet and must do so first. -- You've waited an hour or [the configured interval](index.md#adjust-ldap-group-sync-schedule) for +- You've waited an hour or [the configured interval](ldap_synchronization.md#adjust-ldap-group-sync-schedule) for the group to sync. To speed up the process, either go to the GitLab group **Group information > Members** and press **Sync now** (sync one group) or [run the group sync Rake task](../../raketasks/ldap.md#run-a-group-sync) (sync all groups). @@ -366,8 +364,7 @@ the rails console. 1. Choose a GitLab group to test with. This group should have an LDAP group link already configured. 1. [Enable debug logging, find the above GitLab group, and sync it with LDAP](#sync-one-group). -1. Look through the output of the sync. See [example log - output](#example-console-output-after-a-group-sync) +1. Look through the output of the sync. See [example log output](#example-console-output-after-a-group-sync) for how to read the output. 1. If you still aren't able to see why the user isn't being added, [query the LDAP group directly](#query-a-group-in-ldap) to see what members are listed. @@ -377,20 +374,20 @@ the rails console. #### Administrator privileges not granted -When [Administrator sync](index.md#administrator-sync) has been configured +When [Administrator sync](ldap_synchronization.md#administrator-sync) has been configured but the configured users aren't granted the correct administrator privileges, confirm the following are true: -- A [`group_base` is also configured](index.md#group-sync). +- A [`group_base` is also configured](ldap_synchronization.md#group-sync). - The configured `admin_group` in the `gitlab.rb` is a CN, rather than a DN or an array. - This CN falls under the scope of the configured `group_base`. - The members of the `admin_group` have already signed into GitLab with their LDAP credentials. GitLab only grants the Administrator role to the users whose accounts are already connected to LDAP. -If all the above are true and the users are still not getting access, [run a manual -group sync](#sync-all-groups) in the rails console and [look through the -output](#example-console-output-after-a-group-sync) to see what happens when +If all the above are true and the users are still not getting access, +[run a manual group sync](#sync-all-groups) in the rails console and +[look through the output](#example-console-output-after-a-group-sync) to see what happens when GitLab syncs the `admin_group`. #### Sync all groups @@ -399,7 +396,7 @@ NOTE: To sync all groups manually when debugging is unnecessary, [use the Rake task](../../raketasks/ldap.md#run-a-group-sync) instead. -The output from a manual [group sync](index.md#group-sync) can show you what happens +The output from a manual [group sync](ldap_synchronization.md#group-sync) can show you what happens when GitLab syncs its LDAP group memberships against LDAP. ```ruby @@ -494,7 +491,7 @@ this line indicates the sync is finished: Finished syncing admin users for 'ldapmain' provider ``` -If [administrator sync](index.md#administrator-sync) is not configured, you see a message +If [administrator sync](ldap_synchronization.md#administrator-sync) is not configured, you see a message stating as such: ```shell @@ -583,6 +580,25 @@ end You can then [run a UserSync](#sync-all-users) **(PREMIUM SELF)** to sync the latest DN for each of these users. +## Expired license causes errors with multiple LDAP servers + +Using [multiple LDAP servers](index.md#multiple-ldap-servers) requires a valid license. An expired +license can cause: + +- `502` errors in the web interface. +- The following error in logs (the actual strategy name depends on the name configured in `/etc/gitlab/gitlab.rb`): + + ```plaintext + Could not find a strategy with name `Ldapsecondary'. Please ensure it is required or explicitly set it using the :strategy_class option. (Devise::OmniAuth::StrategyNotFound) + ``` + +To resolve this error, you must apply a new license to the GitLab instance without the web interface: + +1. Remove or comment out the GitLab configuration lines for all non-primary LDAP servers. +1. [Reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) so that it temporarily uses only one LDAP server. +1. Enter the [Rails console and add the license key](../../troubleshooting/gitlab_rails_cheat_sheet.md#add-a-license-through-the-console). +1. Re-enable the additional LDAP servers in the GitLab configuration and reconfigure GitLab again. + ## Debugging Tools ### LDAP check @@ -610,8 +626,7 @@ If a user account is blocked or unblocked due to the LDAP configuration, a message is [logged to `application.log`](../../logs.md#applicationlog). If there is an unexpected error during an LDAP lookup (configuration error, -timeout), the sign-in is rejected and a message is [logged to -`production.log`](../../logs.md#productionlog). +timeout), the sign-in is rejected and a message is [logged to `production.log`](../../logs.md#productionlog). ### ldapsearch diff --git a/doc/administration/auth/ldap/ldap_synchronization.md b/doc/administration/auth/ldap/ldap_synchronization.md new file mode 100644 index 00000000000..2673a8374ec --- /dev/null +++ b/doc/administration/auth/ldap/ldap_synchronization.md @@ -0,0 +1,349 @@ +--- +stage: Manage +group: Access +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# LDAP synchronization **(PREMIUM SELF)** + +If you have [configured LDAP to work with GitLab](index.md), GitLab can automatically synchronize +users and groups. This process updates user and group information. + +You can change when synchronization occurs. + +## User sync + +Once per day, GitLab runs a worker to check and update GitLab +users against LDAP. + +The process executes the following access checks: + +- Ensure the user is still present in LDAP. +- If the LDAP server is Active Directory, ensure the user is active (not + blocked/disabled state). This check is performed only if + `active_directory: true` is set in the LDAP configuration. + +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. + +<!-- vale gitlab.Spelling = NO --> + +For more information, see [Bitmask Searches in LDAP](https://ctovswild.com/2009/09/03/bitmask-searches-in-ldap/). + +<!-- vale gitlab.Spelling = YES --> + +The user is set to an `ldap_blocked` state in GitLab if the previous conditions +fail. This means the user cannot sign in or push or pull code. + +The process also updates the following user information: + +- Email address +- SSH public keys (if `sync_ssh_keys` is set) +- Kerberos identity (if Kerberos is enabled) + +The LDAP sync process: + +- Updates existing users. +- Creates new users on first sign in. + +### Adjust LDAP user sync schedule + +By default, GitLab runs a worker once per day at 01:30 a.m. server time to +check and update GitLab users against LDAP. + +You can manually configure LDAP user sync times by setting the +following configuration values, in cron format. If needed, you can +use a [crontab generator](http://www.crontabgenerator.com). +The example below shows how to set LDAP user +sync to run once every 12 hours at the top of the hour. + +**Omnibus installations** + +1. Edit `/etc/gitlab/gitlab.rb`: + + ```ruby + gitlab_rails['ldap_sync_worker_cron'] = "0 */12 * * *" + ``` + +1. [Reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect. + +**Source installations** + +1. Edit `config/gitlab.yaml`: + + ```yaml + cron_jobs: + ldap_sync_worker_cron: + "0 */12 * * *" + ``` + +1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. + +## Group sync + +If your LDAP supports the `memberof` property, when the user signs in for the +first time GitLab triggers a sync for groups the user should be a member of. +That way they don't have to wait for the hourly sync to be granted +access to their groups and projects. + +A group sync process runs every hour on the hour, and `group_base` must be set +in LDAP configuration for LDAP synchronizations based on group CN to work. 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 configuration file it looks like the +following. + +**Omnibus configuration** + +1. Edit `/etc/gitlab/gitlab.rb`: + + ```ruby + gitlab_rails['ldap_servers'] = { + 'main' => { + # snip... + 'group_base' => 'ou=groups,dc=example,dc=com', + } + } + ``` + +1. [Apply your changes to GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure). + +**Source configuration** + +1. Edit `/home/git/gitlab/config/gitlab.yml`: + + ```yaml + production: + ldap: + servers: + main: + # snip... + group_base: ou=groups,dc=example,dc=com + ``` + +1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. + +To take advantage of group sync, group owners or maintainers must [create one +or more LDAP group links](#add-group-links). + +### Add group links + +For information on adding group links by using CNs and filters, refer to the +[GitLab groups documentation](../../../user/group/index.md#manage-group-memberships-via-ldap). + +### 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 are given administrator privileges. The configuration looks +like the following. + +NOTE: +Administrators are not 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. +Additionally, if an LDAP user has an `admin` role, but is not a member of the `admin_group` +group, GitLab revokes their `admin` role when syncing. + +**Omnibus configuration** + +1. Edit `/etc/gitlab/gitlab.rb`: + + ```ruby + gitlab_rails['ldap_servers'] = { + 'main' => { + # snip... + 'group_base' => 'ou=groups,dc=example,dc=com', + 'admin_group' => 'my_admin_group', + } + } + ``` + +1. [Apply your changes to GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure). + +**Source configuration** + +1. 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 + ``` + +1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. + +### Global group memberships lock + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1793) in GitLab 12.0. + +"Lock memberships to LDAP synchronization" setting allows instance administrators +to lock down user abilities to invite new members to a group. + +When enabled, the following applies: + +- Only administrator can manage memberships of any group including access levels. +- Users are not allowed to share project with other groups or invite members to + a project created in a group. + +To enable it, you must: + +1. [Configure LDAP](index.md#configure-ldap). +1. On the top bar, select **Menu > Admin**. +1. On the left sidebar, select **Settings > General**. +1. Expand the **Visibility and access controls** section. +1. Ensure the **Lock memberships to LDAP synchronization** checkbox is selected. + +### Adjust LDAP group sync schedule + +By default, GitLab runs a group sync process every hour, on the hour. +The values shown are in cron format. If needed, you can use a +[Crontab Generator](http://www.crontabgenerator.com). + +WARNING: +Do not start the sync process too frequently as this +could lead to multiple syncs running concurrently. This concern is primarily +for installations with a large number of LDAP users. Review the +[LDAP group sync benchmark metrics](#benchmarks) to see how +your installation compares before proceeding. + +You can manually configure LDAP group sync times by setting the +following configuration values. The example below shows how to set group +sync to run once every two hours at the top of the hour. + +**Omnibus installations** + +1. Edit `/etc/gitlab/gitlab.rb`: + + ```ruby + gitlab_rails['ldap_group_sync_worker_cron'] = "0 */2 * * * *" + ``` + +1. [Reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect. + +**Source installations** + +1. Edit `config/gitlab.yaml`: + + ```yaml + cron_jobs: + ldap_group_sync_worker_cron: + "*/30 * * * *" + ``` + +1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. + +### External groups + +Using the `external_groups` setting allows you to mark all users belonging +to these groups as [external users](../../../user/permissions.md#external-users). +Group membership is checked periodically through the `LdapGroupSync` background +task. + +**Omnibus configuration** + +1. Edit `/etc/gitlab/gitlab.rb`: + + ```ruby + gitlab_rails['ldap_servers'] = { + 'main' => { + # snip... + 'external_groups' => ['interns', 'contractors'], + } + } + ``` + +1. [Apply your changes to GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure). + +**Source configuration** + +1. Edit `config/gitlab.yaml`: + + ```yaml + production: + ldap: + servers: + main: + # snip... + external_groups: ['interns', 'contractors'] + ``` + +1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. + +### Group sync technical details + +This section outlines what LDAP queries are executed and what behavior you +can expect from group sync. + +Group member access are downgraded from a higher level if their LDAP group +membership changes. For example, if a user the Owner role in a group and the +next group sync reveals they should only have the Developer role, their +access is 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` +- `memberuid` + +This means group sync supports (at least) LDAP groups with the following object +classes: + +- `groupOfNames` +- `posixGroup` +- `groupOfUniqueNames` + +Other object classes should work if members are defined as one of the +mentioned attributes. + +Active Directory supports nested groups. Group sync recursively resolves +membership if `active_directory: true` is set in the configuration file. + +##### Nested group memberships + +Nested group memberships are resolved only if the nested group +is found in the configured `group_base`. For example, if GitLab sees a +nested group with DN `cn=nested_group,ou=special_groups,dc=example,dc=com` but +the configured `group_base` is `ou=groups,dc=example,dc=com`, `cn=nested_group` +is ignored. + +#### Queries + +- Each LDAP group is queried a maximum of one time with base `group_base` and + filter `(cn=<cn_from_group_link>)`. +- If the LDAP group has the `memberuid` attribute, GitLab executes 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=<uid_from_group>)` 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 benchmark was extreme and most instances don't +have near this many users or groups. Disk speed, database performance, +network and LDAP server response time affects these metrics. |