通用 LDAP 设置
极狐GitLab 与 LDAP 集成,以支持用户身份验证。
此集成适用于大多数 LDAP 兼容目录服务器,包括:
- Microsoft Active Directory。 不支持 Microsoft Active Directory Trusts。
- Apple Open Directory。
- Open LDAP。
- 389 Server。
通过 LDAP 添加的用户获得许可席位。
极狐GitLab 包括增强的集成功能,包括组成员同步和多 LDAP 服务器支持。
安全
假设 LDAP 用户:
- 无法更改他们的
mail
、email
或userPrincipalName
属性。允许在 LDAP 服务器上更改电子邮件的用户,可能会接管您服务器上的任何账户。 - 拥有唯一的电子邮件地址。否则,具有相同电子邮件地址的 LDAP 用户可能会共享相同的账户。
如果您的 LDAP 用户被允许在 LDAP 服务器上更改他们的 mail
、email
或 userPrincipalName
属性,或者共享电子邮件地址,我们建议不要使用 LDAP 集成。
删除用户
从 LDAP 服务器中删除的用户,会立即被阻止登录 LDAP 并且不再占用许可证。然而,LDAP 检查缓存时间为 1 小时(对于专业版用户是可配置的)。 这意味着已经登录或通过 SSH 使用 git 的用户还可以访问最多一个小时,您可以在管理中心手动立即阻止所有访问。
Git 密码认证
即使在应用设置中禁用了 Git 密码身份认证,启用 LDAP 的用户可以使用用户名、电子邮件和 LDAP 密码对 Git 进行身份认证。
为现有 GitLab 用户启用 LDAP 登录
当用户第一次使用 LDAP 登录极狐GitLab,并且他们的 LDAP 电子邮件地址是现有用户的主要电子邮件时,LDAP DN 与现有用户相关联。如果在极狐 GitLab 用户数据库中找不到 LDAP 的电子邮件,则会创建一个新用户。
也就是说,如果现有用户想要为自己启用 LDAP 登录,应检查他们在极狐 GitLab 中的电子邮件地址与他们的 LDAP 电子邮件地址匹配,然后可以使用 LDAP 凭据登录极狐GitLab。
配置
要启用 LDAP 集成,当使用 Omnibus GitLab 时,您必须在 /etc/gitlab/gitlab.rb
中添加 LDAP 服务器设置;当使用源安装时,您需要在 /home/git/gitlab/config/gitlab.yml
中添加 LDAP 服务器设置。
有一个 Rake 任务可用于检查 LDAP 配置。使用下方文档配置 LDAP 后,请参阅 LDAP 检查 Rake 任务获取更多信息。
encryption
的值 simple_tls
对应于 LDAP 库中的“Simple TLS”。start_tls
对应于 StartTLS,不要与常规 TLS 混淆。通常,如果您指定 simple_tls
在端口 636 上,而 start_tls
(StartTLS)将在端口 389 上。plain
也在端口 389 上运行。删除的值:tls
被替换为 start_tls
,ssl
被替换为 simple_tls
。LDAP 用户必须设置一个电子邮件地址,无论是否用于登录。
配置案例
Omnibus 配置
gitlab_rails['ldap_enabled'] = true
gitlab_rails['prevent_ldap_sign_in'] = false
gitlab_rails['ldap_servers'] = {
'main' => {
'label' => 'LDAP',
'host' => 'ldap.mydomain.com',
'port' => 389,
'uid' => 'sAMAccountName',
'encryption' => 'simple_tls',
'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' => '',
'ciphers' => '',
'cert' => '',
'key' => ''
},
'timeout' => 10,
'active_directory' => true,
'allow_username_or_email_login' => false,
'block_auto_created_users' => false,
'base' => 'dc=example,dc=com',
'user_filter' => '',
'attributes' => {
'username' => ['uid', 'userid', 'sAMAccountName'],
'email' => ['mail', 'email', 'userPrincipalName'],
'name' => 'cn',
'first_name' => 'givenName',
'last_name' => 'sn'
},
'lowercase_usernames' => false,
# EE Only
'group_base' => '',
'admin_group' => '',
'external_groups' => [],
'sync_ssh_keys' => false
}
}
源安装配置
production:
# snip...
ldap:
enabled: false
prevent_ldap_sign_in: false
servers:
main:
label: 'LDAP'
...
基本配置
配置项 | 说明 | 是否必须配置 | 举例 |
---|---|---|---|
label
| LDAP 服务器的人性化名称。在登录页面展示。 | Yes |
'Paris' or 'Acme, Ltd.'
|
host
| LDAP 服务器的 IP 地址或域名。 | Yes | 'ldap.mydomain.com'
|
port
| 与 LDAP 服务器连接的端口。类型为整数而非字符串。 | Yes |
389 或 636 (用于 SSL)
|
uid
| 用户名的 LDAP 属性。应该是属性,而不是映射到 uid 的值。
| Yes |
'sAMAccountName' 、'uid' 或 'userPrincipalName'
|
bind_dn
| 绑定用户的完整 DN。 | No |
'america\momo' 或 'CN=Gitlab,OU=Users,DC=domain,DC=com'
|
password
| 绑定用户的密码。 | No | 'your_great_password'
|
encryption
| 加密方法。method 已废弃。
| Yes |
'start_tls' 、'simple_tls' 或 'plain'
|
verify_certificates
| 如果加密方法为 start_tls 或 simple_tls ,则启用 SSL 证书验证。默认为 true。
| No | boolean |
timeout
| 为 LDAP 查询设置超时时间(以秒为单位)。当 LDAP 服务器无法响应时,有助于阻止请求。0 值表示没有超时(默认值:10 )
| No |
10 或 30
|
active_directory
| 该设置指定 LDAP 服务器是否为 Active Directory LDAP 服务器。对于非 AD 服务器,会跳过 AD 特定查询。如果您的 LDAP 服务器不是 AD,请将其设置为 false。 | No | boolean |
allow_username_or_email_login
| 如果启用,系统将忽略用户在登录时提交的 LDAP 用户名中第一个 @ 之后的所有内容。如果您在 ActiveDirectory 上使用 uid: 'userPrincipalName' ,您必须禁用这个设置,因为 userPrincipalName 包含一个 @ 。
| No | boolean |
block_auto_created_users
| 为了严格控制计费用户数量,请启用此设置阻止新用户直到他们被管理员清除(默认值:false)。 | No | boolean |
base
| 搜索用户的基础路径。 | Yes |
'ou=people,dc=gitlab,dc=example' or 'DC=mydomain,DC=com'
|
user_filter
| 过滤 LDAP 用户。格式:RFC 4515 注意: 不支持 omniauth-ldap 的自定义过滤器语法。
| No | 查阅用户过滤器的案例。 |
lowercase_usernames
| 如果启用,系统转换用户名称为小写。 | No | boolean |
retry_empty_result_with_codes
| 如果结果/内容为空,将尝试重试操作时的 LDAP 查询响应代码数组。 | No | [80]
|
用户过滤器样例
user_filter
字段语法的一些示例:
'(employeeType=developer)'
'(&(objectclass=user)(|(samaccountname=momo)(samaccountname=toto)))'
SSL 配置
配置项 | 说明 | 是否必须配置 | 举例 |
---|---|---|---|
ca_file
| 例如,当您需要使用内部 CA 时,指定 PEM 格式的 CA 证书文件的路径。 | No | '/etc/ca.pem'
|
ssl_version
| 如果 OpenSSL 默认值不合适,指定 OpenSSL 的 SSL 版本。 | No | 'TLSv1_1'
|
ciphers
| 用于与 LDAP 服务器通信的特定 SSL 密码。 | No | 'ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2'
|
cert
| 客户凭证。 | No | '-----BEGIN CERTIFICATE----- <REDACTED> -----END CERTIFICATE -----'
|
key
| 客户私钥。 | No | '-----BEGIN PRIVATE KEY----- <REDACTED> -----END PRIVATE KEY -----'
|
属性配置
系统为 LDAP 用户创建账户时,使用的 LDAP 属性。指定的属性可以是字符串形式的属性名称(例如,'mail'
),也可以是要按顺序尝试的属性名称数组(例如,['mail', 'email']
)。用户的 LDAP 登录时指定为 uid
的属性。
配置项 | 说明 | 是否必须配置 | 举例 |
---|---|---|---|
username
| 用户名用于用户自己项目的路径 (例如 gitlab.example.com/username/project ) ,以及在议题、合并请求和评论中提及时 (例如 @username )。如果 username 包含电子邮件地址, 则地址中 @ 之前的部分作为极狐GitLab 用户名。
| No | ['uid', 'userid', 'sAMAccountName']
|
email
| 用户电子邮件的 LDAP 属性。 | No | ['mail', 'email', 'userPrincipalName']
|
name
| 用户显示名称的 LDAP 属性。如果 name 为空, 完整的显示名称从 first_name 和 last_name 获取。
| No |
'cn' 或 'displayName' 属性通常带有全名。或者,您可以通过指定不存在的属性,例如 'somethingNonExistent' ,来强制使用 first_name 和 last_name 。
|
first_name
| 用户 first name 的 LDAP 属性。当 name 属性不存在时使用。
| No | 'givenName'
|
last_name
| 用户 last name 的 LDAP 属性。当 name 属性不存在时使用。
| No | 'sn'
|
LDAP 同步配置
配置项 | 说明 | 是否必须配置 | 举例 |
---|---|---|---|
group_base
| 搜索用户组的基础路径。 | No | 'ou=groups,dc=gitlab,dc=example'
|
admin_group
| 包含 GitLab 管理员的组的 CN。注意:不是cn=administrators 或完整的DN。
| No | 'administrators'
|
external_groups
| 包含应被视为外部用户的组 CN 数组。 注意:不是 cn=interns 或完整的 DN。
| No | ['interns', 'contractors']
|
sync_ssh_keys
| 包含用户的公共 SSH 密钥的 LDAP 属性。 | No |
'sshPublicKey' 或者 false(如果未设置)。
|
设置 LDAP 用户过滤器
如果您想要 LDAP 服务器上的一部分 LDAP 用户具有访问极狐GitLab 的权限,第一步应该缩小配置的 base
范围。但是,有时必须进一步过滤用户。在这种情况下,您可以设置 LDAP 用户过滤器。过滤器必须符合 RFC 4515。
Omnibus 配置
gitlab_rails['ldap_servers'] = {
'main' => {
# snip...
'user_filter' => '(employeeType=developer)'
}
}
源安装配置
production:
ldap:
servers:
main:
# snip...
user_filter: '(employeeType=developer)'
如果要限制对 Active Directory 组的嵌套成员的访问,请使用以下语法:
plaintext
(memberOf:1.2.840.113556.1.4.1941:=CN=My Group,DC=Example,DC=com)
获取 “LDAP_MATCHING_RULE_IN_CHAIN” 过滤器的更多信息,请参阅 Microsoft 搜索过滤器语法 文档。
不支持 OmniAuth LDAP 使用的自定义过滤器语法。
转义特殊字符
user_filter
DN 可以包含特殊字符。 例如:
-
逗号:
OU=GitLab, Inc,DC=gitlab,DC=com
-
括号:
OU=Gitlab (Inc),DC=gitlab,DC=com
这些字符必须按照 RFC 4515 文档所述进行转义。
-
使用
\2C
转义逗号。例如:OU=GitLab\2C Inc,DC=gitlab,DC=com
-
同样地,使用
\28
和\29
转义括号。例如:OU=Gitlab \28Inc\29,DC=gitlab,DC=com
启用 LDAP 用户名小写
某些 LDAP 服务器,根据其配置可以返回大写的用户名。这可能导致一些令人困惑的问题,比如使用大写名称创建链接或命名空间。
极狐GitLab 可以通过启用 lowercase_usernames
配置项,自动将 LDAP 服务器提供的用户名小写。默认情况下,该配置选项为 false
。
Omnibus 配置
-
编辑
/etc/gitlab/gitlab.rb
:gitlab_rails['ldap_servers'] = { 'main' => { # snip... 'lowercase_usernames' => true } }
-
重新配置极狐GitLab 使更改生效。
Source configuration
-
编辑
config/gitlab.yaml
:production: ldap: servers: main: # snip... lowercase_usernames: true
-
重启极狐GitLab 使更改生效。
禁用 LDAP web 登录
当首选 SAML 等替代方法时,阻止通过 Web UI 使用 LDAP 凭据会很有用。 这允许 LDAP 用于组同步,同时还允许您的 SAML 身份提供商处理额外的检查,如自定义 2FA。
禁用 LDAP Web 登录后,用户在登录页面上看不到 LDAP 选项。这不会禁用使用 LDAP 凭据进行 Git 访问。
Omnibus 配置
-
编辑
/etc/gitlab/gitlab.rb
:gitlab_rails['prevent_ldap_sign_in'] = true
-
重新配置极狐GitLab 使配置生效。
源安装配置
-
编辑
config/gitlab.yaml
:production: ldap: prevent_ldap_sign_in: true
-
重启极狐GitLab 使配置生效。
使用加密凭证
除了将 LDAP 集成凭证以明文形式存储在配置文件中,您可以选择为 LDAP 凭证使用加密文件。要使用该功能,首先必须启用 GitLab 加密配置。
LDAP 的加密配置存放于加密的 YAML 文件中。默认情况下,该文件将在 shared/encrypted_configuration/ldap.yaml.enc
中创建,位置可以配置。
文件中的未加密内容应该是 LDAP 配置中 servers
的密钥配置。
加密文件的配置项有:
bind_dn
password
可以使用 LDAP 密钥编辑 Rake 命令配置加密内容。
Omnibus 配置
如果最初 LDAP 配置如下:
- 在
/etc/gitlab/gitlab.rb
中:
gitlab_rails['ldap_servers'] = {
'main' => {
# snip...
'bind_dn' => 'admin',
'password' => '123'
}
}
-
编辑加密密钥:
sudo gitlab-rake gitlab:ldap:secret:edit EDITOR=vim
-
LDAP 密钥的未加密内容应按以下案例配置:
main: bind_dn: admin password: '123'
-
编辑
/etc/gitlab/gitlab.rb
并移除user_bn
和password
设置。 -
重新配置极狐GitLab 使更改生效。
源安装配置
如果最初 LDAP 配置如下:
-
在
config/gitlab.yaml
中:production: ldap: servers: main: # snip... bind_dn: admin password: '123'
-
编辑加密密钥:
bundle exec rake gitlab:ldap:secret:edit EDITOR=vim RAILS_ENVIRONMENT=production
-
LDAP 密钥的未加密内容应按以下案例配置:
main: bind_dn: admin password: '123'
-
编辑
config/gitlab.yaml
并移除user_bn
和password
设置。 -
重启极狐GitLab 使更改生效。
加密
TLS 服务器认证
支持两种加密方法,simple_tls
和 start_tls
。
对于任一种加密方法,如果设置了 verify_certificates: false
,在交换 LDAP 协议数据之前,先与 LDAP 服务器建立加密连接但不验证 LDAP 服务器的 SSL 证书。
限制
TLS 客户端认证
未由 Net::LDAP
实现。
您应该禁用匿名 LDAP 身份验证,并启用简单或 SASL 身份验证。LDAP 服务器中的 TLS 客户端身份验证不是强制性的,并且客户端无法使用 TLS 协议进行身份验证。
多 LDAP 服务器
您可以为您的实例配置连接多个 LDAP 服务器。
要添加另一个 LDAP 服务器:
- 复制 主配置 下的设置。
- 编辑复制的设置以匹配额外的 LDAP 服务器。
务必选择一个不同的提供商 ID,ID 可由字母 a-z 和数字 0-9 组成。此 ID 存储在数据库中,以便实例可以记住用户属于哪个 LDAP 服务器。
基于上图的示例,gitlab.rb
应按下方案例进行配置:
gitlab_rails['ldap_enabled'] = true
gitlab_rails['ldap_servers'] = {
'main' => {
'label' => 'GitLab AD',
'host' => 'ad.example.org',
'port' => 636,
...
},
'secondary' => {
'label' => 'GitLab Secondary AD',
'host' => 'ad-secondary.example.net',
'port' => 636,
...
},
'tertiary' => {
'label' => 'GitLab Tertiary AD',
'host' => 'ad-tertiary.example.net',
'port' => 636,
...
}
}
如果您配置多个 LDAP 服务器,请为每个条目的 label
使用唯一的命名。该标签作为登录页面上选项卡的显示名称。
用户同步
系统将运行一个 worker 用来检查和更新 LDAP 用户,每天一次。
该进程执行以下访问检查:
- 确保用户仍存在于 LDAP 中。
- 如果 LDAP 服务器是 Active Directory,请确保用户处于 active 状态(不能时 blocked 或 disabled 状态)。只有在 LDAP 设置了
active_directory: true
时,才会执行检查。
获取更多信息,查阅 LDAP 的 Bitmask 搜索。
若检查失败,用户将被设置为 ldap_blocked
状态,这意味着用户无法登录、推送或拉取代码。
该过程还会更新以下用户信息:
- 电子邮件地址
- SSH 公钥(如果设置了
sync_ssh_keys
) - Kerberos 身份(如果启用了 Kerberos)
LDAP 同步过程:
- 更新现有用户。
- 首次登录时创建新用户。
调整 LDAP 用户同步计划
默认情况下,每天在服务器时间上午 01:30 运行一次 worker,检查和更新用户。
您可以使用 cron 格式,手动配置 LDAP 用户同步时间。如果需要,您可以使用 crontab 生成器。下面的示例展示了如何将 LDAP 用户同步设置为每 12 小时运行一次。
Omnibus 安装方式
-
编辑
/etc/gitlab/gitlab.rb
:gitlab_rails['ldap_sync_worker_cron'] = "0 */12 * * *"
-
重新配置极狐GitLab 使更改生效。
源安装方式
-
编辑
config/gitlab.yaml
:cron_jobs: ldap_sync_worker_cron: "0 */12 * * *"
-
重启极狐GitLab 使更改生效。
群组同步
如果您的 LDAP 支持 memberof
属性,当用户第一次登录极狐GitLab 时,将触发用户所在组的同步。这样他们不需要等待经过每小时的同步后,才能访问他们的小组和项目。
组同步进程每小时执行一次,必须在 LDAP 配置中设置 group_base
,使 LDAP 同步基于组的 CN。极狐GitLab 的群组成员将基于 LDAP 的组成员自动更新。
group_base
配置应该是一个基本的 LDAP container
,例如一个 ‘organization’ 或 ‘organizational unit’,包含极狐GitLab 可用的 LDAP 组。例如,group_base
可以配置为 ou=groups,dc=example,dc=com
,在配置文件中如下例。
Omnibus 配置
-
编辑
/etc/gitlab/gitlab.rb
:gitlab_rails['ldap_servers'] = { 'main' => { # snip... 'group_base' => 'ou=groups,dc=example,dc=com', } }
源安装配置
-
编辑
/home/git/gitlab/config/gitlab.yml
:production: ldap: servers: main: # snip... group_base: ou=groups,dc=example,dc=com
-
重启极狐GitLab 使更改生效。
为实现群组同步,群组的拥有者或维护需要创建一个或多个 LDAP 群组链接。
管理员同步
作为组同步的扩展,您可以自动管理您的全局管理员。通过 admin_group
指定组的 CN,所有在这个 LDAP 组内的成员都会获得管理员去权限。配置举例如下所示。
group_base
也与 admin_group
一起指定。同样,只需要指定 admin_group
的 CN,而不是完整的 DN。此外,如果 LDAP 用户具有 admin
角色,但不是 admin_group
组的成员,则 GitLab 在同步时会撤销其 admin
角色。
Omnibus 配置
-
编辑
/etc/gitlab/gitlab.rb
:gitlab_rails['ldap_servers'] = { 'main' => { # snip... 'group_base' => 'ou=groups,dc=example,dc=com', 'admin_group' => 'my_admin_group', } }
源安装配置
-
编辑
/home/git/gitlab/config/gitlab.yml
:production: ldap: servers: main: # snip... group_base: ou=groups,dc=example,dc=com admin_group: my_admin_group
-
重启极狐GitLab 使变更生效。
全局群组成员锁
“LDAP 同步时锁定成员身份”设置允许实例管理员锁定用户邀请新成员加入群组的权限。
当启用时,应用以下功能:
- 只有管理员可以管理任何群组的成员资格,包括访问级别。
- 不许云用户与其它群组共享项目,或邀请成员加入本群组的项目。
要启用它,您必须执行以下操作:
- 启用 LDAP。
- 在顶部导航栏,选择 目录 > 管理。
- 在左侧导航栏,选择 设置 > 通用。
- 展开 可见性与访问控制 区域。
- 确保勾选 锁定成员身份到 LDAP 同步 复选框。
调整 LDAP 群组同步计划
默认情况下,系统每小时运行一次群组同步。显示值为 cron 格式。如果需要,您可以使用 Crontab 生成器。
您可以通过设置以下配置值,手动配置 LDAP 组同步时间。下面的示例展示了如何将群组同步设置为每两个小时在整点运行一次。
Omnibus 安装
-
编辑
/etc/gitlab/gitlab.rb
:gitlab_rails['ldap_group_sync_worker_cron'] = "0 */2 * * * *"
-
重新配置极狐GitLab 使更改生效。
源安装
-
编辑
config/gitlab.yaml
:cron_jobs: ldap_group_sync_worker_cron: "*/30 * * * *"
-
重启极狐GitLab 使更改生效。
外部群组
使用 external_groups
设置,允许您将属于这些组的所有用户标记为外部用户。通过 LdapGroupSync
后台任务定期检查群组成员身份。
Omnibus 配置
-
编辑
/etc/gitlab/gitlab.rb
:gitlab_rails['ldap_servers'] = { 'main' => { # snip... 'external_groups' => ['interns', 'contractors'], } }
源安装配置
-
编辑
config/gitlab.yaml
:production: ldap: servers: main: # snip... external_groups: ['interns', 'contractors']
-
重启极狐GitLab 使更改生效。
群组同步技术细节
本节概述了 LDAP 查询是如何执行的以及群组同步的表现。
如果 LDAP 组成员身份发生变化,群组成员的权限将从更高的级别降级。例如,如果用户在组中的
支持的 LDAP 组属性
支持使用的成员属性:
member
submember
uniquemember
memberof
memberuid
这以为这组同步支持需要 LDAP 组至少具有以下对象类:
groupOfNames
posixGroup
groupOfUniqueNames
如果成员由以上提及的属性之一定义,则其它对象类应该有效。
Active Directory 支持嵌套组。 如果在配置文件中设置了 active_directory: true
,则组同步会递归地解析成员身份。
Nested group memberships
只有在配置的 group_base
中找到嵌套组时,才会解析嵌套组成员身份。 只有在配置的 group_base
中找到嵌套组时,才会解析嵌套组成员身份。例如,如果系统看到一个
DN 为 cn=nested_group,ou=special_groups,dc=example,dc=com
的嵌套组,但配置的 group_base
为 ou=groups,dc=example,dc=com
,忽略 cn=nested_group
。
查询
-
每个 LDAP 组使用基础
group_base
和过滤器(cn=<cn_from_group_link>)
最多查询一次。 -
如果 LDAP 组具有
memberuid
属性,系统会为每个成员执行另一个 LDAP 查询以获取每个用户的完整 DN。这些查询使用基础base
、范围base object
和过滤器执行,具体取决于是否设置了user_filter
。 过滤器可以是(uid=<uid_from_group>)
或user_filter
的集合。
基准
组同步的写入尽可能地提高性能。数据会被缓存,数据库已优化,并且最小化 LDAP 查询。最后一次基准测试实现了以下指标:
对于 20000 个 LDAP 用户、11000 个 LDAP 组合和 1000 个极狐GitLab 群组,每个群组有 10 个 LDAP 组链接:
- 初始同步(系统中未分配现有成员)耗时 1.8 小时
- 后续同步(检查成员资格,无写入)耗时 15 分钟
这些指标提供基准,性能可能会受多重因素影响。这是一个个极端测试,大多数实例不会拥有这么多用户或群组。磁盘速度、数据库性能、网络和 LDAP 服务器响应时间均会影响指标。