JumpCloud’s Directory-as-a-Service solution is based in large part on LDAP. A core part of the solution is to enable devices and applications to authenticate via LDAP. The way our solution works is that admins place their users in the JumpCloud directory. Our directory enables those credentials that have been created in the JumpCloud directory to be leveraged via a number of different protocols such LDAP, SAML, SSH, and others. The goal of Directory-as-a-Service is to enable a wide variety of devices and applications to be authenticated and authorized.
For this particular blog post, we’ll focus on the ability for applications to authenticate to our LDAP server. The process generally works as follows:
- Users are created within JumpCloud
- To authenticate/authorize via LDAP, you enable the LDAP setting in JumpCloud
- You configure your application to connect and authenticate/authorize to the JumpCloud LDAP server
- An end user types in their credentials in the application
- The application authenticates and authorizes to JumpCloud’s LDAP endpoint
- The user is granted the proper permissions
The core of this process is how to configure your application to communicate with JumpCloud. This can be a tricky configuration setup if you don’t know the various parameters to pass to LDAP. We’ll review some of those parameters here, but, of course, if you need help connecting your application to JumpCloud, just drop us a note – we’d be happy to help.
We’ve already blogged about connecting a number of common applications to JumpCloud. These include: Git LDAP authentication, Okta, OpenVPN, Meraki, Jira, Confluence, and MySQL LDAP configurations among others. These are good examples and will provide you with a variety of different approaches to connecting your application to LDAP.
For your specific application, we’ll go over some of the key parameters to consider:
- Hostname or IP address – you’ll need to configure the JumpCloud hostname or IP address for your application to connect to JumpCloud. With JumpCloud, this is “ldap.jumpcloud.com”
- Port – you’ll want to specify the port that you would like to go over to JumpCloud. We use two ports – 389 and 636. Port 636 is reserved for LDAPS, while 389 supports either clear text communications or STARTTLS.
- Encryption approach – you’ll want to specify whether you are using SSL, STARTTLS, or clear text. Because LDAP encryption is up to the client, and not the server, we recommend that you use STARTTLS whenever possible (LDAPS, or LDAP over SSL, is deprecated, though still frequently supported by clients and servers, including JumpCloud). Using cleartext for initial setup and troubleshooting can be very helpful, but for production, STARTTLS is preferred (use port 389 with STARTTLS enabled in your client).
Binding
Field names for applications include: Bind DN, Manager DN, Password
In LDAP, authenticating your user is called “binding” to the directory. With a bind, you provide your username and password to the LDAP server. There are three potential outcomes:
- Your username and password are not recognized. This results in an authentication failure (you can’t go any further, nor do you know any more about the user than when you started).
- Your username and password are recognized, but the user has no further permissions on the LDAP server. You know from this that the user has provided correct credentials, so you can (reasonably) trust that they are who they say they are, but they can’t do anything further with the directory itself. Most of your user accounts should fall into this category.
- Your username and password are recognized, and the user has additional permissions to read and/or write objects in the directory. JumpCloud calls this type of user an “LDAP Binding User Service account.” Users with this level of permission can search the remainder of the directory. They are able to look at all the users in the JumpCloud account, as well as their tag and POSIX group membership. You’ll use this type of user account for your applications to look up group membership, enumerate users, or to be able to use the LDAP directory for application or system-wide authentication and authorization.
Because LDAP is a directory database, and not simply a user store, it’s a bit more complicated to specify your username than with a simple user store. LDAP is a hierarchical database, which means that you need to provide a full path to your user object. A username in isolation won’t be enough information for LDAP to identify which user object you’re talking about.
In JumpCloud you specify a user in the following format:
uid=<username>,ou=Users,o=<organizationId>,dc=jumpcloud,dc=com
for example:
uid=jdoe,ou=Users,o=309AF39093AFBBDCF902093015672309,dc=jumpcloud,dc=com
The directory structure is read from right to left:
- That is, dc=com is the top of the directory tree, and potentially multiple dc objects can be found beneath it. With JumpCloud’s hosted LDAP service, only one dc object exists within “com”, and that is “dc=jumpcloud”. The abbreviation, “dc”, stands for domain component, and is meant to identify an organizational domain.
- Next, o=<organizationId> uniquely identifies your part of the JumpCloud LDAP directory. It’s how JumpCloud partitions and isolates user account data from one customer to the next – fully and securely.
- “ou=Users” specifies the “organizational unit”, which is a fancy term for a container of multiple objects. All objects in the JumpCloud hosted LDAP service can be found in the Users OU, which includes user objects, group objects, and POSIX group objects.
- Finally, uid specifies the username in your Users OU. This username is what you would commonly think of as the username that you would type in along with your password.
The string above, “uid=<username>,ou=Users,o=<organizationId>,dc=jumpcloud,dc=com” is called a “DN” or distinguished name, because it uniquely identifies an object in the LDAP directory structure.
So when you bind to JumpCloud’s LDAP directory, instead of username and password, you really provide a DN and password for authentication. Some applications only try to bind to LDAP to perform authentication, while others bind and then search. Those that bind and search require an LDAP Binding User Service Account for the DN, while the others do not.
Searching
Field names for applications include: Search Base, Group Name, User Name, Base DN
Assuming that a bind has taken place with an LDAP Binding User Service Account, let’s consider the three types of objects that you can search:
- Users: A user is an object (really based on an object type called InetOrgPerson) which contains all the details for a given user in your directory. JumpCloud also provides the “memberOf overlay”, which means that each user contains the list of groups of which it is a member, which some client applications require to determine group membership.
- Groups: JumpCloud LDAP provides “groupsOfNames” objects which contains DNs for all users that are selected within a JumpCloud Tag. This allows you to use a Tag as a way to specify roles and access authorization for any number of users or any number of applications. It’s always up to the application to assign meaning to being a member of a group, such as “Administrators”, “WiFi Users”, or “Internal App Users”.
- POSIX Groups: POSIX groups reflect the attributes necessary to create a group on a Linux or OS X server, including a POSIX compliant group name, group ID, and users who are members of the group. It is this type of object that allows you to cause LDAP client operating systems, such as Linux, to be able to determine operating system-level group membership.
Because LDAP’s directory is freeform, many applications have to ask you for the path where they can find each of the above types of objects (normally they only ask about Users and Groups, however). This is referred to as the Search Base, the place where the client application expects to search and find that type of object. Some applications expect a single search base (which is similar to how Active Directory is structured), while others know that User and Group objects may be in different directory locations.
Your answer to this question for either Users or Groups is the same:
ou=Users,o=<organizationId>,dc=jumpcloud,dc=com
This is because that DN includes all three object types. That value is what you’ll use for your search base, or base DN value.
When an application requests user unique identifier, you’ll generally want to use:
uid
A uid value, followed by the rest of the search base, will uniquely identify any user object in your JumpCloud LDAP directory, for example:
uid=jdoe,ou=Users,o=<organizationId>,dc=jumpcloud,dc=com,
When an application requests group unique identifier, you’ll generally use:
cn
“CN” stands for Common Name, and is the way a JumpCloud group is identified. For example:
cn=WiFi Users,ou=Users,o=<organizationId>,dc=jumpcloud,dc=com
This will uniquely identify the “WiFi Users” group in your JumpCloud LDAP directory.
Filtering
Because it is up to the client application to bring meaning to the LDAP directory, the client chooses which groups are meaningful to it. For example, if you’re running OpenVPN and using JumpCloud to authenticate user logins, you may only want to allow members of the “Chicago OpenVPN Users” group to be able to login using the VPN.
To do that, you’ll need to filter your set of users down to only those that are members of “Chicago OpenVPN Users”, and to do that, we’ll need to use a filter.
Groups-First Filter
In some cases, an application will allow you to specify a group DN and will be able to query all the members of that group. In these cases, you’ll simply provide the DN of your group, such as:
cn=Chicago OpenVPN Users,ou=Users,o=<organizationId>,dc=jumpcloud,dc=com
The application can then query all the member attributes of the “Chicago OpenVPN Users” group, which will look like:
member: uid=jdoe,ou=Users,o=<organizationId>,dc=jumpcloud,dc=com
member: uid=pembroke,ou=Users,o=<organizationId>,dc=jumpcloud,dc=com
member: uid=jody,ou=Users,o=<organizationId>,dc=jumpcloud,dc=com
The application can then use this list to determine whether to allow the to login, or not.
MemberOf Filter
Since the JumpCloud LDAP service supports the memberOf overlay, each user also contains the list of all the groups of which it is a member.
In this case, the search is a bit different, you’ll specify a filter that returns only the members of a particular group. A filter for our OpenVPN group would look like:
(&(objectType=inetOrgPerson)(memberOf=cn=Chicago OpenVPN Users,ou=Users,o=<organizationId>,dc=jumpcloud,dc=com))
This filter says, return me all the objects with an objectType of inetOrgPerson (a User), that are also a member of the “Chicago OpenVPN Users” group.
Other Filters
Filters can be very complex, but this filter is one that is very common. You can also build filters that search for only a specific group. For example:
(&(objectClass=groupOfNames)(cn=Admins))
This filter will return only group objects named “Admins”. For more details around using filters, please see our knowledge base article on the topic.
Need More Help?
These are the most common settings that you’ll need when connecting your application to JumpCloud’s hosted LDAP solution. Of course, there may be more nuances depending upon the application, but this should get you started. If you need further help, drop our support line a note and they would be happy to help.