使用SASL的Gitlab LDAP

时间:2017-10-02 20:24:18

标签: ldap gitlab

我试图配置Gitlab 10.0.2以使用LDAP身份验证。我不能使用TLS,所以我希望使用SASL DIGEST-MD5来提供比明文更好的安全性。 Gitlab文档seems to suggest that this is possible(强调我的):

  

您应禁用匿名LDAP身份验证并启用简单的或SASL身份验证

但是,它没有提供有关如何配置SASL绑定的任何指导。我已尝试设置the omniauth-ldap README中提到的try_saslsasl_mechanisms配置密钥,但我已通过Wireshark验证仍在使用简单绑定而不是DIGEST- MD5。

我的gitlab.rb中的相关部分:

gitlab_rails['ldap_enabled'] = true

###! **remember to close this block with 'EOS' below**
gitlab_rails['ldap_servers'] = YAML.load <<-'EOS'
  main: # 'main' is the GitLab 'provider ID' of this LDAP server
    label: 'LDAP'
    host: 'my-ldap.example.com'
    port: 389
    uid: 'sAMAccountName'
    bind_dn: 'my-username'
    password: 'my-password'
    encryption: 'plain' # "start_tls" or "simple_tls" or "plain"
    verify_certificates: true
    ca_file: ''
    ssl_version: ''
    active_directory: true
    try_sasl: true
    sasl_mechanisms: 'DIGEST-MD5'
    allow_username_or_email_login: false
    block_auto_created_users: false
    base: ''
    user_filter: ''
    attributes:
      username:   'sAMAccountName'
      email:      'mail'
      name:       'displayName'
      first_name: 'givenName'
      last_name:  'sn'
    ## EE only
    group_base: ''
    admin_group: ''
    sync_ssh_keys: false
EOS

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我得到了它的工作,但只是通过修补Gitlab安装。所以,要预先警告:这里有龙

修补程序

/etc/gitlab/gitlab.rb

gitlab_rails['ldap_enabled'] = true

###! **remember to close this block with 'EOS' below**
gitlab_rails['ldap_servers'] = YAML.load <<-'EOS'
  main: # 'main' is the GitLab 'provider ID' of this LDAP server
    label: 'LDAP'
    host: 'my-ldap.example.com'
    port: 389
    uid: 'sAMAccountName'
    bind_dn: 'my-username'
    bind_target: 'userPrincipalName'
    password: 'my-password'
    encryption: 'plain' # "start_tls" or "simple_tls" or "plain"
    verify_certificates: true
    ca_file: ''
    ssl_version: ''
    active_directory: true
    try_sasl: true
    sasl_mechanisms: ['DIGEST-MD5']
    sasl_realm: 'Digest'
    allow_username_or_email_login: false
    block_auto_created_users: false
    base: ''
    user_filter: ''
    attributes:
      username:   'sAMAccountName'
      email:      'mail'
      name:       'displayName'
      first_name: 'givenName'
      last_name:  'sn'
    ## EE only
    group_base: ''
    admin_group: ''
    sync_ssh_keys: false
EOS

/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/ldap/config.rb

修补程序omniauth_options以传递配置参数

def omniauth_options
  opts = base_options.merge(
    base: base,
    encryption: options['encryption'],
    filter: omniauth_user_filter,
    name_proc: name_proc,
    disable_verify_certificates: !options['verify_certificates']
  )

  if has_auth?
    opts.merge!(
      bind_dn: options['bind_dn'],
      password: options['password']
    )
  end

  opts[:ca_file] = options['ca_file'] if options['ca_file'].present?
  opts[:ssl_version] = options['ssl_version'] if options['ssl_version'].present?
  opts[:try_sasl] = options['try_sasl'] if options['try_sasl'].present?
  opts[:sasl_mechanisms] = options['sasl_mechanisms'] if options['sasl_mechanisms'].present?
  opts[:bind_target] = options['bind_target'] if options['bind_target'].present?
  opts[:sasl_digest_uri] = options['sasl_digest_uri'] if options['sasl_digest_uri'].present?
  opts[:sasl_realm] = options['sasl_realm'] if options['sasl_realm'].present?

  opts
end

/opt/gitlab/embedded/lib/ruby/gems/2.3.0/gems/pyu-ruby-sasl-0.0.3.3/lib/sasl/digest_md5.rb

修补程序receive使用来自配置的领域优先于来自服务器质询的领域(这是针对活动目录进行身份验证所必需的)

response['realm'] = preferences.realm || c['realm']

/opt/gitlab/embedded/lib/ruby/gems/2.3.0/gems/gitlab_omniauth-ldap-2.0.4/lib/omniauth-ldap/adaptor.rb

修改有效的配置密钥

VALID_ADAPTER_CONFIGURATION_KEYS = [
  :hosts, :host, :port, :encryption, :disable_verify_certificates, :bind_dn, :password, :try_sasl,
  :sasl_mechanisms, :bind_target, :uid, :base, :allow_anonymous, :filter, :ca_file, :ssl_version,
  :sasl_digest_uri, :sasl_realm,

  # Deprecated
  :method
]

initialize中,将'dn'设置为默认绑定目标

@configuration[:bind_target] ||= :dn

修改bind_as以修复对SASL配置密钥的检查并使用绑定目标

def bind_as(args = {})
  result = false
  @connection.open do |me|
    rs = me.search args
    if rs and rs.first and user = rs.first.first(@bind_target).to_s
      password = args[:password]
      password = password.call if password.respond_to?(:call)
      if @bind_method == :sasl
      result = rs.first if me.bind(sasl_auths({:username => user, :password => password}).first)
      else
      result = rs.first if me.bind(:method => :simple, :username => user,
                          :password => password)
      end
    end
  end
  result
end

我不太了解ruby,但是从我可以看出未打补丁的版本被打破并将始终使用简单的绑定

(Unpatched)
method = args[:method] || @method
password = password.call if password.respond_to?(:call)
if method == 'sasl'

修补程序sasl_bind_setup_digest_md5将领域属性传递给SASL

def sasl_bind_setup_digest_md5(options)
  bind_dn = options[:username]
  digest_uri = options[:digest_uri] || @sasl_digest_uri || "ldap/#{@host}"
  realm = options[:realm] || @sasl_realm || @host
  initial_credential = ""
  challenge_response = Proc.new do |cred|
    pref = SASL::Preferences.new :digest_uri => digest_uri, :realm => realm, :username => bind_dn, :has_password? => true, :password => options[:password]
    sasl = SASL.new("DIGEST-MD5", pref)
    response = sasl.receive("challenge", cred)
    response[1]
  end
  [initial_credential, challenge_response]
end

结果

 tshark -i any -f "tcp port 389" -Y "ldap" -T text
  4 0.000627931  **.**.**.** -> **.**.**.**  LDAP 96 bindRequest(1) "<ROOT>" [Malformed Packet]
  5 0.001160032  **.**.**.** -> **.**.**.**  LDAP 323 bindResponse(1) saslBindInProgress
  7 0.001826383  **.**.**.** -> **.**.**.**  LDAP 432 bindRequest(1) "<ROOT>" sasl
  8 0.005544029  **.**.**.** -> **.**.**.**  LDAP 132 bindResponse(1) success
  9 0.005872822  **.**.**.** -> **.**.**.**  LDAP 264 searchRequest(2) "<ROOT>" baseObject
 11 0.006116795  **.**.**.** -> **.**.**.**  LDAP 253 searchResEntry(2) "<ROOT>"
 13 0.006579437  **.**.**.** -> **.**.**.**  LDAP 175 searchRequest(3) "*************" wholeSubtree
 17 0.008437742  **.**.**.** -> **.**.**.**  LDAP 584 searchResEntry(3) "CN=*******************************************"
 18 0.009509758  **.**.**.** -> **.**.**.**  LDAP 96 bindRequest(4) "<ROOT>" [Malformed Packet]
 19 0.009794269  **.**.**.** -> **.**.**.**  LDAP 323 bindResponse(4) saslBindInProgress
 20 0.010279312  **.**.**.** -> **.**.**.**  LDAP 431 bindRequest(4) "<ROOT>" sasl
 21 0.013109814  **.**.**.** -> **.**.**.**  LDAP 132 bindResponse(4) success