UPDATE: I realized today that I wrote this same topic twice, in two different posts. This one should be considered the combined effort, but may read a bit like a blog Frankenstein. Original of the other one remains up here:
This post is part 5 of the new LDAP series I’ve started to help people become more aware of what LDAP is and how it works.
Part one was posted here:
This post will focus on LDAP servers and clients.
Servers vs clients
The LDAP client/server relationship is also symbiotic. The server needs the client to ask it questions and the client needs the server to feed it information.
If nature isn’t your thing, there’s always the Spider-Man/Venom symbiotic relationship:
In the case of LDAP, a client will be asking for things like usernames, home directory locations, group memberships, etc. The server would be responsible for delivering that information.
LDAP isn’t unlike other protocols, such as HTTP, NFS, etc. There is a client and server relationship. And just like any successful relationship, there needs to be someone talking and someone listening.
I have a two year old son. He talks, but most of it is just practice for him. He’ll say things like “dada, bird truck.” And I’ll say “Bird? Truck? Cool!” It’s mostly a one-sided conversation where I essentially ACK his SYNs. (I need to get out more)
Sometimes, it’s “dada read book.” And I comply.
LDAP client/server conversations aren’t much different. The client is my two year old. The LDAP server is me.
“LDAP, find user information”
“User information? Cool! Here ya go!”
At its very base, LDAP conversations are nothing more than TCP SYNs and ACKs. So, when configuring or troubleshooting, they should be treated as such.
Where things get muddled is when you start to consider what it takes for a client/server relationship to be successful. It’s not a good idea to leave the channels of communication wide open for everyone in the world to see, so there are some rules we have to follow when clients want to talk to servers.
LDAP clients can be anything running software that can query LDAP via RFC-2307 standards. Windows, Linux, storage system OSes, etc can all act as clients. Some operating systems contain built-in LDAP functionality (such as Windows) that doesn’t require you to install anything special. Some storage systems, such as NetApp’s clustered Data ONTAP, fully support LDAP that adheres to the RFC-2307 standard. For more information, see TR-4073: Secure Unified Authentication.
Basic network information.
Remember, at its base, it’s a simple TCP conversation.
- LDAP server names, URI or IP addresses (is the server in DNS? Are there SRV records for LDAP?)
- LDAP port (default ports are 389 for LDAP, 636 for LDAP over SSL, 3268 for Global Catalog; did you change the server port?)
- Can the client talk to the server (routing?)
Before a client can initiate a conversation with a server, it has to be configured with information about that server. The configuration will follow the basics of the OSI model, starting at the first few layers of the stack to initiate a TCP conversation with the server.
Common LDAP clients
LDAP clients also tend to adhere to the same standards as the servers. Why? Because it makes sense. Clients can stand alone from an operating system, but some OSes integrate LDAP into their configuration by default. Windows is an example of this because of how integral LDAP is to Active Directory.
Other clients include (but are certainly not limited to):
Hopefully the information in this post has helped clear up any confusion on LDAP clients and servers.
Some LDAP servers will even allow you to make modifications to the port it listens on for LDAP communication. This is to help secure LDAP servers by not leveraging well known ports. With common LDAP servers such as Active Directory, however, it’s difficult to use different ports from the common ones. When configuring the clients, the LDAP server configuration always needs to be reviewed.
After we get past the TCP connection, we spend our time in the application layer of the OSI model.
First we have to worry about authenticating to the LDAP server. This is also known as binding. The level of authentication will depend on what the server has been set to allow. The lowest possible authentication level is “anonymous,” but no modern LDAP server allows anonymous binds by default. Generally, a read-only account on the LDAP server is required to authenticate to a server to issue LDAP queries.
The necessary bind information is included in the client configuration. For the most secure configuration, using a ticket or key based authentication system is preferred over using passwords.
LDAP Search Information
After a bind takes place, the queries are performed. The nature of the queries will depend on the client configuration. What schema are we using? What information do we need? Have we configured the client to make sure to try LDAP for information at all times (via nsswitch.conf configuration)? Did we tell the client where to start looking for information on the LDAP server by providing the base DN?
This tells the client where to start looking for information in the LDAP server.The format for this information is Distinguished Names (DNs), which I cover in part 4. You can set a base DN and then specific DNs for users, groups, netgroups, etc. You can even specify multiple locations to search. The idea here is to filter our searches to speed things up for the clients.
Fun fact: Apple auto-corrects DNs to DNS. Not cool, Apple. Not cool.
Once the LDAP client has the necessary information, it should unbind – we don’t want to stay logged in indefinitely. That’s a resource hog.
LDAP schema information
I cover schemas in detail on part 3. Many clients know about the default schemas LDAP uses, such as RFC-2307, RFC-2307bis, etc. In most cases, the schemas on the server will not stray from that. But in some instances, such as through manual intervention or 3rd party tools like Dell Vintela (also known as Centrify, Quest, etc), there may be need to make adjustments. This can be done on the client. This allows the client to ask for the right information from the server, which then allows the server to find the information and respond to the client.
Many clients offer specific options like caching of users/groups, credentials, Kerberos configuration, etc. These are generally optional, but should be looked into on a per-client vendor basis.
Sample client configuration
The following is an example of what a clustered Data ONTAP LDAP client would look like:
cluster::*> ldap client show -client-config DOMAIN Vserver: NAS Client Configuration Name: DOMAIN LDAP Server List: 10.228.225.120 Active Directory Domain: domain.win2k8.netapp.com Preferred Active Directory Servers: - Bind Using the Vserver's CIFS Credentials: false Schema Template: WinMap LDAP Server Port: 389 Query Timeout (sec): 3 Minimum Bind Authentication Level: sasl Bind DN (User): ldapuser Base DN: dc=domain,dc=win2k8,dc=netapp,dc=com Base Search Scope: subtree User DN: cn=users,dc=domain,dc=win2k8,dc=netapp,dc=com User Search Scope: subtree Group DN: cn=users,dc=domain,dc=win2k8,dc=netapp,dc=com Group Search Scope: subtree Netgroup DN: - Netgroup Search Scope: subtree Vserver Owns Configuration: true Use start-tls Over LDAP Connections: false Allow SSL for the TLS Handshake Protocol: - Enable Netgroup-By-Host Lookup: true Netgroup-By-Host DN: - Netgroup-By-Host Scope: subtree
This is what my client configuration running SSSD looks like:
# cat /etc/sssd/sssd.conf [domain/default] cache_credentials = True case_sensitive = False [sssd] config_file_version = 2 services = nss, pam domains = DOMAIN debug_level = 7 [nss] filter_users = root,ldap,named,avahi,haldaemon,dbus,radiusd,news,nscd filter_groups = root [pam] [domain/DOMAIN] id_provider = ldap auth_provider = krb5 case_sensitive = false chpass_provider = krb5 cache_credentials = false ldap_uri = _srv_,ldap://domain.win2k8.netapp.com ldap_search_base = dc=domain,dc=win2k8,dc=netapp,dc=com ldap_schema = rfc2307 ldap_sasl_mech = GSSAPI ldap_user_object_class = user ldap_group_object_class = group ldap_user_home_directory = unixHomeDirectory ldap_user_principal = userPrincipalName ldap_group_member = memberUid ldap_group_name = cn ldap_account_expire_policy = ad ldap_force_upper_case_realm = true ldap_user_search_base = cn=Users,dc=domain,dc=win2k8,dc=netapp,dc=com ldap_group_search_base = cn=Users,dc=domain,dc=win2k8,dc=netapp,dc=com ldap_sasl_authid = root/centos64.domain.win2k8.netapp.com@DOMAIN.WIN2K8.NETAPP.COM krb5_server = domain.win2k8.netapp.com krb5_realm = DOMAIN.WIN2K8.NETAPP.COM krb5_kpasswd = domain.win2k8.netapp.com
If you want somewhere for the clients to ask for information, you need a server. The server needs to have a valid RFC-2307 schema to contain the necessary LDAP objects. If you’re doing UNIX-based LDAP and want to use Microsoft Active Directory to serve UNIX-based authentication, then you’d need to ensure the server has UNIX attributes in the schema. While Microsoft Active Directory runs on a LDAP backend, it’s not true UNIX-based LDAP server until you extend the schema. I talk a bit about this in my blog post on IDMU.
As mentioned in the client section, you need a bunch of information to configure clients. The server is where this information comes from. Here’s the stuff you need to check on the server to ensure you configure your clients correctly:
- Server network info (IP address, hostname, DNS entries, SRV records, LDAP server ports, etc.)
- Supported bind level (use the strongest available, if possible)
- Valid bind user or SPN
- DN information
- Schema type/attributes
LDAP servers can host tons of information. UNIX user creds, Windows creds, netgroups, IP addresses, SPNs, name mapping rules…. It just depends on what the clients support that determines what you can use.
Common LDAP servers
LDAP servers all tend to adhere to a common set of standards as defined by IETF. This is to ensure a wide range of support for clients. Some of the more common LDAP servers include (but are not limited to):
- Active Directory
- RedHat Directory Server/389 Directory Server
- Apple Open Directory
- Oracle Internet Directory
If you are using multiple LDAP servers and a client is not able to find an object in the specified LDAP server’s domain, it may attempt to use an LDAP referral to look in the other servers. Essentially, it takes information in the LDAP server about other servers we know about and attempts to connect to them via LDAP URI until it either a) finds the object or b) runs out of servers to try. This can happen in both Windows and non-Windows LDAP servers. Some LDAP clients do not support “referral chasing,” so it’s important to know if this is happening in your environment and if your client is able to chase referrals.
Global Catalog Searches
In Active Directory, it is possible to store a copy of attributes from multiple domains in a forest on local domain controllers acting as Global Catalog servers. By default, UNIX attributes don’t get replicated to the Global Catalog, but you can change that behavior as needed. I cover how to do this in TR-4073. If you need to query multiple domains in the same forest and want to avoid LDAP referrals, you can simply replicate the necessary attributes and change the LDAP port to 3268 to let the servers know to use the Global Catalog instead!
In my environment, I use Active Directory LDAP with Identity Management. But I’ve been known to use OpenLDAP and RedHat Directory Services. Both are perfectly valid to use. However, if you’re intent on doing multiprotocol NAS (CIFS/SMB and NFS), I strongly suggest using Microsoft Active Directory for authentication for UNIX and Windows users. Makes life infinitely easier.
If you are already using Linux-based LDAP, that’s fine. If possible, try to ensure the UNIX user names (uid LDAP attribute) match the Windows user names (sAMAccount attribute). That way, if you are using multiprotocol NAS, you don’t have to worry about name mapping.
If you want to see anything added to this post regarding LDAP servers and clients, feel free to comment or follow me on Twitter @NFSDudeAbides!
For more detailed information on LDAP configuration (particularly with NetApp clustered Data ONTAP), see TR-4073: Secure Unified Authentication.
Also, stay tuned for more in the series of LDAP basics on this blog!
Links to other sections can be found on the first post in this series: