Skip to content

使用 LDAP 情况下,Gitlab HTTP 协议 git clone/pull 的分析

核心原因是使用 http 来请求代码

  1. 用户查找 - 在数据库中查找用户:User.find_by_login(login)
  2. LDAP 认证 - 如果用户是 LDAP 用户或未找到,会进行 LDAP Bind 和 Search 操作
  3. 额外的 DN 查找 - 在某些情况下(特别是当 GitLab username 与 LDAP username 不匹配时)会额外查询 LDAP

以下是详细的分析

为什么会出现大量 LDAP 查询?

从您的 LDAP 日志和 GitLab 代码来看,每次使用 HTTP 协议进行 git clone/pull/push 时,GitLab 会进行以下操作:

  1. 用户查找 - 在数据库中查找用户:User.find_by_login(login)
  2. LDAP 认证 - 如果用户是 LDAP 用户或未找到,会进行 LDAP Bind 和 Search 操作
  3. 额外的 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=* 查询有问题?

  1. 性能影响objectclass=* 会匹配 LDAP 目录中的所有对象,包括用户、组、组织单位等
  2. 网络开销:返回大量不必要的数据
  3. LDAP 服务器负载:每个查询都需要扫描整个目录树

总结

您当前的情况不完全正常,主要是因为:

  • 缺少 user_filter 配置导致查询范围过大
  • 每次 HTTP Git 认证都会触发 LDAP 查询(这是正常的)
  • 但查询应该是精确的,而不是 objectclass=*

立即建议:在 config/gitlab.yml 中添加 user_filter: '(objectClass=person)',重启 GitLab,然后观察 LDAP 日志的变化。

TianLu 编辑于