我试图配置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_sasl
和sasl_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
感谢您的帮助。
答案 0 :(得分:1)
我得到了它的工作,但只是通过修补Gitlab安装。所以,要预先警告:这里有龙
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
修补程序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
修补程序receive
使用来自配置的领域优先于来自服务器质询的领域(这是针对活动目录进行身份验证所必需的)
response['realm'] = preferences.realm || c['realm']
修改有效的配置密钥
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