Gitlab LDAP与SASL

Gitlab LDAP与SASL,ldap,gitlab,Ldap,Gitlab,我正在尝试将Gitlab 10.0.2配置为使用LDAP身份验证。我不能使用TLS,所以我希望使用SASL DIGEST-MD5来提供比明文更好的安全性。Gitlab文档(我的重点): 您应该禁用匿名LDAP身份验证并启用简单的或SASL身份验证 但是,它没有提供关于如何配置SASL绑定的任何指导。我已尝试设置中提到的try_sasl和sasl_机制配置键,但我已使用Wireshark验证了仍然使用简单绑定而不是DIGEST-MD5 my gitlab.rb中的相关部分: gitlab_rail

我正在尝试将Gitlab 10.0.2配置为使用LDAP身份验证。我不能使用TLS,所以我希望使用SASL DIGEST-MD5来提供比明文更好的安全性。Gitlab文档(我的重点):

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

但是,它没有提供关于如何配置SASL绑定的任何指导。我已尝试设置中提到的
try_sasl
sasl_机制
配置键,但我已使用Wireshark验证了仍然使用简单绑定而不是DIGEST-MD5

my 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
gitlab_rails['ldap_enabled']=true
###! **记住用下面的“EOS”关闭此块**

gitlab_rails['ldap_servers']=YAML.load我让它工作了,但只是通过修补gitlab安装。所以,要预先警告:这里有龙

补丁 /etc/gitlab/gitlab.rb /opt/gitlab/embedded/lib/ruby/gems/2.3.0/gems/pyu-ruby-sasl-0.0.3.3/lib/sasl/digest_md5.rb 修补程序
receive
使用配置中的领域优先于服务器中的领域挑战(这是针对active directory进行身份验证所必需的)

/opt/gitlab/embedded/lib/ruby/gems/2.3.0/gems/gitlab_omniauth-ldap-2.0.4/lib/omniauth-ldap/adapter.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
]
在初始化中,将“dn”设置为默认绑定目标

@configuration[:bind_target] ||= :dn
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
修改
bind_as
以修复SASL配置密钥的检查并使用bind target

@configuration[:bind_target] ||= :dn
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\u bind\u setup\u digest\u 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端口389”-Y“ldap”-T文本
4 0.000627931**.*.*.->**.*.*.*.*.*LDAP 96 bindRequest(1)“[格式错误的数据包]
5 0.001160032**.*.*.*.->**.*.*.*.*LDAP 323 bindResponse(1)SASLBindindProgress
7 0.001826383**.*.*.->**.*.*.*.*LDAP 432 bindRequest(1)“sasl
8 0.005544029**.*.*.*.->**.*.*.*.*LDAP 132 bindResponse(1)成功
9 0.005872822**.*.*.->**.*.*.*.*.*LDAP 264搜索请求(2)“baseObject
11 0.006116795**.*.*.->**.*.*.*.*.*LDAP 253 searchResEntry(2)”
13 0.006579437**.*.*.->***.*.*.*.*LDAP 175搜索请求(3)“整体子树”
17 0.008437742**.*.*.*.->***.*.*.*.*LDAP 584 SearchReservery(3)“CN=***********************************************”
18 0.009509758**.*.*.->**.*.*.*.*.*LDAP 96 bindRequest(4)“[格式错误的数据包]
19 0.009794269**.*.*.*.->**.*.*.*.*LDAP 323 bindResponse(4)SASLBindindProgress
20 0.010279312**.*.*.->**.*.*.*.*LDAP 431 bindRequest(4)“sasl
21 0.013109814**.*.*.->**.*.*.*.*.*LDAP 132 bindResponse(4)成功
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