Introduction and Background
Microsoft has been pushing companies to adopt settings to require signing and Channel binding for LDAP. If you are looking at this post, you already knew that. Signing and encryption typically mean people using port 636 (LDAPS or LDAP over TLS). Signing can also work on port 389 using STARTTLS.
Once the the change is implemented for Requiring LDAP Integrity, Simple/Non-Secure Binds would start to fail. Secure Binds on port 389/3268 will work and Binds using LDAPS (636/3269) will work.
Here is the Microsoft Article on the configuration change
The mapping between LDAP Signing Policy settings and registry settings are included as follows:
- Policy Setting: “Domain controller: LDAP server signing requirements”
- Registry Setting: LDAPServerIntegrity
- DataType: DWORD
- Registry Path: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters
Group Policy Setting | Registry Setting |
None | 1 |
Require Signing | 2 |
The mapping between LDAP Channel Binding Policy settings and registry settings are included as follows:
- Policy Setting: “Domain controller: LDAP server channel binding token requirements”
- Registry Setting: LdapEnforceChannelBinding
- DataType: DWORD
- Registry Path: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters
Group Policy Setting | Registry Setting |
Never | 0 |
When Supported | 1 |
Always | 2 |
Now the problem
A lot of organizations use Load Balancer VIPs to prevent users from connecting directly to individual Domain Controllers over LDAP using technologies like F5 LTM or Citrix Netscaler ADC.
With new changes for LDAP Channel binding, which is meant to prevent MiTM (Man-in-the-Middle) or Relay attacks, the load balancer may be seen as a Man-In-The-Middle and hence LDAP binds will fail for applications that support Channel Binding when Channel Binding is configured to “When Supported”. If it is set to always be required, all connections through a Load Balanced VIP will fail.
The only workaround I have found so far is to either have then talk to the Domain Controllers directly on port 636 OR to to disable Channel Binding on the Domain Controllers that are behind your LB VIP. The LDAP signing requirement works fine through a Load Balancer as long as there is a valid certificate with the correct SANs present.
Here is a sample Error you would get using LDP.exe when you try to connect to a Domain Controller using a simple bind on port 389. This is good since hopefully everything that you care about has been converted to use secure binds within your organizations (don’t want to minimize it, took months of effort).
———–
res = ldap_simple_bind_s(ld, ‘MYDOMAIN\myldapuser’, <unavailable>); // v.3
Error <8>: ldap_simple_bind_s() failed: Strong Authentication Required
Server error: 00002028: LdapErr: DSID-0C090276, comment: The server requires binds to turn on integrity checking if SSL\TLS are not already active on the connection, data 0, v2580
Error 0x2028 A more secure authentication method is required for this server.
———–
If you are connecting through some kind of reverse proxy or Load Balancer, this is the error you would get from ldp.exe (because the channel binding token will not match between client and DC)
53 = ldap_set_option(ld, LDAP_OPT_ENCRYPT, 1)
res = ldap_bind_s(ld, NULL, &NtAuthIdentity, NEGOTIATE (1158)); // v.3
{NtAuthIdentity: User=’myldapuser’; Pwd=<unavailable>; domain = ‘MYDOMAIN’}
Error <49>: ldap_bind_s() failed: Invalid Credentials.
Server error: 80090346: LdapErr: DSID-0C090590, comment: AcceptSecurityContext error, data 80090346, v2580
Error 0x80090346 Client’s supplied SSPI channel bindings were incorrect.
Additional Reading
RFC 5056 https://tools.ietf.org/html/rfc5056
From https://www.hub.trimarcsecurity.com/post/ldap-channel-binding-and-signing
“LDAP channel binding is the act of tying the TLS tunnel and the application layer (leveraged by LDAP) together to create a unique identifier (channel binding token) for that specific LDAP session. This channel binding token (CBT) can only be used within that TLS tunnel and therefore prevents a “stolen” LDAP ticket from being leveraged elsewhere.”
RFC 2743 https://tools.ietf.org/html/rfc2743
1.1.6: Channel Bindings The GSS-API accommodates the concept of caller-provided channel binding ("chan_binding") information. Channel bindings are used to strengthen the quality with which peer entity authentication is provided during context establishment, by limiting the scope within which an intercepted context establishment token can be reused by an attacker. Specifically, they enable GSS-API callers to bind the establishment of a security context to relevant characteristics (e.g., addresses, transformed representations of encryption keys) of the underlying communications channel, of protection mechanisms applied to that communications channel, and to application-specific data. The caller initiating a security context must determine the appropriate channel binding values to provide as input to the GSS_Init_sec_context() call, and consistent values must be provided to GSS_Accept_sec_context() by the context's target, in order for both peers' GSS-API mechanisms to validate that received tokens possess correct channel-related characteristics. Use or non-use of the GSS-API channel binding facility is a caller option. GSS-API mechanisms can operate in an environment where NULL channel bindings are presented; mechanism implementors are encouraged, but not Linn Standards Track [Page 16]
RFC 2743 GSS-API January 2000 required, to make use of caller-provided channel binding data within their mechanisms. Callers should not assume that underlying mechanisms provide confidentiality protection for channel binding information. When non-NULL channel bindings are provided by callers, certain mechanisms can offer enhanced security value by interpreting the bindings' content (rather than simply representing those bindings, or integrity check values computed on them, within tokens) and will therefore depend on presentation of specific data in a defined format. To this end, agreements among mechanism implementors are defining conventional interpretations for the contents of channel binding arguments, including address specifiers (with content dependent on communications protocol environment) for context initiators and acceptors. (These conventions are being incorporated in GSS-API mechanism specifications and into the GSS-API C language bindings specification.) In order for GSS-API callers to be portable across multiple mechanisms and achieve the full security functionality which each mechanism can provide, it is strongly recommended that GSS-API callers provide channel bindings consistent with these conventions and those of the networking environment in which they operate.