Directory Sync with idM


#1

Hi everyone,

Is is possible to add users (via Directory Sync) from RedHat idM (essentially FreeIPA)?

I have a team member who has completed the first 2 steps in Directory Sync (Directory Settings and DUO Authentication Proxy) but no groups are available in step 3 (Choose Groups). Instead we see “Note: 79 groups can’t be shown. Please upgrade your Duo Authentication Proxy to show all groups.”

We have the latest version of Duo Authentication Proxy (v2.7.0) installed and the debug log shows successful LDAP STARTTLS connections to our idM server with groups successfully returned.


#2

We have some very specific prerequisites for syncing any OpenLDAP type directory (i.e., an LDAP directory that isn’t Active Directory).

Copied from https://duo.com/docs/ldapsync#prerequisites:

  • Synced groups must have the groupOfNames object class.
  • Synced groups must list their members by DN (directoryName) via themember attribute.
  • Synced groups must have a cn attribute, used as the Duo group name after import.
  • Synced users must have the organizationalPerson object class.

Does RedHat idM support these requirements?

What is the next LDAP search operation after you see a list of groups returned in the Authentication Proxy debug log?


#3

Hi Kristina,

I’m using the default idM settings and I think RedHat idM supports those requirements. Full disclosure, I could be misinterpreting the ldapsearch output below for a test user and test group.

ldapsearch results for the developers group:

SASL/GSSAPI authentication started
SASL username: admin@CORP.TEST.LAB
SASL SSF: 56
SASL data security layer installed.
dn: cn=developers,cn=groups,cn=accounts,dc=corp,dc=test,dc=lab
member: uid=testuser,cn=users,cn=accounts,dc=corp,dc=test,dc=lab        <--- members listed by member attribute
member: uid=testuser1,cn=users,cn=accounts,dc=corp,dc=test,dc=lab        <--- members listed by member attribute
objectClass: top
objectClass: groupofnames        <--- groupOfNames object class
objectClass: nestedgroup
objectClass: ipausergroup
objectClass: ipaobject
objectClass: posixgroup
cn: developers        <--- cn attribute used as Duo group name after import
ipaUniqueID: *****REDACTED*****
gidNumber: 400001

ldapsearch results for the user “testuser”:

SASL/GSSAPI authentication started
SASL username: admin@CORP.TEST.LAB
SASL SSF: 56
SASL data security layer installed.
dn: uid=testuser,cn=users,cn=accounts,dc=corp,dc=test,dc=lab
krbLastAdminUnlock: 20180213122820Z
krbLoginFailedCount: 0
krbLastFailedAuth: 20180213122633Z
telephoneNumber: 1234567890
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=corp,dc=test,dc=lab
memberOf: cn=developers,cn=groups,cn=accounts,dc=corp,dc=test,dc=lab
memberOf: cn=test_user_group1,cn=groups,cn=accounts,dc=corp,dc=test,dc=lab
mobile: 1234567890
ipaUserAuthType: password
krbPasswordExpiration: 20180510203423Z
krbExtraData:: *****REDACTED*****
krbTicketFlags: 128
krbLastPwdChange: 20180209203423Z
employeeType: Staff
mepManagedEntry: cn=testuser,cn=groups,cn=accounts,dc=corp,dc=test,dc=lab
displayName: Test User
uid: testuser
krbCanonicalName: testuser@CORP.TEST.LAB
objectClass: top
objectClass: person
objectClass: organizationalperson        <--- organizationalPerson object class
objectClass: inetorgperson
objectClass: inetuser
objectClass: posixaccount
objectClass: krbprincipalaux
objectClass: krbticketpolicyaux
objectClass: ipaobject
objectClass: ipasshuser
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
objectClass: ipauserauthtypeclass
loginShell: /bin/sh
initials: TU
gecos: Test User
sn: User
homeDirectory: /home/testuser
mail: testuser@corp.test.lab
krbPrincipalName: testuser@CORP.TEST.LAB
givenName: Test
cn: Test User
ipaUniqueID: *****REDACTED*****
uidNumber: 400004
gidNumber: 400004

After the groups are returned, the Authentication Proxy debug log shows a LDAPSearchResultDone message. Snippet of the redacted debug log follows:

2018-02-12T21:27:06+0000 [-] Duo Security Authentication Proxy 2.7.0 - Init Complete
2018-02-12T21:27:06+0000 [-] DRPC Disconnected: no rpc server
2018-02-12T21:27:06+0000 [-] (Re)connecting to service...
2018-02-12T21:27:06+0000 [-] http GET to https://******REDACTED******.duosecurity.com:443/auth/v2/ping: 
2018-02-12T21:27:06+0000 [duoauthproxy.lib.http._DuoHTTPClientFactory#info] Starting factory <_DuoHTTPClientFactory: https://******REDACTED******.duosecurity.com:443/auth/v2/ping>
2018-02-12T21:27:06+0000 [HTTPPageGetter (TLSMemoryBIOProtocol),client] http POST to https://******REDACTED******.duosecurity.com:443/: 
2018-02-12T21:27:06+0000 [duoauthproxy.lib.http._DuoHTTPClientFactory#info] Starting factory <_DuoHTTPClientFactory: https://******REDACTED******.duosecurity.com:443/>
2018-02-12T21:27:06+0000 [duoauthproxy.lib.http._DuoHTTPClientFactory#info] Stopping factory <_DuoHTTPClientFactory: https://******REDACTED******.duosecurity.com:443/auth/v2/ping>
2018-02-12T21:27:18+0000 [duoauthproxy.lib.ldap.client.ADClientFactory#info] Starting factory <duoauthproxy.lib.ldap.client.ADClientFactory object at 0x3262b90>
2018-02-12T21:27:18+0000 [-] C->S LDAPMessage(id=1, value=LDAPStartTLSRequest())
2018-02-12T21:27:19+0000 [ADClientProtocol,client] C<-S LDAPMessage(id=1L, value=LDAPExtendedResponse(resultCode=0L, errorMessage='Start TLS request accepted.Server willing to negotiate SSL.'))
2018-02-12T21:27:19+0000 [ADClientProtocol,client] C->S LDAPMessage(id=2, value=LDAPBindRequest(version=3, dn='uid=duoauthproxysvcuser,cn=users,cn=compat,dc=corp,dc=test,dc=lab', auth='*****', sasl=False))
2018-02-12T21:27:19+0000 [ADClientProtocol,client] C<-S LDAPMessage(id=2L, value=LDAPBindResponse(resultCode=0L))
2018-02-12T21:27:19+0000 [ADClientProtocol,client] C->S LDAPMessage(id=3, value=LDAPSearchRequest(baseObject=u'dc=corp,dc=test,dc=lab', scope=2, derefAliases=0, sizeLimit=0, timeLimit=0, typesOnly=0, filter=LDAPFilter_equalityMatch(attributeDesc=LDAPAttributeDescription(value='objectclass'), assertionValue=LDAPAssertionValue(value='groupofnames')), attributes=['entrydn', 'entryuuid', 'cn']))
2018-02-12T21:27:19+0000 [ADClientProtocol,client] C<-S LDAPMessage(id=3L, value=LDAPSearchResultEntry(objectName='cn=ipausers,cn=groups,cn=accounts,dc=corp,dc=test,dc=lab', attributes=[('cn', ['ipausers'])])
2018-02-12T21:27:19+0000 [ADClientProtocol,client] C<-S LDAPMessage(id=3L, value=LDAPSearchResultEntry(objectName='cn=developers,cn=groups,cn=accounts,dc=corp,dc=test,dc=lab', attributes=[('cn', ['developers'])])
2018-02-12T21:27:19+0000 [ADClientProtocol,client] C<-S LDAPMessage(id=3L, value=LDAPSearchResultDone(resultCode=0L))
2018-02-12T21:27:19+0000 [duoauthproxy.lib.ldap.client.ADClientFactory#info] Stopping factory <duoauthproxy.lib.ldap.client.ADClientFactory object at 0x3262b90>

#4

The LDAP search for group objects is looking for the attributes attributes=['entrydn', 'entryuuid', 'cn'], but the LDAP search result only returns the cn for those groups. It turns out we require all three of those attributes in the search result to present a group for selection in the sync config.

The “Please upgrade your Duo Authentication Proxy to show all groups” message is misleading, and I’ve filed this for correction to a more helpful message. I’ll also add this additional requirement to the OpenLDAP sync page.

Do the entrydn and entryuuid attributes for groups exist in your directory? Unfortunately, we don’t let you specify the source attributes for group searches at this time like you do for users when configuring the sync. I’ve filed this as an enhancement request as well.


#5

This makes sense and explains why LDAP authentications via Duo Access Gateway work but the directory sync functionality using the Authentication Proxy does not.

I ran a few ldapsearch queries to check on the attributes for the developers group… The exact queries were:

  1. ldapsearch -LLL -Y GSSAPI -b dc=corp,dc=test,dc=lab developers
  2. ldapsearch -LLL -Y GSSAPI -b dc=corp,dc=test,dc=lab developers +

entryDN exists in the directory as an operational attribute (only visible from ldapsearch #2 above). I ran a quick test with ldaptor code from StackOverflow and ldaptor appears to treat operational attributes differently from “normal” attributes. That may explain why I’m not seeing the entrydn in the authentication proxy log.

The entryuuid attribute does not appear to be available within the directory. idM/FreeIPA (both use 389ds as the underlying directory server) have a nsUniqueId operational attribute that seems to fulfill the same role.

It looks like other vendors integrating with idM have run into the same issue with entryuuid missing. I’ll keep digging.


#6

@DuoKristina

Is there an additional requirement that synced users must have the memberOf attribute?


#7

Yes, they do. It looked like your ldapsearch output for testuser did include memberof.