Every time a firewall, a printer or a line-of-business app asks "is this person allowed in", it usually asks a directory. The directory answers over a protocol that has been doing the same job since the 1990s, and it is still in every network you manage. This post explains what LDAP is, how a lookup and a bind work, and where LDAP ends and Active Directory begins.
What LDAP Is
LDAP stands for Lightweight Directory Access Protocol. It is a way for a client to read and write entries in a directory over a network. The current version, LDAPv3, is defined in RFC 4511, published in June 2006.
The word to hold onto is protocol. LDAP is not a database and not a product. It is the language a client speaks to a directory server, the same way HTTP is the language a browser speaks to a web server. The "lightweight" part is historical: it replaced the heavier X.500 Directory Access Protocol, and kept the X.500 idea of a tree of entries.
A directory holds entries. Each entry has a distinguished name (DN), which is its address in the tree, and a set of attributes. A user in a company directory looks like this:
codedn: CN=Jane Doe,OU=Finance,DC=corp,DC=example objectClass: user sAMAccountName: jdoe mail: jane.doe@example.com memberOf: CN=Finance-Users,OU=Groups,DC=corp,DC=example
Read the DN from right to left: the domain, then the organizational unit, then the person. That tree is what LDAP was built to search, and it is why a directory is fast at "who is this" and slow at "sum every invoice".
How a Lookup Works
An LDAP session has four moves: connect, bind, search, unbind. The bind is the one that matters for security, so it gets its own paragraph.
RFC 4511 defines the bind as the step that lets "authentication information to be exchanged between the client and server". There are three kinds. An anonymous bind sends no name. A simple bind sends a DN and a password. A SASL bind hands the job to another mechanism, which on a Windows network means Kerberos or NTLM through Negotiate.
Here is the catch with simple binds. The RFC says a textual password "SHALL be transferred as UTF-8 encoded Unicode". That is the password in the clear on the wire unless the connection is wrapped in TLS. Plenty of appliances still default to a simple bind on port 389, which is why the hardening section below exists.
After the bind comes the search. A search request carries four things: a base object (where in the tree to start), a scope (that entry only, one level down, or the whole subtree), a filter, and the attributes you want back. A filter that finds one user reads like this:
code(&(objectClass=user)(sAMAccountName=jdoe))
The server returns matching entries, the client reads the attributes it asked for, and then it unbinds. A VPN appliance checking group membership does this whole cycle in a few milliseconds, thousands of times a day.
If you want the vocabulary for what happens after the lookup, our post on role-based access control picks up where the memberOf attribute leaves off.
Ports, LDAPS and What Secure Means
Microsoft's firewall guidance for domain controllers lists four LDAP ports. 389 TCP and UDP is plain LDAP. 636 TCP is LDAP over SSL/TLS, usually called LDAPS. 3268 and 3269 are the same pair for the global catalog, the forest-wide index that answers cross-domain lookups.
Three separate controls get lumped together as "secure LDAP", and they do different jobs.
LDAPS encrypts the session. The domain controller needs a certificate, the client needs to trust the issuer, and the password in a simple bind travels inside TLS instead of in the clear.
LDAP signing protects integrity. Microsoft's LDAP signing guidance explains the risk it closes: unsigned traffic "is susceptible to replay attacks" and to man-in-the-middle attacks where "an intruder captures packets between the client and the server, changes the packets, and then forwards them". Signing applies to SASL binds on port 389. It does not encrypt anything.
Channel binding ties the authentication inside a TLS session to that specific session. Without it, an attacker who can relay a client's authentication into their own LDAPS connection gets a valid session. With it, the relayed credential fails because the channel token does not match.
The r/sysadmin thread below asked the question directly, whether LDAPS alone is enough without channel binding. The most upvoted serious reply said to enable both, and one commenter pointed to authentication relay as the case that needs the pair.
One more date worth knowing. Microsoft's March 10, 2020 update added the channel binding policy and the audit events, but Microsoft stated that the updates "will not change LDAP signing or LDAP channel binding default policies" on new or existing domain controllers. Enforcement is still your decision, and the defaults are still permissive.
LDAP vs Active Directory
This is the comparison people search for, and it is a category error. LDAP is a protocol. Active Directory is a product that, among other things, speaks it.
Microsoft's own overview of AD DS lists what the directory service includes: a schema that defines object classes and attributes, a global catalog, a query and index mechanism, and a replication service that copies changes to every domain controller in the domain. None of that is LDAP. LDAP is how a client reaches the data store those pieces maintain.
Active Directory also does things LDAP has no opinion about. It authenticates Windows sign-ins with Kerberos, hands out Group Policy, runs its own DNS integration and manages trusts between domains. When a workstation says the trust relationship with the domain failed, that is a Kerberos and machine-account problem, and our guide to the trust relationship error covers it. LDAP is not involved.
The other direction matters too. LDAP servers exist without Active Directory: OpenLDAP, 389 Directory Server, FreeIPA and Samba running as a domain controller all speak the same protocol. A Linux-heavy shop can run a directory with no Windows server in it, and a Windows shop uses LDAP mostly without ever typing the word.
So when a vendor's setup page says "LDAP or Active Directory", it is offering a generic LDAP bind against any directory, or an AD-aware integration that also understands Kerberos, nested groups and the AD schema. Pick the second when the directory is AD. It handles the corner cases the generic path does not.
Where Microsoft Entra ID Fits
Microsoft Entra ID, the cloud directory behind Microsoft 365, does not speak LDAP. Applications talk to it over SAML, OpenID Connect and OAuth. That is the reason a legacy appliance cannot "point at Entra" for authentication the way it pointed at a domain controller.
Microsoft's LDAP authentication guidance for Entra names the supported pattern: Microsoft Entra Domain Services. It is a managed domain that syncs one way from Entra ID and exposes "LDAP, domain join, group policy, Kerberos, and NTLM authentication" to workloads on a virtual network. Secure LDAP is a separate configuration step with its own certificate.
The practical rule for a small IT team: if an app supports SAML or OIDC, use that against Entra ID. If it only supports LDAP, either keep an on-premises domain controller in scope, stand up Domain Services, or replace the app. The choice sits inside the wider question of which IAM tools the organization standardizes on. A full comparison of Entra ID and Active Directory is coming as its own post.
Hardening LDAP on a Domain Controller
Every Active Directory domain controller answers LDAP on 389 by default, with signing and channel binding set to permissive. Tightening that is a four-step job, and the order matters because step one tells you what step four will break.
- Read the Directory Service log. Event 2887 is logged once every 24 hours with a count of simple binds without TLS and SASL binds without signing. Event 2886 at service start is the reminder that the settings are still permissive.
- Find the clients. Raise the "16 LDAP Interface Events" diagnostic to 2 and the server logs Event 2889 per offending bind, with the client IP and the account it used. This is your inventory of appliances, scanners and scripts that need fixing.
- Fix the clients. Move simple binds to LDAPS on 636 or to a SASL bind, and repoint anything that hard-codes 389 with a password.
- Enforce. Set "Domain controller: LDAP server signing requirements" to Require signing and "Domain controller: LDAP server channel binding token requirements" to Always in the Default Domain Controllers Policy. Event 2888 then reports what got rejected.
The step that trips people is the middle one. In the thread below, an admin with "little to no LDAP integrations" asked whether enabling the two GPO settings was all there was to it. The top reply flagged load balancers that terminate TLS in front of domain controllers: to channel binding, a proxy that re-establishes the connection is indistinguishable from an attacker in the middle.
Across a fleet, the inventory step is a script job: pull Event 2889 from every domain controller and group by client IP. OpenFrame can run that script across a client's devices and collect each machine's output, so the list of offenders lands in one place instead of one Event Viewer at a time. Ship the events to your log management pipeline as well, because the 24-hour summaries are the cheapest proof you have that the cleanup held.
The Short Version
LDAP is the protocol a client uses to bind to a directory and search it. Active Directory is a directory service that speaks LDAP and a lot else. Port 389 is plain, 636 is TLS, and neither is safe by default until signing and channel binding are enforced, which Microsoft leaves to you. Read Event 2887 this week, fix the clients it counts, then enforce.
Next reads: our domain controller guide covers the servers that answer these lookups.
For the identity layer above the directory, start with IAM solutions.
FAQ
Is LDAP the same as Active Directory?
No. LDAP is a protocol for reading and writing directory entries, defined in RFC 4511. Active Directory is Microsoft's directory service. It speaks LDAP, and it also runs Kerberos authentication, Group Policy, DNS integration, a global catalog and replication, none of which are part of LDAP.
What port does LDAP use?
Port 389 TCP and UDP for plain LDAP, and 636 TCP for LDAP over SSL/TLS (LDAPS). Active Directory adds 3268 and 3269 for global catalog queries. Microsoft notes that 636 and 3269 only need to be open if clients use LDAP with SSL/TLS.
Is LDAP secure?
Not by default. A simple bind on port 389 sends the password as UTF-8 text on the wire. Securing it means three separate controls: LDAPS to encrypt the session, LDAP signing to verify integrity, and channel binding to stop relayed authentication inside TLS. Microsoft's 2020 updates added the policies but left the defaults permissive.
Does Microsoft Entra ID support LDAP?
Not directly. Entra ID uses SAML, OpenID Connect and OAuth. For apps that only speak LDAP, Microsoft's supported route is Microsoft Entra Domain Services, a managed domain synced from Entra ID that provides LDAP, secure LDAP, Kerberos and NTLM on a virtual network.
Content Marketing Lead
Ohayo! I run content, SEO, social, and community at Flamingo. Before IT, I worked as a correspondent for Ukraine's Public Broadcasting Company and have a Master's in journalism.
