使用 LDAP 情况下,Gitlab HTTP 协议 git clone/pull 的分析
核心原因是使用 http 来请求代码
-
用户查找 - 在数据库中查找用户:
User.find_by_login(login) - LDAP 认证 - 如果用户是 LDAP 用户或未找到,会进行 LDAP Bind 和 Search 操作
- 额外的 DN 查找 - 在某些情况下(特别是当 GitLab username 与 LDAP username 不匹配时)会额外查询 LDAP
以下是详细的分析
为什么会出现大量 LDAP 查询?
从您的 LDAP 日志和 GitLab 代码来看,每次使用 HTTP 协议进行 git clone/pull/push 时,GitLab 会进行以下操作:
-
用户查找 - 在数据库中查找用户:
User.find_by_login(login) - LDAP 认证 - 如果用户是 LDAP 用户或未找到,会进行 LDAP Bind 和 Search 操作
- 额外的 DN 查找 - 在某些情况下(特别是当 GitLab username 与 LDAP username 不匹配时)会额外查询 LDAP
查看您配置文件中的 LDAP 设置:
user_filter: ''
空的 user_filter 会导致 GitLab 使用非常宽泛的 LDAP 查询,这就是为什么您会看到 objectclass=* 这样的查询。
解决方案
1. 配置 user_filter(推荐)
在 config/gitlab.yml 中添加合适的 user_filter 来限制查询范围:
ldap:
enabled: true
servers:
main:
# ... 其他配置 ...
# 只查询特定类型的用户对象
user_filter: '(objectClass=person)'
# 或者更具体的过滤器,例如:
# user_filter: '(&(objectClass=person)(employeeType=developer))'
# user_filter: '(&(objectClass=inetOrgPerson)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))'
常用的过滤器示例:
-
'(objectClass=person)'- 只查询人员对象 -
'(objectClass=inetOrgPerson)'- 标准的 LDAP 用户对象类 -
'(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))'- Active Directory 中排除禁用用户
2. 启用 LDAP 用户同步缓存
GitLab 会在数据库中缓存 LDAP 用户信息。确保:
ldap:
enabled: true
servers:
main:
# ... 其他配置 ...
# 设置合理的超时时间
timeout: 10
# 如果是 Active Directory,设置为 true
active_directory: false # 根据您的实际情况设置
3. 使用 Personal Access Tokens (推荐用于自动化)
对于 CI/CD 或自动化脚本,建议使用 Personal Access Token 而不是密码:
# 使用 PAT 进行 git 操作
git clone https://username:TOKEN@gitlab.example.com/project.git
这样可以完全避免 LDAP 查询。
4. 检查并优化 LDAP 服务器设置
在 LDAP 服务器端:
- 为常用查询添加索引(特别是
uid,cn,dn字段) - 配置查询结果缓存
- 限制每个查询返回的属性数量
5. 验证配置
修改配置后,测试 LDAP 连接:
# 在 GitLab 服务器上运行
cd /Users/jacksontom/jihu-project/dev/gdk/gitlab
bundle exec rake gitlab:ldap:check RAILS_ENV=production
6. 监控改善情况
配置更改后,您应该看到:
- LDAP 查询中不再出现
objectclass=* - 查询会变成类似
(&(uid=username)(objectClass=person))的更具体的过滤器 - 每次 git 操作的 LDAP 查询次数显著减少
为什么频繁的 objectclass=* 查询有问题?
-
性能影响:
objectclass=*会匹配 LDAP 目录中的所有对象,包括用户、组、组织单位等 - 网络开销:返回大量不必要的数据
- LDAP 服务器负载:每个查询都需要扫描整个目录树
总结
您当前的情况不完全正常,主要是因为:
- 缺少
user_filter配置导致查询范围过大 - 每次 HTTP Git 认证都会触发 LDAP 查询(这是正常的)
- 但查询应该是精确的,而不是
objectclass=*
立即建议:在 config/gitlab.yml 中添加 user_filter: '(objectClass=person)',重启 GitLab,然后观察 LDAP 日志的变化。
由 TianLu 编辑于