FortiOS 6.0: LDAP Authentication with Nested AD Groups
If you want the story, ready this…otherwise you can skip to the solution below. :-)
I ran into an issue today while configuring a new FortiGate cluster running FortiOS 6.0 in an environment heavily utilizing nested AD groups (like many others). On an old unit running FortiOS 5.2, authentication with nested AD groups worked as expected. On the newer unit, authentication was failing every time unless I removed the group restriction. In the GUI at least, it looked like my unit running 6.0 was running the same config as my unit running 5.2.
After a bit of research, I ran across a blog or forum post referencing the
set search-type nested command for LDAP server config in FortiOS 5.2. That blew the cobwebs off some dark corner of my memory…yes…I do remember dealing with this before. Unfortunately, this command was no longer available in 6.0 (and might not be in 5.4 or 5.6…haven’t checked those versions). However, a quick look at the LDAP server config options showed a new
group-filter option. Hmmm…this looks promising.
group-filter option allows specifying a custom filter for identifying group membership. In the AD LDAP world, Microsoft implements custom object identifiers (OIDs) that can be used to extend LDAP query syntax (MS docs here). One of these custom OIDs,
LDAP_MATCHING_RULE_IN_CHAIN, provides “a special ‘extended’ match operator that walks the chain of ancestry in objects all the way to the root until it finds a match” (quoted from MS docs). In other words, we can use this to find all groups of which a user is a member, including nested groups. These OIDs are used in LDAP queries by specifying the numeric OID, in this case
1.2.840.1135184.108.40.2061. Turns out, the documentation on the FortiGate CLI for
set group-filter even shows examples using this OID:
fortigate (ldap-server) # set group-filter filter used for group matching. Here are some examples: (&(objectclass=group)(member=%u)) (&(objectclass=group)(member:1.2.840.1135220.127.116.111:=%u)) (&(objectclass=group)(member:1.2.840.113518.104.22.1681:=%u)(cn=*)) (&(objectcategory=group)(member:1.2.840.113522.214.171.1241:=%u))
While I couldn’t find any documentation stating that this was the case (in fact, I couldn’t find any documentation from Fortinet referencing the
group-filter option at all), the
%u at the end of the query is a variable that will be expanded to the Distinguished Name (DN) of the user attempting to authenticate.
With this in mind, the following sequence of commands will get authentication with nested AD group membership working in FortiOS 6.0 (assuming your LDAP server entry is already created):
config user ldap edit YOUR_LDAP_SERVER_NAME set group-filter (&(objectclass=group)(member:1.2.840.1135126.96.36.1991:=%u)) end
You’ll notice that the custom filter I used was straight from the CLI help. Once this was done, I was able to successfully authenticate using nested AD groups.
Of course, there are various other settings you’ll need to dial in to set up LDAP authentication the desired way in your environment, but these are well documented elsewhere and beyond the scope of this post. Also, if you have a huge environment with sprawling AD group membership (i.e., users are members of hundreds of groups), you may run into performance issues using
LDAP_MATCHING_RULE_IN_CHAIN to query for group membership. You do need to be running AD LDAP for this to work; the OID used is Microsoft-specific and isn’t available in other directories (to my knowledge, though there may be alternative methods).
Hope this is helpful!