As I’ve mentioned before, OpenDJ follows a pretty wide open security model. That’s unfortunate, but not fatal. Here are my notes on locking down an OpenDJ directory.
To begin with, both Active Directory and Oracle’s old OID (now replaced by its own OpenDS clone, OUD) follow the same philosophy of basically allowing read, search and compare on everything by everyone. The main difference with Active Directory is that by default it requires authentication to any access at all.
The iPlanet/Sun/Netscape directories that form the basis for Red Hat/389 Directory took the opposite approach. In keeping with least privilege principles everyone (except fro the cn=Directory Manager root user) starts off without any access at all. Access is granted via access control instructions (aci) that must be added to the directory. The sample directory configuration did include some basic, and relatively open, aci entries but its use was optional.
The following discussion only relates to access controls, not privilege controls. Privileges are a separate topic that have been treated elsewhere on this blog.
By default OpenDJ contains a global aci for “anonymous” read access that is actually a deny rule providing everyone with read, search and compare rights over the entire directory. Only a certain select few attributes like userPassword are excluded by this rule. It can be found at “cn=Access Control Handler, cn=config”:
ds-cfg-global-aci: (targetattr!="userPassword||authPassword||changes||changeNumb er||changeType||changeTime||targetDN||newRDN||newSuperior||deleteOldRDN||target EntryUUID||changeInitiatorsName||changeLogCookie||includedAttributes")(version 3.0; acl "Anonymous read access"; allow (read,search,compare) userdn="ldap:///a nyone";)
Rather than have an aneurysm over this, consider the following advice to make things a bit more survivable.
First, modify the aforementioned aci so that it becomes a grant rather than a deny rule as follows:
ds-cfg-global-aci: (targetattr="entrydn")(version 3.0; acl "Anonymous read acces s"; allow (read,search,compare) userdn="ldap:///anyone";)
This will give unauthenticated users the right to see very little other than the DSE Root entry and the schema. That’s OK, in fact it’s about as locked down as you’re going to get because further restrictions (like removing the aci completely) will result in fatal errors being thrown by most LDAP search tools. This is because they almost all check the schema and DSE Root before proceeding. If they can’t get to those, they give up.
The final step is to begin building out your root access controls for various categories of users. This can be as simple or complicated as you want. If you’re not interested in anything other than administrators and applications accessing the directory, you can probably get by with the following 3 sample rules:
dn: dc=example,dc=com aci: (targetattr = "*") (target = "ldap:///dc=example,dc=com") (version 3.0;acl "Directory Administrators control over root";allow (all,proxy)(groupdn ="ldap: ///cn=Directory Administrators,dc=example,dc=com");) aci: (targetattr = "objectclass || cn || ou") (target = "ldap:///dc=example,dc= com") (version3.0;acl "Authenticated users access to root";allow (read,search, compare) (userdn = "ldap:///all");) aci: (targetattr = "*") (target = "ldap:///ou=People,dc=example,dc=com") (versi on3.0;acl "Applications access to People";allow (read,search, compare)(groupdn = "ldap:///cn=Applications,ou=Groups,dc=example,dc=com");)
The first rule gives full control over the entire directory tree to the members of the Directory Administrators group. The second rule gives limited read access over the whole the directory tree to authenticated users (keyword “ldap:///all”). The third rule grants read access to all the attributes of entries under “ou=People”.
To put these rules into effect for a particular application, you would add the entry dn used by the application to bind to the directory to the “cn=Applications” group. Under normal circumstances the list of attributes applications would be allowed to see is going to be more restricted, like “uid || sn || givenname || displayname || mail || title || o || telephonenumber || mobile || street || l || st || postalcode || c”. You get the idea. Treat setting up access controls as you would configuring a firewall and you should be able to avoid getting fired when there’s a security breach somewhere on your company network.
While the more secure proposal described above will secure your directory data, be sure you understand its impact on all your directory users, particularly applications.
For example, say you have a container “ou=Applications,dc=example,dc=com” that holds application configuration data. If you want the members of your “cn=Applications” group to be able to read more than objectclass, cn and ou you will need to create a new rule to do that like:
aci: (targetattr = "*")(target = "ldap:///ou=Applications,dc=example,dc=com")( version3.0;acl "Applications access to Applications";allow (read,search, comp are)(groupdn = "ldap:///cn=Applications,ou=Groups,dc=example,dc=com");)