Smartcard configuration against Active Directory throws 500
Summary
A federal customer is trying to set up Smartcard authentication against an Active Directory server but they're getting a 500 error.
Everything in their setup looks right, and they can login with standard LDAP. The failure comes about when using the Smartcard.
At this point we're uncertain as to whether Smartcard authentication supports Active Directory or not.
- If it is supported, then how can we get this to work?
- If it's not supported, we should document that and evaluate if and how we can support it.
Steps to reproduce
On GitLab 13.7.0, set up Smartcard authentication against an Active Directory server according to the documentation.
Their LDAP & Smartcard configuration:
gitlab_rails['ldap_enabled'] = true
gitlab_rails['prevent_ldap_sign_in'] = false
###! **remember to close this block with 'EOS' below**
gitlab_rails['ldap_servers'] = YAML.load <<-'EOS'
main:
label: 'Active Directory'
host: 'redacted.redacted'
port:389
uid: 'sAMAccountName'
bind_dn: 'cn=redacted'
password:'redacted'
encryption: 'plain' # "start_tls" or "simple_tls" or "plain"
verify_certificates: false
smartcard_auth: optional
active_directory: true
allow_username_or_email_login: false
block_auto_created_users: false
base: 'redacted'
attributes:
username:'sAMAccountName'
name: 'cn'
first_name:'givinName'
last_name: 'sn'
group_base:'redacted'
admin_group: 'admins'
EOS
### Smartcard authentication settings
gitlab_rails['smartcard_enabled'] = true
gitlab_rails['smartcard_ca_file'] = "/etc/gitlab/trusted-certs/redactedcert.pem"
gitlab_rails['smartcard_client_certificate_required_port'] = 3444
The certs were correctly added to the /etc/gitlab/trusted-certs
dir. Once reconfigured, logging in throws an error.
What is the current bug behavior?
On login, the following error is thrown in the production_json.log
:
"exception.class":"NoMethodError","exception.message":"undefined method `dn' for nil:NilClass","exception.backtrace":["ee/lib/gitlab/auth/smartcard/ldap_certificate.rb:20:in `find_user'","ee/lib/gitlab/auth/smartcard/base.rb:36:in `find_or_create_user'","ee/app/controllers/smartcard_controller.rb:58:in `sign_in_with'","ee/app/controllers/smartcard_controller.rb:23:in `verify_certificate'","ee/lib/gitlab/ip_address_state.rb:10:in `with'","ee/app/controllers/ee/application_controller.rb:44:in `set_current_ip_address'","app/controllers/application_controller.rb:486:in `set_current_admin'","lib/gitlab/session.rb:11:in `with_session'","app/controllers/application_controller.rb:477:in `set_session_storage'","lib/gitlab/i18n.rb:73:in `with_locale'","lib/gitlab/i18n.rb:79:in `with_user_locale'","app/controllers/application_controller.rb:471:in `set_locale'","app/controllers/application_controller.rb:464:in `block in set_current_context'","lib/gitlab/application_context.rb:63:in `block in use'","lib/gitlab/application_context.rb:63:in `use'","lib/gitlab/application_context.rb:24:in `with_context'","app/controllers/application_controller.rb:455:in `set_current_context'","lib/gitlab/metrics/elasticsearch_rack_middleware.rb:16:in `call'","lib/gitlab/middleware/rails_queue_duration.rb:33:in `call'","lib/gitlab/metrics/rack_middleware.rb:16:in `block in call'","lib/gitlab/metrics/transaction.rb:56:in `run'","lib/gitlab/metrics/rack_middleware.rb:16:in `call'","lib/gitlab/request_profiler/middleware.rb:17:in `call'","lib/gitlab/jira/middleware.rb:19:in `call'","lib/gitlab/middleware/go.rb:20:in `call'","lib/gitlab/etag_caching/middleware.rb:21:in `call'","lib/gitlab/middleware/multipart.rb:172:in `call'","lib/gitlab/middleware/read_only/controller.rb:50:in `call'","lib/gitlab/middleware/read_only.rb:18:in `call'","lib/gitlab/middleware/same_site_cookies.rb:27:in `call'","lib/gitlab/middleware/handle_malformed_strings.rb:21:in `call'","lib/gitlab/middleware/basic_health_check.rb:25:in `call'","lib/gitlab/middleware/handle_ip_spoof_attack_error.rb:25:in `call'","lib/gitlab/middleware/request_context.rb:21:in `call'","config/initializers/fix_local_cache_middleware.rb:11:in `call'","lib/gitlab/metrics/requests_rack_middleware.rb:76:in `call'","lib/gitlab/middleware/release_env.rb:12:in
Here's the line it's failing on, where the ldap_user
method is failing to get defined because find_by_certificate_issuer_and_serial
doesn't produce a ldap user.
def ldap_user
@ldap_user ||= ::Gitlab::Auth::Ldap::Person.find_by_certificate_issuer_and_serial(
@certificate.issuer.to_s(OpenSSL::X509::Name::RFC2253),
@certificate.serial.to_s,
adapter)
end
At this point we're not sure if this is because of a configuration issue or something else.
It looks like Active Directory doesn't support the certificateExactMatch
matching rule, which is a requirement for using the Smartcard, but this is difficult to either confirm or refute. I asked the customer to use ldapsearch
to search for a user's userCertificate
using this matching rule, with "(userCertificate:2.5.13.34:=SAMPLE_USER_CERT_VALUE)"
, and that returned 0 entries. However, I'm not positive I asked him to run it correctly. Here's the format:
# Format of command ran
ldapsearch -D "cn=admin,dc=ldap-testing,dc=example,dc=com" \
-w Password1 \
-p 389 \
-h 127.0.0.1 \
-b "dc=ldap-testing,dc=example,dc=com" \
"(userCertificate:2.5.13.34:=SAMPLE_USER_CERT_VALUE)"
What is the expected correct behavior?
Smartcard authentication against Active Directory should just work.