Brand new tech report: Multiprotocol NAS Best Practices in ONTAP

I don’t like to admit to being a procrastinator, but…

Lazy Sloth Drawing (Page 1) - Line.17QQ.com
(Not actually a sloth)

Four years ago, I said this:

And people have asked about it a few times since then. To be fair, I did say “will be a ways out…”

In actuality, I started that TR in March of 2017. And then again in February of 2019. And then started all over when the pandemic hit, because what else did I have going on? 🙂

And it’s not like I haven’t done *stuff* in that time.

The trouble was, I do multiprotocol NAS every day, so I think I had writer’s block because I didn’t know where to start and the challenge of writing an entire TR on the subject without making it 100-200 pages like some of the others I’ve written was… daunting. But, it’s finally done. And the actual content is under 100 pages!

Topics include:

  • NFS and SMB best practices/tips
  • Name mapping explanations and best practices
  • Name service information
  • CIFS Symlink information
  • Advanced multiprotocol NAS concepts

Multiprotocol NAS Best Practices in ONTAP

If you have any comments/questions, feel free to comment!

Behind the Scenes: Episode 170 – Active IQ

Welcome to the Episode 170, part of the continuing series called “Behind the Scenes of the NetApp Tech ONTAP Podcast.”

tot-gopher

This week on the podcast,we talk NetApp Active IQ and how it can benefit storage administrators with guest co-host Dan Isaacs (@danisaacs), Active IQ TME Brett Albertson (bretta@netapp.com) and director of Solutions Engineering, Kim Weller (https://www.linkedin.com/in/wellerkim/)! 

Also, check out Active IQ blogs here: 

https://blog.netapp.com/how-to-use-netapp-active-iq-predictive-analytics-for-actionable-intelligence/ 

https://blog.netapp.com/how-we-use-the-netapp-data-fabric-to-innovate-with-active-iq/  

https://blog.netapp.com/intelligent-insights-with-active-iq-and-ai  

Finding the Podcast

You can find this week’s episode here:

Also, if you don’t like using iTunes or SoundCloud, we just added the podcast to Stitcher.

http://www.stitcher.com/podcast/tech-ontap-podcast?refid=stpr

I also recently got asked how to leverage RSS for the podcast. You can do that here:

http://feeds.soundcloud.com/users/soundcloud:users:164421460/sounds.rss

Our YouTube channel (episodes uploaded sporadically) is here:

NFS Kerberos in ONTAP Primer

Fun fact!

Kerberos was named after Cerberus, the hound of Hades, which protected the gates of the underworld with its three heads of gnashing teeth.

cerberos

Kerberos in IT security isn’t a whole lot different; it’s pretty effective at stopping intruders and is literally a three-headed monster.

In my day to day role as a Technical Marketing Engineer for NFS, I find that one of the most challenging questions I get is regarding NFS mounts using Kerberos. This is especially true now, as IT organizations are focusing more and more on securing their data and Kerberos is one way to do that. CIFS/SMB already does a nice job of this and it’s pretty easily integrated without having to do a ton on the client or storage side.

With NFS Kerberos, however, there are a ton of moving parts and not a ton of expertise that spans those moving parts. Think for a moment what all is involved here when dealing with ONTAP:

  • DNS
  • KDC server (Key Distribution Center)
  • Client/principal
  • NFS server/principal
  • ONTAP
  • NFS
  • LDAP/name services

This blog post isn’t designed to walk you through all those moving parts; that’s what TR-4073 was written for. Instead, this blog is going to simply walk through the workflow of what happens during an NFS mount using Kerberos and where things can fail/common failure scenarios. This post will focus on Active Directory KDCs, since that’s what I see most and get the most questions on. Other UNIX-based KDCs are either not as widely used, or the admins running them are ninjas that never need any help. 🙂

Common terms

First, let’s cover a few common terms used in NFS Kerberos.

Storage Virtual Machine (SVM)

This is what clustered ONTAP uses to present NAS and SAN storage to clients. SVMs act as tenants within a cluster. Think of them as “virtualized storage blades.”

Key Distribution Center (KDC)

The Kerberos ticket headquarters. This stores all the passwords, objects, etc. for running Kerberos in an environment. In Active Directory, domain controllers are KDCs and replicate to other DCs in the environment, which makes Active Directory an ideal platform to run Kerberos on due to ease of use and familiarity. As a bonus, Active Directory is already primed with UNIX attributes for Identity Management with LDAP. (Note: Windows 2012 has UNIX attributes by default; prior to 2012, you had to manually extend the schema.)

Kerberos principals

Kerberos principals are objects within a KDC that can have tickets assigned. Users can own principals. Machine accounts can own principals. However, simply creating a user or machine account doesn’t mean you have created a principal. Those are stored within the object’s LDAP schema attributes in Active Directory. Generally speaking, it’s one of either:

  • servicePrincipalName (SPN)
  • userPrincipalName (UPN)

These get set when adding computers to a domain (including joining Linux clients), as well as when creating new users (every user gets a UPN). Principals include three different components.

  1. Primary – this defines the type of principal (usually a service such as ldap, nfs, host, etc) and is followed by a “/”; Not all principals have primary components. For example, most users are simply user@REALM.COM.
  2. Secondary – this defines the name of the principal (such as jimbob)
  3. Realm – This is the Kerberos realm and is usually defined in ALL CAPS and is the name of the domain your principal was added into (such as CONTOSO.COM)

Keytabs

The keytab file allows a client or server that is participating in an NFS mount to use their keytab to generate AS (authentication service) ticket requests. Think of this as the principal “logging in” to the KDC, similar to what you’d do with a username and password. Keytab files can make their way to clients one of two ways.

  1. Manually creating and copying the keytab file to the client (old school)
  2. Using the domain join tool of your choice (realmd, net ads/samba, adcli, etc.) on the client to automatically negotiate the keytab and machine principals on the KDC (recommended)

Keytab files, when created using the domain join tools, will create multiple entries for Kerberos principals. Generally, this will include a service principal name (SPN) for host/shortname@REALM.COM, host/fully.qualified.name@REALM.COM and a UPN for the machine account such as MACHINE$@REALM.COM. The auto-generated keytabs will also include multiple entries for each principal with different encryption types (enctypes). The following is an example of a CentOS 7 box’s keytab joined to an AD domain using realm join:

# klist -kte
Keytab name: FILE:/etc/krb5.keytab
KVNO Timestamp Principal
---- ------------------- ------------------------------------------------------
 3 05/15/2017 18:01:39 host/centos7.ntap.local@NTAP.LOCAL (des-cbc-crc)
 3 05/15/2017 18:01:39 host/centos7.ntap.local@NTAP.LOCAL (des-cbc-md5)
 3 05/15/2017 18:01:39 host/centos7.ntap.local@NTAP.LOCAL (aes128-cts-hmac-sha1-96)
 3 05/15/2017 18:01:39 host/centos7.ntap.local@NTAP.LOCAL (aes256-cts-hmac-sha1-96)
 3 05/15/2017 18:01:39 host/centos7.ntap.local@NTAP.LOCAL (arcfour-hmac)
 3 05/15/2017 18:01:39 host/CENTOS7@NTAP.LOCAL (des-cbc-crc)
 3 05/15/2017 18:01:39 host/CENTOS7@NTAP.LOCAL (des-cbc-md5)
 3 05/15/2017 18:01:39 host/CENTOS7@NTAP.LOCAL (aes128-cts-hmac-sha1-96)
 3 05/15/2017 18:01:39 host/CENTOS7@NTAP.LOCAL (aes256-cts-hmac-sha1-96)
 3 05/15/2017 18:01:39 host/CENTOS7@NTAP.LOCAL (arcfour-hmac)
 3 05/15/2017 18:01:39 CENTOS7$@NTAP.LOCAL (des-cbc-crc)
 3 05/15/2017 18:01:39 CENTOS7$@NTAP.LOCAL (des-cbc-md5)
 3 05/15/2017 18:01:39 CENTOS7$@NTAP.LOCAL (aes128-cts-hmac-sha1-96)
 3 05/15/2017 18:01:39 CENTOS7$@NTAP.LOCAL (aes256-cts-hmac-sha1-96)
 3 05/15/2017 18:01:39 CENTOS7$@NTAP.LOCAL (arcfour-hmac)

Encryption types (enctypes)

Encryption types (or enctypes) are the level of encryption used for the Kerberos conversation. The client and KDC will negotiate the level of enctype used. The client will tell the KDC “hey, I want to use this list of enctypes. Which do you support?” and the KDC will respond “I support these, in order of strongest to weakest. Try using the strongest first.” In the example above, this is the order of enctype strength, from strongest to weakest:

  • AES-256
  • AES-128
  • ARCFOUR-HMAC
  • DES-CBC-MD5
  • DES-CBC-CRC

The reason a keytab file would add weaker enctypes like DES or ARCFOUR is for backwards compatibility. For example, Windows 2008 DCs don’t support AES enctypes. In some cases, the enctypes can cause Kerberos issues due to lack of support. Windows 2008 and later don’t support DES unless you explicitly enable it. ARCFOUR isn’t supported in clustered ONTAP for NFS Kerberos. In these cases, it’s good to modify the machine accounts to strictly define which enctypes to use for Kerberos.

What you need before you try mounting

This is a quick list of things that have to be in place before you can expect Kerberos with NFS to work properly. If I left something out, feel free to remind me in the comments. There’s so much info involved that I occasionally forget some things. 🙂

KDC and client – The KDC is a given – in this case, Active Directory. The client would need to have some things installed/configured before you try to join it, including a valid DNS server configuration, Kerberos utilities, etc. This varies depending on client and would be too involved to get into here. Again, TR-4073 would be a good place to start.

DNS entries for all clients and servers participating in the NFS Kerberos operation – this includes forward and reverse (PTR) records for the clients and servers. The DNS friendly names *must* match the SPN names. If they don’t, then when you try to mount, the DNS lookup will file the name hostname1 and use that to look up the SPN host/hostname1. If the SPN was called nfs/hostname2, then the Kerberos attempt will fail with “PRINCIPAL_UNKNOWN.” This is also true for Kerberos in CIFS/SMB environments. In ONTAP, a common mistake people make is they name the CIFS server or NFS Kerberos SPN as the SVM name (such as SVM1), but their DNS names are something totally different (such as cifs.domain.com).

Valid Kerberos SPNs and UPNs – When you join a Linux client to a domain, the machine account and SPNs are automatically created. However, the UPN is not created. Having no UPN on a machine account can create issues with some Linux services that use Kerberos keytab files to authenticate. For example, RedHat’s LDAP service (SSSD) can fail to bind if using a Kerberos service principal in the configuration via the ldap_sasl_authid option. The error you’d see would be “PRINCIPAL_UNKNOWN” and would drive you batty because it would be using a principal you *know* exists in your environment. That’s because it’s trying to find the UPN, not the SPN. You can manage the SPN and UPN via the Active Directory attributes tab in the advanced features view. You can query whether SPNs exist via the setspn command (use /q to query by SPN name) in the CLI or PowerShell.

PS C:\> setspn /q host/centos7.ntap.local
Checking domain DC=NTAP,DC=local
CN=CENTOS7,CN=Computers,DC=NTAP,DC=local
 HOST/centos7.ntap.local
 HOST/CENTOS7

Existing SPN found!

You can view a user’s UPN and SPN with the following PowerShell command:

PS C:\> Get-ADUser student1 -Properties UserPrincipalName,ServicePrincipalName

DistinguishedName : CN=student1,CN=Users,DC=NTAP,DC=local
Enabled : True
GivenName : student1
Name : student1
ObjectClass : user
ObjectGUID : d5d5b526-bef8-46fa-967b-00ebc77e468d
SamAccountName : student1
SID : S-1-5-21-3552729481-4032800560-2279794651-1108
Surname :
UserPrincipalName : student1@NTAP.local

And a machine account’s with:

PS C:\> Get-ADComputer CENTOS7$ -Properties UserPrincipalName,ServicePrincipalName

DistinguishedName : CN=CENTOS7,CN=Computers,DC=NTAP,DC=local
DNSHostName : centos7.ntap.local
Enabled : True
Name : CENTOS7
ObjectClass : computer
ObjectGUID : 3a50009f-2b40-46ea-9014-3418b8d70bdb
SamAccountName : CENTOS7$
ServicePrincipalName : {HOST/centos7.ntap.local, HOST/CENTOS7}
SID : S-1-5-21-3552729481-4032800560-2279794651-1140
UserPrincipalName : HOST/centos7.ntap.local@NTAP.LOCAL

Network Time Protocol (NTP) – With Kerberos, there is a 5 minute default time skew window. If a client and server/KDC’s time is outside of that window, Kerberos requests will fail with “Access denied” and you’d see time skew errors in the cluster logs. This KB covers it nicely:

https://kb.netapp.com/support/s/article/ka11A0000001V1YQAU/Troubleshooting-Workflow-CIFS-Authentication-failures?language=en_US

A common issue I’ve seen with this is time zone differences or daylight savings issues. I’ve often seen the wall clock time look identical on server and client, but the time zones or month/date differ, causing the skew.

The NTP requirement is actually a “make sure your time is up to date and in sync on everything” requirement, but NTP makes that easier.

Kerberos to UNIX name mappings – In ONTAP, we authenticate via name mappings not only for CIFS/SMB, but also for Kerberos. When a client attempts to send an authentication request to the cluster for an AS request or ST (service ticket) request, it has to map to a valid UNIX user. The UNIX user mapping will depend on what type of principal is coming in. If you don’t have a valid name mapping rule, you’d see something like this in the event log:

5/16/2017 10:24:23 ontap9-tme-8040-01
 ERROR secd.nfsAuth.problem: vserver (DEMO) General NFS authorization problem. Error: RPC accept GSS token procedure failed
 [ 8 ms] Acquired NFS service credential for logical interface 1034 (SPN='nfs/demo.ntap.local@NTAP.LOCAL').
 [ 11] GSS_S_COMPLETE: client = 'CENTOS7$@NTAP.LOCAL'
 [ 11] Trying to map SPN 'CENTOS7$@NTAP.LOCAL' to UNIX user 'CENTOS7$' using implicit mapping
 [ 12] Using a cached connection to oneway.ntap.local
**[ 14] FAILURE: User 'CENTOS7$' not found in UNIX authorization source LDAP.
 [ 15] Entry for user-name: CENTOS7$ not found in the current source: LDAP. Ignoring and trying next available source
 [ 15] Entry for user-name: CENTOS7$ not found in the current source: FILES. Entry for user-name: CENTOS7$ not found in any of the available sources
 [ 15] Unable to map SPN 'CENTOS7$@NTAP.LOCAL'
 [ 15] Unable to map Kerberos NFS user 'CENTOS7$@NTAP.LOCAL' to appropriate UNIX user

For service principals (SPNS) such as host/name or nfs/name, the mapping would try to default to primary/, so you’d need a UNIX user named host or nfs on the local SVM or in a name service like LDAP. Otherwise, you can create static krb-unix name mappings in the SVM to map to whatever user you like. If you want to use wild cards, regex, etc. you can do  that. For example, this name mapping rule will map all SPNs coming in as {MACHINE}$@REALM.COM to root.

cluster::*> vserver name-mapping show -vserver DEMO -direction krb-unix -position 1

Vserver: DEMO
 Direction: krb-unix
 Position: 1
 Pattern: (.+)\$@NTAP.LOCAL
 Replacement: root
IP Address with Subnet Mask: -
 Hostname: -

To test the mapping, use diag priv:

cluster::*> diag secd name-mapping show -node node1 -vserver DEMO -direction krb-unix -name CENTOS7$@NTAP.LOCAL

'CENTOS7$@NTAP.LOCAL' maps to 'root'

You can map the SPN to root, pcuser, etc. – as long as the UNIX user exists locally on the SVM or in the name service.

The workflow

Now that I’ve gotten some basics out of the way (and if you find that I’ve missed some, add to the comments), let’s look at how the workflow for an NFS mount using Kerberos would work, end to end. This is assuming we’ve configured everything correctly and are ready to mount, and that all the export policy rules allow the client to mount NFSv4 and Kerberos. If a mount fails, always check your export policy rules first.

Some common export policy issues include:

  • The export policy doesn’t have any rules configured
  • The vserver/SVM root volume doesn’t allow read access in the export policy rule for traversal of the / mount point in the namespace
  • The export policy has rules, but they are either misconfigured (clientmatch is wrong, read access disallowed, NFS protocol or auth method is disallowed) or they aren’t allowing the client to access the mount (Run export-policy rule show -instance)
  • The wrong/unexpected export policy has been applied to the volume (Run volume show -fields policy)

What’s unfortunate about trying to troubleshoot mounts with NFS Kerberos involved is that, regardless of the failures happening, the client will report:

mount.nfs: access denied by server while mounting

It’s a generic error and isn’t really helpful in diagnosing the issue.

In ONTAP, there is a command in admin privilege to check the export policy access for the client for troubleshooting purposes. Be sure to use it to rule out export issues.

cluster::> export-policy check-access -vserver DEMO -volume flexvol -client-ip 10.193.67.225 -authentication-method krb5 -protocol nfs4 -access-type read-write
 Policy Policy Rule
Path Policy Owner Owner Type Index Access
----------------------------- ---------- --------- ---------- ------ ----------
/ root vsroot volume 1 read
/flexvol default flexvol volume 1 read-write
2 entries were displayed.

The mount command is issued.

In my case, I use NFSv4.x, as that’s the security standard. Mounting without specifying a version will default to the highest NFS version allowed by the client and server, via a client-server negotiation. If NFSv4.x is disabled on the server, the client will fall back to NFSv3.

# mount -o sec=krb5 demo:/flexvol /mnt

Once the mount command gets issued and Kerberos is specified, a few (ok, a lot of) things happen in the background.

While this stuff happens, the mount command will appear to “hang” as the client, KDC and server suss out if you’re going to be allowed access.

  • DNS lookups are done for the client hostname and server hostname (or reverse lookup of the IP address) to help determine what names are going to be used. Additionally, SRV lookups are done for the LDAP service and Kerberos services in the domain. DNS lookups are happening constantly through this process.
  • The client uses its keytab file to send an authentication service request (AS-REQ) to the KDC, along with what enctypes it has available. The KDC then verifies if the requested principal actually exists in the KDC and if the enctypes are supported.
  • If the enctypes are not supported, or if the principal exists, or if there are DUPLICATE principals, the AS-REQ fails. If the principal exists, the KDC will send a successful reply.
  • Then the client will send a Ticket Granting Service request (TGS-REQ) to the KDC. This request is an attempt to look up the NFS service ticket named nfs/name. The name portion of the ticket is generated either via what was typed into the mount command (ie, demo) or via reverse lookup (if we typed in an IP address to mount). The TGS-REQ will be used later to allow us to obtain a service ticket (ST). The TGS will also negotiate supported enctypes for later. If the TGS-REQ between the KDC and client negotiates an enctype that ONTAP doesn’t support (for example, ARCFOUR), then the mount will fail later in process.
  • If the TGS-REQ succeeds, a TGS-REP is sent. If the KDC doesn’t support the requested enctypes from the client, we fail here. If the NFS principal doesn’t exist (remember, it has to be in DNS and match exactly), then we fail.
  • Once the TGS is acquired by the NFS client, it presents the ticket to the NFS server in ONTAP via a NFS NULL call. The ticket information includes the NFS service SPN and the enctype used. If the NFS SPN doesn’t match what’s in “kerberos interface show,” the mount fails. If the enctype presented by the client isn’t supported or is disallowed in “permitted enctypes” on the NFS server, the request fails. The client would show “access denied.”
  • The NFS service SPN sent by the client is presented to ONTAP. This is where the krb-unix mapping takes place. ONTAP will first see if a user named “nfs” exists in local files or name services (such as LDAP, where a bind to the LDAP server and lookup takes place). If the user doesn’t exist, it will then check to see if any krb-unix name mapping rules were set explicitly. If no rules exist and mapping fails, ONTAP logs an error on the cluster and the mount fails with “Access denied.” If the mapping works, the mount procedure moves on to the next step.
  • After the NFS service ticket is verified, the client will send SETCLIENTID calls and then the NFSv4.x mount compound call (PUTROOTFH | GETATTR). The client and server are also negotiating the name@domainID string to make sure they match on both sides as part of NFSv4.x security.
  • Then, the client will try to run a series of GETATTR calls to “/” in the path. If we didn’t allow “read” access in the policy rule for “/” (the vsroot volume), we fail. If the ACLs/mode bits on the vsroot volume don’t allow at least traverse permissions, we fail. In a packet trace, we can see that the vsroot volume has only traverse permissions:
    V4 Reply (Call In 268) ACCESS, [Access Denied: RD MD XT], [Allowed: LU DL]

    We can also see that from the cluster CLI (“Everyone” only has “Execute” permissions in this NTFS security style volume):

    cluster::> vserver security file-directory show -vserver DEMO -path / -expand-mask true
    
    Vserver: DEMO
     File Path: /
     File Inode Number: 64
     Security Style: ntfs
     Effective Style: ntfs
     DOS Attributes: 10
     DOS Attributes in Text: ----D---
    Expanded Dos Attributes: 0x10
     ...0 .... .... .... = Offline
     .... ..0. .... .... = Sparse
     .... .... 0... .... = Normal
     .... .... ..0. .... = Archive
     .... .... ...1 .... = Directory
     .... .... .... .0.. = System
     .... .... .... ..0. = Hidden
     .... .... .... ...0 = Read Only
     UNIX User Id: 0
     UNIX Group Id: 0
     UNIX Mode Bits: 777
     UNIX Mode Bits in Text: rwxrwxrwx
     ACLs: NTFS Security Descriptor
     Control:0x9504
    
    1... .... .... .... = Self Relative
     .0.. .... .... .... = RM Control Valid
     ..0. .... .... .... = SACL Protected
     ...1 .... .... .... = DACL Protected
     .... 0... .... .... = SACL Inherited
     .... .1.. .... .... = DACL Inherited
     .... ..0. .... .... = SACL Inherit Required
     .... ...1 .... .... = DACL Inherit Required
     .... .... ..0. .... = SACL Defaulted
     .... .... ...0 .... = SACL Present
     .... .... .... 0... = DACL Defaulted
     .... .... .... .1.. = DACL Present
     .... .... .... ..0. = Group Defaulted
     .... .... .... ...0 = Owner Defaulted
    
    Owner:BUILTIN\Administrators
     Group:BUILTIN\Administrators
     DACL - ACEs
     ALLOW-NTAP\Domain Admins-0x1f01ff-OI|CI
     0... .... .... .... .... .... .... .... = Generic Read
     .0.. .... .... .... .... .... .... .... = Generic Write
     ..0. .... .... .... .... .... .... .... = Generic Execute
     ...0 .... .... .... .... .... .... .... = Generic All
     .... ...0 .... .... .... .... .... .... = System Security
     .... .... ...1 .... .... .... .... .... = Synchronize
     .... .... .... 1... .... .... .... .... = Write Owner
     .... .... .... .1.. .... .... .... .... = Write DAC
     .... .... .... ..1. .... .... .... .... = Read Control
     .... .... .... ...1 .... .... .... .... = Delete
     .... .... .... .... .... ...1 .... .... = Write Attributes
     .... .... .... .... .... .... 1... .... = Read Attributes
     .... .... .... .... .... .... .1.. .... = Delete Child
     .... .... .... .... .... .... ..1. .... = Execute
     .... .... .... .... .... .... ...1 .... = Write EA
     .... .... .... .... .... .... .... 1... = Read EA
     .... .... .... .... .... .... .... .1.. = Append
     .... .... .... .... .... .... .... ..1. = Write
     .... .... .... .... .... .... .... ...1 = Read
    
    ALLOW-Everyone-0x100020-OI|CI
     0... .... .... .... .... .... .... .... = Generic Read
     .0.. .... .... .... .... .... .... .... = Generic Write
     ..0. .... .... .... .... .... .... .... = Generic Execute
     ...0 .... .... .... .... .... .... .... = Generic All
     .... ...0 .... .... .... .... .... .... = System Security
     .... .... ...1 .... .... .... .... .... = Synchronize
     .... .... .... 0... .... .... .... .... = Write Owner
     .... .... .... .0.. .... .... .... .... = Write DAC
     .... .... .... ..0. .... .... .... .... = Read Control
     .... .... .... ...0 .... .... .... .... = Delete
     .... .... .... .... .... ...0 .... .... = Write Attributes
     .... .... .... .... .... .... 0... .... = Read Attributes
     .... .... .... .... .... .... .0.. .... = Delete Child
     .... .... .... .... .... .... ..1. .... = Execute
     .... .... .... .... .... .... ...0 .... = Write EA
     .... .... .... .... .... .... .... 0... = Read EA
     .... .... .... .... .... .... .... .0.. = Append
     .... .... .... .... .... .... .... ..0. = Write
     .... .... .... .... .... .... .... ...0 = Read
  • If we have the appropriate permissions to traverse “/” then the NFS client attempts to find the file handle for the mount point via a LOOKUP call, using the file handle of vsroot in the path. It would look something like this:
    V4 Call (Reply In 271) LOOKUP DH: 0x92605bb8/flexvol
  • If the file handle exists, it gets returned to the client:
    fh.png
  • Then the client uses that file handle to run GETATTRs to see if it can access the mount:
    V4 Call (Reply In 275) GETATTR FH: 0x1f57355e

If all is clear, our mount succeeds!

But we’re not done… now the user that wants to access the mount has to go through another ticket process. In my case, I used a user named “student1.” This is because a lot of the Kerberos/NFSv4.x requests I get are generated by universities interested in setting up multiprotocol-ready home directories.

When a user like student1 wants to get into a Kerberized NFS mount, they can’t just cd into it. That would look like this:

# su student1
sh-4.2$ cd /mnt
sh: cd: /mnt: Not a directory

Oh look… another useless error! If I were to take that error literally, I would think “that mount doesn’t even exist!” But, it does:

sh-4.2$ mount | grep mnt
demo:/flexvol on /mnt type nfs4 (rw,relatime,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=krb5,clientaddr=10.193.67.225,local_lock=none,addr=10.193.67.219)

What that error actually means is that the user requesting access does not have a valid Kerberos AS ticket (login) to make the request for a TGS (ticket granting ticket) to get a service ticket for NFS (nfs/server-hostname). We can see that via the klist -e command.

sh-4.2$ klist -e
klist: Credentials cache keyring 'persistent:1301:1301' not found

Before you can get into a mount that is only allowing Kerberos access, you have to get a Kerberos ticket. On Linux, you can do that via the kinit command, which is akin to a Windows login.

sh-4.2$ kinit
Password for student1@NTAP.LOCAL:
sh-4.2$ klist -e
Ticket cache: KEYRING:persistent:1301:1301
Default principal: student1@NTAP.LOCAL

Valid starting Expires Service principal
05/16/2017 15:54:01 05/17/2017 01:54:01 krbtgt/NTAP.LOCAL@NTAP.LOCAL
 renew until 05/23/2017 15:53:58, Etype (skey, tkt): aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96

Now that I have a my ticket, I can cd into the mount. When I cd into a Kerberized NFS mount, the client will make TGS requests to the KDC (seen in the trace in packet 101) for the service ticket. If that process is successful, we get access:

sh-4.2$ cd /mnt
sh-4.2$ pwd
/mnt
sh-4.2$ ls
c0 c1 c2 c3 c4 c5 c6 c7 newfile2 newfile-nfs4
sh-4.2$ klist -e
Ticket cache: KEYRING:persistent:1301:1301
Default principal: student1@NTAP.LOCAL

Valid starting Expires Service principal
05/16/2017 15:55:32 05/17/2017 01:54:01 nfs/demo.ntap.local@NTAP.LOCAL
 renew until 05/23/2017 15:53:58, Etype (skey, tkt): aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96
05/16/2017 15:54:01 05/17/2017 01:54:01 krbtgt/NTAP.LOCAL@NTAP.LOCAL
 renew until 05/23/2017 15:53:58, Etype (skey, tkt): aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96

Now we’re done. (at least until our tickets expire…)

 

May 2016 update to TR-4073 (the NetApp NFS Kerberos/LDAP manifesto)

It’s time for new technical report updates!

koolaid

Since clustered Data ONTAP 8.3.2 is now available, we are publishing our 8.3.2 updates to our docs. I finally got the updates added to TR-4073: Secure Unified Authentication.

What is Secure Unified Authentication?

Secure Unified Authentication is a solution-based methodology to provide secure (via Kerberos) unified (via central LDAP servers for identity management) authentication for enterprise IT environments.

Security is more important than ever, so using a ticket-based auth process instead of over-the-wire passwords is one way to ensure you have protected your business assets. With AES-256 encryption, you are using the strongest available enctype for Kerberos.

Ease of management is also critical to an ever changing IT landscape. LDAP for Identity Management makes user account management and NAS permissioning easier.

What’s new?

  • PowerShell alternatives to LDIFDE queries
  • Extended GIDs best practices
  • Improved asymmetric name mapping support in LDAP
  • Expanding all hosts in a netgroup information
  • Vserver security command examples and information (fsecurity command parity)
  • Improved RFC-2307bis informati0n
  • Bind DN examples
  • LDAP terminology

Where can I find it?

Technical reports can be found a variety of ways. Google search works, as does looking in the NetApp library. I cover how to be better at NetApp documentation in a separate blog post. I also have a yet-unfinished series on LDAP here:

LDAP::What the heck is an LDAP anyway? – Part 1: Intro

To make it super easy, just follow this link:

TR-4073: Secure Unified Authentication

LDAP::LDAP Servers and Clients – Part 5

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:

https://whyistheinternetbroken.wordpress.com/2015/06/05/ldapldap-servers-and-clients-and-bears-oh-my-part-5/

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:

What the heck is an LDAP anyway?

This post will focus on LDAP servers and clients.

Servers vs clients

In the animal kingdom, you will often see symbotic relationships, such as the alleged relationship between crocodiles and the plover bird, which eats dead stuff from the croc’s teeth.

crocodileplover

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:

spider-symbiote

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.

Client/Server configuration

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):

  • SSSD
  • OpenLDAP

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.

osi-network-layer-cats

Bind/Login information.

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.

unbind

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.

Client-specific options

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

Servers

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
  • OpenLDAP
  • RedHat Directory Server/389 Directory Server
  • Apple Open Directory
  • Oracle Internet Directory
  • ApacheDS

LDAP Referrals

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!

My environment

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!

Wrap-up

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:

What the heck is an LDAP anyway?

LDAP::LDAP servers and clients and bears, oh my! – Part 5

UPDATE: I realized today that I wrote this same topic twice, in two different posts. This one should be considered the older effort. The newer, up-to-date post is here:

https://whyistheinternetbroken.wordpress.com/2015/07/29/ldap-servers-clients/

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:

What the heck is an LDAP anyway?

This post will focus on the bind portion of LDAP.

We’re off to see the Wizard of LDAP!

Clients vs. Servers

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.

Clients

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.

Others, like Linux OSes, need you to install packages to run client operations. Some common Linux-based LDAP clients include:

And many more!

When you install a client, you are far from done. You now have to configure that client to talk to the LDAP server. This requires a plethora of necessary information, including:

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?)

Bind/Login information.

This will depend on type of bind supported by the server. Can be username/password, Kerberos SPN, anonymous, etc. For more detailed info on binds, see part 2 of this series.

LDAP Search Information

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.

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.

Client-specific options

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

Servers

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.

LDAP Referrals

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!

My environment

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!

LDAP::Distinguishing Distinguished Names in LDAP – Part 4

This post is part 4 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:

What the heck is an LDAP anyway?

This post will focus on Distinguished Names (DN) in LDAP.


In LDAP, objects are stored in a hierarchical structure, much like folders in a file system. Each object has a unique identifier so that LDAP queries can find them quickly. These identifiers are known as “distinguished names.”

homer-distinguished

Contrary to how it sounds, these attributes are not fancy by any stretch of the imagination. In fact, they can be downright messy, depending on how the LDAP objects are laid out.

Distinguished Names (DNs)

Distinguished Names are the full paths to objects in LDAP. They are comprised of a number of Relative Distinguished Names (RDNs).

Relative Distinguished Names (RDNs)

RDNs are components of the Distinguished Name. In the diagram below, “DC=domain,DC=com” is a Relative DN to the DN of CN=Pat, OU=Users, DC=domain, DC=com.

ldap-directory-structure

How do these get messy?

In very large LDAP environments where objects are laid out in a deep folder structure, a DN can start to become very long. Each time a new object is added as a child to another object, another RDN is added to the DN. As a result, you could see a DN that looks like this:

CN=Pat, OU=Super, OU=Cali, OU=Fragi, OU=Listic, OU=Espi, OU=Alli, OU=Docius, OU=Users, DC=domain, DC=com

To avoid long DNs, you could use a wide folder structure. This is one suggested best practice for designing a LDAP environment, if only to make managing objects easier.

ldap-deep-wide

Types of Relative Distinguished Names

In the examples above, we see abbreviations like OU (Organizational Unit), DC (Domain Component) and others. These are simply different types of RDNs. There are a slew of these that are used in various LDAP schemas. The following table (from Microsoft’s MSDN) shows a list of typical RDNs used in LDAP.

String Attribute type
DC domainComponent
CN commonName
OU organizationalUnitName
O organizationName
STREET streetAddress
L localityName
ST stateOrProvinceName
C countryName
UID userid

As to what “type” of RDN to use, there really isn’t a wrong answer. These are simply identifiers. If there’s any “best practice” for this, it would be “make sure it makes sense.” For example, don’t use STREET to identify a user. Use something like CN instead. Sure, it’s possible to use STREET for users, but…

just-because

Reserved characters

There are rules to what characters can be used in RDNs. If these characters need to be included in the RDN, they have to be “escaped” with a backslash (\). The following characters are reserved for specific functions, so they require an escape.

Reserved character Description Hex value
space or # character at the beginning of a string
space character at the end of a string
, comma 0x2C
+ plus sign 0x2B
double quote 0x22
\ backslash 0x5C
< left angle bracket 0x3C
> right angle bracket 0x3E
; semicolon 0x3B
LF line feed 0x0A
CR carriage return 0x0D
= equals sign 0x3D
/ forwards slash 0x2F

Modifying DNs

In LDAP, it’s always possible to modify a DN. However, the best way to do that is via the automated tools available from the LDAP server provider. For example, in Active Directory LDAP, we can modify DNs via ADSI Edit. But the better way to do this is via the Active Directory Users and Computers interface. ADSI Edit should only be used when necessary. However, keep in mind that native Windows LDAP management tools are going away in the future, so you may have to resort to a 3rd party management tool. In non-Windows LDAP, DN modification can be done manually via LDIF files, or via the provided GUI interface. As always, check with your vendor for the best ways to do this.

Distinguished, but often forgotten

Distinguished names are often overlooked when implementing or troubleshooting LDAP environments. It’s important to keep them in mind and avoid not being able to see the forest for the trees…

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:

What the heck is an LDAP anyway?

LDAP::Schemin’ with schemas – Part 3

This post is part 3 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:

What the heck is an LDAP anyway?

This post will focus on the schema portion of LDAP.

homer-ldap-schema

What is a schema in LDAP?

A schema, as used by LDAP, is a set of defined rules that govern the kinds of information a server can hold. These include, but are not limited to:

  • Attribute Syntaxes—Provide information about the kind of information that can be stored in an attribute.
  • Matching Rules—Provide information about how to make comparisons against attribute values.
  • Matching Rule Uses—Indicate which attribute types may be used in conjunction with a particular matching rule.
  • Attribute Types—Define an object identifier (OID) and a set of names that may be used to refer to a given attribute, and associates that attribute with a syntax and set of matching rules. These are defined in detail in RFC-2252.
  • Object Classes—Define named collections of attributes and classify them into sets of required and optional attributes.
  • Name Forms—Define rules for the set of attributes that should be included in the RDN for an entry.
  • Content Rules—Define additional constraints about the object classes and attributes that may be used in conjunction with an entry.
  • Structure Rule—Define rules that govern the kinds of subordinate entries that a given entry may have.

When dealing with LDAP schemas, there are a subset of the above that we deal with on a regular basis for name services/identity management.

Attribute syntaxes

Attribute syntaxes define what type of information can be stored as an attribute. These are defined by an object identifier (OID) and control whether an entry can be in Unicode, integer format or other format.

The following table from OpenLDAP.org shows some commonly used attribute syntax OIDs:

Name OID Description
boolean 1.3.6.1.4.1.1466.115.121.1.7 boolean value
directoryString 1.3.6.1.4.1.1466.115.121.1.15 Unicode (UTF-8) string
distinguishedName 1.3.6.1.4.1.1466.115.121.1.12 LDAP DN
integer 1.3.6.1.4.1.1466.115.121.1.27 integer
numericString 1.3.6.1.4.1.1466.115.121.1.36 numeric string
OID 1.3.6.1.4.1.1466.115.121.1.38 object identifier
octetString 1.3.6.1.4.1.1466.115.121.1.40 arbitary octets

Microsoft Active Directory LDAP uses different OIDs for their attribute syntaxes. These can be seen in the schema via ADSI edit. As an example, while OpenLDAP uses an OID of 1.3.6.1.4.1.1466.115.121.1.15 for Unicode (UTF-8) strings, Active Directory uses 2.5.5.12:

attr-syntax-unicode

These attribute syntaxes are generally not modifiable.

Object classes

Object classes in LDAP are collections of specific types of attributes that help LDAP searches execute more efficiently. When a search is kicked off, the objectClass is passed in the search. For example:

Filter: (&(objectClass=User)(sAMAccountName=ldapuser))

The above objectClass is defined as “User,” but an also include (but is not limited to):

  • Person
  • organizationalPerson
  • Group
  • Top

For a complete list of objectClass attributes, see: http://oav.net/mirrors/LDAP-ObjectClasses.html

In Active Directory, the objectClass can be modified and viewed via the Active Directory Users and Computers in advanced view via the Attribute Editor tab.

attribute-edit-objectclass

When a LDAP search runs, it would pass the defined schema attribute for objectClass as defined in the client configuration. In NetApp’s clustered Data ONTAP, it would be passed via one of the object-class attributes:

cluster::*> ldap client schema show -vserver SVM -schema AD-IDMU -fields nis-object-class
 (vserver services ldap client schema show)
vserver schema  nis-object-class
------- ------- ----------------
SVM     AD-IDMU nisObject
cluster::*> ldap client schema show -vserver SVM -schema AD-IDMU -fields nis-netgroup-object-class
 (vserver services ldap client schema show)
vserver schema  nis-netgroup-object-class
------- ------- -------------------------
SVM     AD-IDMU nisNetgroup
cluster::*> ldap client schema show -vserver SVM -schema AD-IDMU -fields posix-group-object-class
 (vserver services ldap client schema show)
vserver schema  posix-group-object-class
------- ------- ------------------------
SVM     AD-IDMU Group
cluster::*> ldap client schema show -vserver SVM -schema AD-IDMU -fields posix-account-object-class
 (vserver services ldap client schema show)
vserver schema  posix-account-object-class
------- ------- --------------------------
SVM     AD-IDMU User

In a Linux client like RedHat running SSSD, it might look like this:

# cat /etc/sssd/sssd.conf | grep class
ldap_user_object_class = user
ldap_group_object_class = group

In general, we could think of objectClasses like we’d think of how we use a phone book’s Yellow Pages. We don’t look for things in the Yellow Pages by name, but rather by type of business. If we wanted to find a grocery store, we’d use an objectClass of “groceryStore” to filter our results to speed up our search.

Attributes

The most relevant and necessary parts of a LDAP server’s schema (at least when it comes to client configuration) are the attributes themselves. These are the specific entries in the LDAP schema that define who and what the object is, specifically. If we extend our Yellow Pages analogy, after we find the objectClass=groceryStore, these would be the phone number, address, etc. of the grocery store. That information happens to be the most critical portion of the object, as they tell us what we need to know about the object we were looking for.

In a LDAP server used for name services/identity management, the attributes will tell us information about users, groups, hosts, netgroups, etc. such as phone numbers, email addresses, physical location, IP addresses, UID/GID for UNIX based permissions, SIDs for Windows environments and many, many more.

Attributes are broken down into two categories: the attribute and the value.

The attribute

With regards to name services/identity management, an attribute that might matter to us would include (but are not limited to):

  • uid
  • uidNumber
  • gid
  • gidNumber
  • memberOf
  • objectClass
  • primaryGroupID
  • objectSid
  • sAMAccountName

These attributes are defined in schema templates of clients and should be compliant with RFC-2307 standards for a valid LDAP server configuration. Common LDAP servers such as Microsoft Active Directory, OpenLDAP, Sun Directory Server, RedHat Directory Server (and IdM), Apple Open Directory, Oracle Internet Directory, Vintela… these all fall under the RFC standards. For a list of LDAP software available, see this Wiki entry.

The value

This is the portion of the attribute that populates the information we want to be used in queries. For example, if I have an attribute of uid, I can populate the value with the list of UNIX names I want to use in queries.

When a LDAP search is issued, the attribute and value are passed.

Filter: (&(objectClass=User)(sAMAccountName=ldapuser))

In the above, both objectClass and sAMAccountName are attributes. User and ldapuser are values.

How do I change them?

Attribute values are editable in most cases, but in some cases, the LDAP schema might have set the value to “read only.” This is fairly common in Active Directory as a means of idiot-proofing/CYA. But there often are ways to modify the schemas to allow editing of these attributes, if desired. Always do this with caution, and ideally, in a lab first and with the guidance of your LDAP server vendor.

Attributes themselves are also editable. We can also create custom attributes in LDAP if we choose. 3rd party LDAP products like Vintela do this for you. But in most cases, it’s best to leave the default schemas alone, and instead, modify the clients to query the attributes we have populated. Many clients have default schema templates, including NetApp’s clustered Data ONTAP.

 Schema Template: AD-IDMU
 Comment: Schema based on Active Directory Identity Management for UNIX (read-only)
 RFC 2307 posixAccount Object Class: User
 RFC 2307 posixGroup Object Class: Group
 RFC 2307 nisNetgroup Object Class: nisNetgroup
 RFC 2307 uid Attribute: uid
 RFC 2307 uidNumber Attribute: uidNumber
 RFC 2307 gidNumber Attribute: gidNumber
 RFC 2307 cn (for Groups) Attribute: cn
 RFC 2307 cn (for Netgroups) Attribute: name
 RFC 2307 userPassword Attribute: unixUserPassword
 RFC 2307 gecos Attribute: name
 RFC 2307 homeDirectory Attribute: unixHomeDirectory
 RFC 2307 loginShell Attribute: loginShell
 RFC 2307 memberUid Attribute: memberUid
 RFC 2307 memberNisNetgroup Attribute: memberNisNetgroup
 RFC 2307 nisNetgroupTriple Attribute: nisNetgroupTriple
ONTAP Name Mapping windowsAccount Attribute: msDS-PrincipalName
 Vserver Owns Schema: false
 RFC 2307 nisObject Object Class: nisObject
 RFC 2307 nisMapName Attribute: nisMapName
 RFC 2307 nisMapEntry Attribute: nisMapEntry

Schema extension

By default, Microsoft Active Directory do not contain the UNIX attributes needed to use the server as a UNIX Identity Management server. The schema had to be extended to create the necessary attributes types to allow for proper UNIX-based authentication. Extending the schema in domains with multiple domain controllers is non-disruptive; only one server needs to have the schema extended and then it can replicate to the other servers. For information on extending schemas or enabling identity management, see the TechNet article on IDMU.

UNIX-based LDAP servers such as OpenLDAP don’t have to do this, as they are intended for use with UNIX authentication by default.

Replication of schemas

One of the reasons I like Microsoft’s Active Directory so much for UNIX identity management (aside from the integration of services and pre-existence in enterprise environments) is the built-in schema replication. Want to create a new LDAP server? Cool. Add it to the domain. You’re done.

Microsoft Active Directory replicates every 15 minutes by default. That means all schemas, attributes, etc. get copied over to all domain controllers in a domain.

In a forest with multiple domains, it’s possible to replicate UNIX attributes across those domains to allow cross-domain UNIX authentication. So if your company acquires another company, you can simply add their domain to your forest and enable replication of their UNIX attributes and keep using your existing set up. I describe how to do this in TR-4073 on page 103.

Non-Windows LDAP servers also have the capability to replicate schemas and attributes, but they need configuration and are not as robust as Windows, in my opinion. This is changing somewhat with RedHat Directory Server/IdM, especially with RedHat 7 and the ability to integrate into Active Directory domains. I’ll cover that set up in a later blog post. 🙂 (thanks to Natxo for pointing out that omission)

What else?

LDAP schemas are the lifeblood of directory services, so it’s important to understand them as best as possible. Hopefully this post has helped clear some things up.

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:

What the heck is an LDAP anyway?

LDAP:: In a bind? LDAP can help! – Part 2

This post is part 2 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:

What the heck is an LDAP anyway?

This post will focus on the bind portion of LDAP.

What is a “bind”?

Not to be confused with BIND (the DNS server), bind in LDAP is essentially authenticating to the LDAP server to allow access to query for schema attributes. You “bind” to the server and start LDAP-ing.

Binds can occur in one of three main ways.

1. Anonymous

This type of bind is, as the name suggests, extremely insecure. Anonymous binds allow everyone and anyone who has the LDAP server information to query for users, groups, etc. There is no username or password needed. While this is much easier to set up and likely much faster (since we don’t have to ask any questions/give any answers), it’s also not recommended. In fact, many vendors, including Microsoft Active Directory and RedHat, disable anonymous binds by default.

2. Simple

Simple binds are more secure than anonymous binds in that the require a valid user in LDAP with read-only permissions, as well as a password. However, simple binds still aren’t *that* secure, as the password is passed over the wire. In plain text.

simple-bind1

simple-bind2-plaintext

With simple binds, it’s possible to use SSL to encrypt the bind to prevent that. In the example below, I connected to my LDAP server over SSL on port 636 using ldp.exe:

ldaps

My Windows 2008R2 LDAP server supports GSSAPI, GSS-SPNEGO, EXTERNAL and DIGEST-MD5 for SASL. Even though we’re doing simple bind, we still encrypt using the strongest available enctype possible on the LDAP server. In this case, we end up using AES:

tls-aes

And a packet trace shows no LDAP packets – only TLSv1:

tls-ldap

Some caveats:

  • Setting up LDAP over SSL on your LDAP server isn’t  the most intuitive thing in the world, but it’s not hard. For Windows, use the following links:

LDAP over SSL Certificate

Using ldp to test connectivity

  • When you use LDAP over SSL, good luck troubleshooting LDAP queries via packet trace. They’re all encrypted now.
  • LDAP clients must have the certs installed as well.

3. SASL

Simple Authentication and Security Layer (SASL) is a security mechanism that allows a variety of different encryption types to be used without the need for setting up certificate services on a LDAP server. It splits the authentication mechanism out and allows more integrated mechanisms to be used. A list of these can be found on the SASL wiki page.

Using our existing setup as an example, I can leverage Kerberos to bind to my LDAP server rather than SSL. Ldp.exe is a great tool to use for this, as I can control how my binds occur. Be on the look out for future posts on that tool…

When I bind via SASL, I see LDAP packets, but my bind doesn’t come across with a username/password. Instead, I am able to use Kerberos to bind. I didn’t even need to provide a username/password at all!

The following query was done from a cluster running clustered Data ONTAP 8.2.3:

cdot-ldap-sasl

In the trace, we’re doing AES-256 (strongest enctype available) to bind using SPNEGO (SPN negotiation). To do this, you would need a SPN with the LDAP server information available.

For example:

C:\>setspn /Q ldap/2k8-dc-1.domain.win2k8.netapp.com
Checking domain DC=domain,DC=win2k8,DC=netapp,DC=com
CN=2K8-DC-1,OU=Domain Controllers,DC=domain,DC=win2k8,DC=netapp,DC=com
 cifs/2k8-dc-1.domain.win2k8.netapp.com
 kadmin/2k8-dc-1.domain.win2k8.netapp.com
 ldap/2K8-DC-1.domain.win2k8.netapp.com/ForestDnsZones.domain.win2k8.netapp.com
 ldap/2K8-DC-1.domain.win2k8.netapp.com/DomainDnsZones.domain.win2k8.netapp.com
 TERMSRV/2K8-DC-1
 TERMSRV/2K8-DC-1.domain.win2k8.netapp.com
 Dfsr-12F9A27C-BF97-4787-9364-D31B6C55EB04/2K8-DC-1.domain.win2k8.netapp.com
 DNS/2K8-DC-1.domain.win2k8.netapp.com
 GC/2K8-DC-1.domain.win2k8.netapp.com/domain.win2k8.netapp.com
 RestrictedKrbHost/2K8-DC-1.domain.win2k8.netapp.com
 RestrictedKrbHost/2K8-DC-1
 HOST/2K8-DC-1/DOMAIN
 HOST/2K8-DC-1.domain.win2k8.netapp.com/DOMAIN
 HOST/2K8-DC-1
 HOST/2K8-DC-1.domain.win2k8.netapp.com
 HOST/2K8-DC-1.domain.win2k8.netapp.com/domain.win2k8.netapp.com
 E3514235-4B06-11D1-AB04-00C04FC2DCD2/277b3b64-265b-4612-a5ac-b06adf2a39b8/domain.win2k8.netapp.com
 ldap/2K8-DC-1/DOMAIN
 ldap/277b3b64-265b-4612-a5ac-b06adf2a39b8._msdcs.domain.win2k8.netapp.com
 ldap/2K8-DC-1.domain.win2k8.netapp.com/DOMAIN
 ldap/2K8-DC-1
 ldap/2K8-DC-1.domain.win2k8.netapp.com
 ldap/2K8-DC-1.domain.win2k8.netapp.com/domain.win2k8.netapp.com
Existing SPN found!

Additionally, you’d need a LDAP SRV record in DNS for the specified LDAP server. In this case, I use “domain.win2k8.netapp.com” as my LDAP server.

C:\>nslookup
Default Server: UnKnown
Address: ::1
> set type=all
> _ldap._tcp.dc._msdcs.domain.win2k8.netapp.com
Server: UnKnown
Address: ::1
_ldap._tcp.dc._msdcs.domain.win2k8.netapp.com SRV service location:
 priority = 0
 weight = 100
 port = 389
 svr hostname = 2k8-dc-1.domain.win2k8.netapp.com
2k8-dc-1.domain.win2k8.netapp.com internet address = 10.228.225.120
2k8-dc-1.domain.win2k8.netapp.com AAAA IPv6 address = fd20:8b1e:b255:8599:5457:61d9:fc87:423f

As luck would have it (ok, design), Microsoft Active Directory is perfect for UNIX based LDAP because it already includes things like SRV records, SPNs, etc. The only time things get hard is when you have to get more customized with the configuration.

You can also do many of the same things with any LDAP server that supports the RFC-2307, RFC-2251, etc. standards.

What can be used to bind?

For authenticated binds, the options for what can be used for binding to LDAP depend on the client. For details, contact the owner of the LDAP client or the docs.

Some of the options include:

  • Name in LDAP DN format. (ie, CN=ldapuser,OU=Users,DC=domain,DC=com)
  • Simple user name. (ie, ldapuser)
  • User principal name (UPN, ie ldapuser@domain.com)
  • Service principal name. (SPN, ie root/fqdn.domain.com)
  • Blank user name. (anonymous binds or binds that negotiate protocols via Kerberos/DNS)
  • CIFS/SMB Machine account. (Often in storage vendors where CIFS is also present)

If using a user to bind with simple or SASL, then the user has to have readonly access to the LDAP schema.

Troubleshooting binds

Troubleshooting binds should be pretty straightforward – you are essentially troubleshooting a login.

The following things should be considered when dealing with binds that are not working properly:

  • Is the LDAP client connecting to the server? (check network, ports, IP, DNS, etc.)
  • Is the LDAP server/hostname correct?
  • Is the bind level correct? Does the client configuration for bind level match what the server supports? (SSL? SASL?)
  • If using SSL, is the LDAP port configuration correct? (Port 389 for LDAP, port 636 for SSL, port 3268 for Active Directory Global Catalog searches)
  • Is the bind user correct? The bind password?
  • If intending to use Kerberos for binds, is there a SPN configured? Are there forward (A/AAAA) and reverse (PTR) DNS records for the LDAP server/domain?

Some tools that come in handy for troubleshooting LDAP:

  • Ping
  • Telnet (to check for ports)
  • Netstat (to check for ports)
  • Nslookup/dig
  • Ldp.exe
  • Ldapsearch
  • Wireshark/tcpdump (my personal favorite)
  • Various logs (Event viewer in MS, /var/log in Linux) – try debug level!

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:

What the heck is an LDAP anyway?

LDAP::What the heck is an LDAP anyway? – Part 1: Intro

Where’d I put that UID? Source: ZDNet.com

In my time in technical support and as the Technical Marketing Engineer at NetApp, I’ve come to realize that LDAP is one misunderstood technology, which is unfortunate, because I am seeing a large uptick in people who are using it in enterprise environments. As a result, I plan on starting a series of LDAP related posts based on this one, which was originally posted in February of 2015. These will be listed in TECH and LDAP Categories on this blog.

Some topics I’ll be covering (which will become links as they are written):

NOTE: I’m going to keep this real high-level and not bore you with all the details because we could get into the weeds real fast. You can always find copious amount of less interesting information out there in my Technical Reports or on your preferred search engine. If you have specific questions or want me to add something to this entry, hit me up on Twitter @NFSDudeAbides.

What is LDAP?

LDAP is also known as “Lightweight Directory Access Protocol.” It is, essentially, a database that acts as a phone book for all sorts of information for clients and servers in enterprise NAS environments. Some of these include:

  • Names
  • Addresses
  • Phone numbers
  • Unique numerical identifiers (SID, UID, GID, UUID, etc)
  • And many more!

Is Microsoft Active Directory LDAP?

Yes. And no. And maybe.

Microsoft Active Directory uses LDAP for its backend. It leverages LDAP RFC-2307 schema standards and populates records in its database with all sorts of good information about its objects.

For example, this machine account:

machineaccount

Notice it has all sorts of data about that machine account, including the servicePrincipalName (SPN) that is critical to leveraging Kerberos in both Microsoft and non-Microsoft KDCs.

However, while Microsoft is a using LDAP and technically could be called LDAP, it’s not LDAP in the traditional sense. That is reserved for the use of UNIX style attributes for users, groups, netgroups and so on. By default, Microsoft does not apply these schema attributes to its implementation of LDAP. However, the schema can be modified or extended to add attributes to populate things like UID, GID, etc.

How does it work?

LDAP functionality works like this, in a simplistic view.

  • A database is populated with objects and schema attributes.
  • LDAP clients are configured to connect to the LDAP server. This normally means they use port 389 or 636 (LDAP over SSL). Sometimes, the Global Catalog port 3268 can be used when using AD LDAP.
  • When a client connects to LDAP, it tries to bind based on the configuration. This can be SASL (such as GSSAPI, DIGEST-MD5, etc), simple or anonymous, depending on what the client and server are configured for/support.
  • After a bind, a lookup is done via RFC standards using ldapsearch commands and filter strings.
  • If the object and requested attributes exist, they are returned to the client.

Pretty straightforward. The hard part is remembering it. 🙂

What is it used for?

LDAP is used for enterprise NAS environments that want to centralize their identity management rather than keeping track of n number of passwd, group, netgroup and other files. Having LDAP service the clients allows standardized and automated client rollout. All atomic updates are done from the server side and replicated across multiple servers. All a client has to do is connect and search.

In TR-4073: Secure Unified Authentication, I cover LDAP as it pertains to NetApp’s clustered Data ONTAP. It focuses mainly on Microsoft Active Directory as an LDAP server, but also includes information on RedHat’s Directory Server (which is THE best UNIX-based LDAP server I’ve used so far).

Additionally, a new name service best practice guide was just released today. Check out TR-4379: Name Services Best Practices for more info.