Part 4 of the secure LDAP series covering Kerberos SASL and passwordless binds
|

Why Send a Password You Can’t Take Back? (Part 4 of 6)

Part 4 of 6 ยท Moving Past LDAP Simple Bind

Found this one on its own? That’s fine – it holds up by itself. The thread running through the series is simple: securing LDAP is three jobs, not one – the connection, the login, and the account. This part is the login, and it’s the one I’d argue matters most.

So far this series has protected a password as it travels – Part 3 wrapped it in a TLS tunnel. But that still leaves the framing’s second job open. As Part 1 put it, the three jobs are data in transit (A), authentication (B), and the account (C), and a sealed tunnel around a reusable password is still a reusable password. This article is about Concern B, and it asks the better question: why send a password at all?

๐—ง๐—ต๐—ฒ ๐—ฏ๐—ถ๐—ป๐—ฑ ๐˜๐—ต๐—ฎ๐˜ ๐—ฑ๐—ผ๐—ฒ๐˜€๐—ป’๐˜ ๐˜€๐—ฒ๐—ป๐—ฑ ๐—ฎ ๐—ฝ๐—ฎ๐˜€๐˜€๐˜„๐—ผ๐—ฟ๐—ฑ

LDAP offers two ways to log in: the simple bind (just a password) and SASL (Simple Authentication and Security Layer). SASL is not a login method itself; it is a standard slot that lets LDAP plug in a stronger method in place of a raw password. You choose what plugs in. The strongest common choice is Kerberos, the ticket-based system Windows already uses (with Active Directory) to log you in each day: a trusted authority issues a short-lived ticket that proves who you are without ever sending your password.

So a SASL bind using Kerberos means logging in to LDAP with one of those tickets instead of a password. A password handed over in a simple bind is reusable; a Kerberos ticket obtained through SASL is not. Nothing worth stealing crosses the network.

a ticket instead of a password - nothing worth stealing crosses the network

a ticket instead of a password – nothing worth stealing crosses the network

When you (or a service account) sign in, the Windows system quietly issues you a ticket (like a wristband) from a trusted gatekeeper (the KDC). After that, apps show the wristband instead of typing a password. The server checks it with the gatekeeper and lets you in. No password ever travels, so there is nothing on the wire to steal.

๐—” ๐—พ๐˜‚๐—ถ๐—ฐ๐—ธ ๐—ป๐—ผ๐˜๐—ฒ ๐—ผ๐—ป ๐˜๐—ต๐—ฒ ๐—ฎ๐—ฐ๐—ฟ๐—ผ๐—ป๐˜†๐—บ๐˜€, because they pile up: SASL is the slot. GSSAPI (Generic Security Services API) is the piece that plugs into the slot and carries Kerberos. So “SASL with GSSAPI” simply means: log in with a Kerberos ticket.

๐—›๐—ผ๐˜„ ๐˜๐—ผ ๐—ถ๐—บ๐—ฝ๐—น๐—ฒ๐—บ๐—ฒ๐—ป๐˜, ๐—ฏ๐—ฟ๐—ถ๐—ฒ๐—ณ๐—น๐˜†:

  • Ensure DNS and time sync are healthy (Kerberos is time-sensitive) and the LDAP SPN is registered on the DC (it is by default).

  • Configure the client or app to use Negotiate or GSSAPI/Kerberos as its bind type, instead of Basic/Simple.

  • Run the service under a domain account or (better) a gMSA so it can obtain tickets. (That leads straight into Part 5.)

  • A .NET Kerberos sign-and-seal bind, with no password on the wire:

$c = New-Object
System.DirectoryServices.Protocols.LdapConnection('dc01.corp.local')
$c.AuthType = 'Negotiate' # GSSAPI / Kerberos
$c.SessionOptions.Signing = $true
$c.SessionOptions.Sealing = $true # encrypt via Kerberos
$c.Bind() # uses current Kerberos identity

The OpenLDAP equivalent: ldapsearch -Y GSSAPI -H ldap://dc01.corp.local

For domain-joined clients and modern libraries, this is the preferred mechanism. It is the most worthwhile fix in the series if a client can support it.

the wristband from a trusted gatekeeper

the wristband from a trusted gatekeeper

๐—–๐—ต๐—ฎ๐—ป๐—ป๐—ฒ๐—น ๐—ฏ๐—ถ๐—ป๐—ฑ๐—ถ๐—ป๐—ด – ๐—บ๐—ฎ๐—ธ๐—ถ๐—ป๐—ด ๐—ฎ ๐—ฐ๐—ฎ๐—ฝ๐˜๐˜‚๐—ฟ๐—ฒ๐—ฑ ๐—น๐—ผ๐—ด๐—ถ๐—ป ๐˜‚๐—ป-๐—ฟ๐—ฒ๐˜‚๐˜€๐—ฎ๐—ฏ๐—น๐—ฒ

There is a second, separate piece inside Concern B, and people constantly confuse the two. Keep them apart:

  1. ๐—ง๐—ต๐—ฒ ๐—ฏ๐—ถ๐—ป๐—ฑ ๐—บ๐—ฒ๐˜๐—ต๐—ผ๐—ฑ – ๐—ต๐—ผ๐˜„ ๐—ถ๐—ฑ๐—ฒ๐—ป๐˜๐—ถ๐˜๐˜† ๐—ถ๐˜€ ๐—ฝ๐—ฟ๐—ผ๐˜ƒ๐—ฒ๐—ป. A SASL/Kerberos bind replaces the password with a time-limited ticket. This is the part that actually authenticates the connection.

  2. ๐—–๐—ต๐—ฎ๐—ป๐—ป๐—ฒ๐—น ๐—ฏ๐—ถ๐—ป๐—ฑ๐—ถ๐—ป๐—ด – ๐—ฝ๐—ฟ๐—ผ๐˜๐—ฒ๐—ฐ๐˜๐—ถ๐—ป๐—ด ๐˜๐—ต๐—ฎ๐˜ ๐—ฝ๐—ฟ๐—ผ๐—ผ๐—ณ ๐—ถ๐—ป ๐˜๐—ฟ๐—ฎ๐—ป๐˜€๐—ถ๐˜. A separate add-on that ties a login to the exact TLS connection it was made on, so a captured login cannot be replayed on a different connection. It is not an authentication method in its own right – it is not part of Kerberos and proves nobody’s identity by itself. It simply stops a valid login from being reused elsewhere.

Put simply: the SASL/Kerberos bind decides how you log in; channel binding makes sure that login can only be used where it was created. Both belong to authentication, and you want both.

Alongside channel binding sits signing, which adds a tamper-evident seal – integrity. Signing proves a message was not altered in transit; break the seal and the server says no. Channel binding is like a ticket stamped “valid only on this train, today” – copy it onto another train and it simply will not scan. That is why relayed logins fail.

valid only where created - a relayed copy is rejected

valid only where created – a relayed copy is rejected

๐—›๐—ผ๐˜„ ๐˜๐—ผ ๐—ฐ๐—ผ๐—ป๐—ณ๐—ถ๐—ด๐˜‚๐—ฟ๐—ฒ (๐—š๐—ฟ๐—ผ๐˜‚๐—ฝ ๐—ฃ๐—ผ๐—น๐—ถ๐—ฐ๐˜†):

  • LDAP signing: on 2025 DCs, leave Domain controller: LDAP server signing requirements at None and set the new …signing requirements enforcement to Enabled (enforcement wins when both are set).

  • Channel binding: set Domain controller: LDAP server channel binding token requirements to “When supported” during transition, then “Always” once clients are ready.

  • Client side: set Network security: LDAP client signing requirements to “Require signing” so domain clients never negotiate down.

  • Stage with auditing first – events 2887/2889 for signing, and 3074/3075 for channel binding – before flipping to enforce, one setting at a time.

The classic registry equivalents on a pre-2025 DC (on 2025, use the Enforcement policy instead of LDAPServerIntegrity):

– reg add “HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters” /v LDAPServerIntegrity /t REG_DWORD /d 2 /f – (2 = Require)

– reg add “HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters” /v LdapEnforceChannelBinding /t REG_DWORD /d 1 /f (1 = When supported, 2 = Always)

๐—ช๐—ต๐—ฎ๐˜ ๐˜๐—ต๐—ถ๐˜€ ๐˜€๐˜๐—ถ๐—น๐—น ๐—ฑ๐—ผ๐—ฒ๐˜€ ๐—ป๐—ผ๐˜ ๐—ฐ๐—ผ๐˜ƒ๐—ฒ๐—ฟ

Proving identity safely does not, by itself, hide bulk directory data – you still want TLS or sealing for confidentiality. And it says nothing about what the account may do once it is in (that is authorization, out of scope), nor about the service account shared across ten systems carrying far more rights than it needs. That is Concern C – and it is Part 5.

These layers are strongest combined: run a Kerberos/SASL bind with channel binding inside an LDAPS or StartTLS tunnel and you get both halves at once. TLS protects the trip; Kerberos protects the identity. The tunnel even gives channel binding the TLS session it needs to bind to, so the two reinforce each other.

๐—ง๐—ต๐—ถ๐˜€ ๐—ถ๐˜€ ๐—ฃ๐—ฎ๐—ฟ๐˜ ๐Ÿฐ ๐—ผ๐—ณ ๐—ฎ ๐Ÿฒ-๐—ฝ๐—ฎ๐—ฟ๐˜ ๐˜€๐—ฒ๐—ฟ๐—ถ๐—ฒ๐˜€.

Previously – Part 3: Is Your “Encrypted” LDAP Actually Protected?

Next – Part 5: When Did That Service Account Last Rotate? Kerberos proves identity beautifully – but it says nothing about a shared, over-privileged service account whose password hasn’t changed in years. We tackle Concern C: gMSA, dMSA, and least privilege.

Full series:

Question – How many of your apps still use Basic/Simple bind purely because nobody ever switched them to Negotiate?

If even one app in your environment is still doing Basic/Simple bind out of habit, repost this for whoever owns it – the switch to Negotiate is often a one-line change. Follow for Part 5, the service account nobody wants to talk about.

Genuinely curious in the comments: what’s the one app in your shop still sending a password it doesn’t need to? Repost if “why send a password at all?” reframed it for you.

Replace LDAP Password Binds with Kerberos supporting illustration

๐—ฅ๐—ฒ๐—ณ๐—ฒ๐—ฟ๐—ฒ๐—ป๐—ฐ๐—ฒ๐˜€:

๐—š๐—น๐—ผ๐˜€๐˜€๐—ฎ๐—ฟ๐˜†

  • Simple bind: an LDAP login that sends an account name and password directly; the reusable secret this part replaces.

  • SASL: Simple Authentication and Security Layer; a standard “slot” in LDAP that lets a stronger login method plug in place of a password.

  • GSSAPI: Generic Security Services API; the component that plugs into SASL and carries Kerberos. “SASL with GSSAPI” means logging in with a Kerberos ticket

  • Kerberos: a ticket-based authentication system; identity is proven with a ticket from a trusted authority, so no password crosses the network.

  • KDC: Key Distribution Center; the trusted authority (on the DC) that issues Kerberos tickets.

  • SPN: Service Principal Name; the unique name Kerberos uses to identify a service, such as ldap/dc01.corp.local.

  • Negotiate: the Windows bind type that selects Kerberos (falling back to NTLM); set it instead of Basic/Simple.

  • Signing: an integrity control that signs LDAP messages so tampering in transit is detected and rejected.

  • Sealing: encrypting the LDAP message contents (confidentiality), as opposed to only signing them (integrity).

  • Channel binding (CBT): a token that ties a login to the specific TLS session it was made in, so a captured login cannot be replayed elsewhere.

  • gMSA: Group Managed Service Account; a managed identity a service can run under to obtain tickets (covered in Part 5).

  • TLS / LDAPS / StartTLS: the transit encryption (Part 3) that channel binding ties to; strongest when paired with this bind.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *