Options for Securing an eDirectory Tree

1 Likes
over 4 years ago
From time to time, questions arise as to how to secure eDirectory, often based on somebody's idea of a "security scan" throwing out nasty sounding messages. A while back, I looked in to what could be done, and what the benefits and costs are of modifying some of the default permissions.

Change: Remove [Public] Read Rights



By default, when a new eDirectory tree is installed, several attributes are set up in the schema as being readable by the [Public] pseudo-object. This allows any connection, whether authenticated or not, to read any data stored in these attributes. This may be helpful for general purpose use, but is insecure. In order to provide for good data security, these rights should be removed.



Attributes that are normally flagged for Public Read that need to be secured are:





  • Email Address




  • Surname




  • Given Name




  • Initials




  • Generational Qualifier




  • Internet Email Address




There are other attributes in the schema with the X-NDS_PUBLIC_READ flag. Those should be left alone.


To remove [Public] read rights, use ldapmodify with an LDIF file:


ldapmodify -x -H ldaps://192.168.1.1 -D cn=admin,o=oname -w password -f remove-public-read.ldif




dn: cn=schema
changetype: modify
delete: attributeTypes
attributeTypes: ( 2.16.840.1.113719.1.1.4.1.22 NAME 'eMailAddress' SYNTAX 2.16
.840.1.113719.1.1.5.1.14{64512} X-NDS_NAME 'EMail Address' X-NDS_PUBLIC_READ
'1' X-NDS_NONREMOVABLE '1' )
-
add: attributeTypes
attributeTypes: ( 2.16.840.1.113719.1.1.4.1.22 NAME 'eMailAddress' SYNTAX 2.16
.840.1.113719.1.1.5.1.14{64512} X-NDS_NAME 'EMail Address' X-NDS_NONREMOVABLE '1' )
-
delete: attributeTypes
attributeTypes: ( 2.5.4.4 NAME ( 'sn' 'surname' ) SYNTAX 1.3.6.1.4.1.1466.115.
121.1.15{64} X-NDS_NAME 'Surname' X-NDS_LOWER_BOUND '1' X-NDS_PUBLIC_READ '1'
X-NDS_NONREMOVABLE '1' )
-
add: attributeTypes
attributeTypes: ( 2.5.4.4 NAME ( 'sn' 'surname' ) SYNTAX 1.3.6.1.4.1.1466.115.
121.1.15{64} X-NDS_NAME 'Surname' X-NDS_LOWER_BOUND '1' X-NDS_NONREMOVABLE '1' )
-
delete: attributeTypes
attributeTypes: ( 2.5.4.42 NAME 'givenName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.
15{32} X-NDS_NAME 'Given Name' X-NDS_LOWER_BOUND '1' X-NDS_PUBLIC_READ '1' X-
NDS_NONREMOVABLE '1' )
-
add: attributeTypes
attributeTypes: ( 2.5.4.42 NAME 'givenName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.
15{32} X-NDS_NAME 'Given Name' X-NDS_LOWER_BOUND '1' X-NDS_NONREMOVABLE '1' )
-
delete: attributeTypes
attributeTypes: ( 2.5.4.43 NAME 'initials' SYNTAX 1.3.6.1.4.1.1466.115.121.1.1
5{8} X-NDS_NAME 'Initials' X-NDS_LOWER_BOUND '1' X-NDS_PUBLIC_READ '1' X-NDS_
NONREMOVABLE '1' )
-
add: attributeTypes
attributeTypes: ( 2.5.4.43 NAME 'initials' SYNTAX 1.3.6.1.4.1.1466.115.121.1.1
5{8} X-NDS_NAME 'Initials' X-NDS_LOWER_BOUND '1' X-NDS_NONREMOVABLE '1' )
-
delete: attributeTypes
attributeTypes: ( 2.5.4.44 NAME 'generationQualifier' SYNTAX 1.3.6.1.4.1.1466.
115.121.1.15{8} SINGLE-VALUE X-NDS_NAME 'Generational Qualifier' X-NDS_LOWER_
BOUND '1' X-NDS_PUBLIC_READ '1' X-NDS_NONREMOVABLE '1' )
-
add: attributeTypes
attributeTypes: ( 2.5.4.44 NAME 'generationQualifier' SYNTAX 1.3.6.1.4.1.1466.
115.121.1.15{8} SINGLE-VALUE X-NDS_NAME 'Generational Qualifier' X-NDS_LOWER_
BOUND '1' X-NDS_NONREMOVABLE '1' )
-
delete: attributeTypes
attributeTypes: ( 0.9.2342.19200300.100.1.3 NAME 'mail' SYNTAX 1.3.6.1.4.1.146
6.115.121.1.15{64512} X-NDS_NAME 'Internet EMail Address' X-NDS_PUBLIC_READ '
1' )
-
add: attributeTypes
attributeTypes: ( 0.9.2342.19200300.100.1.3 NAME 'mail' SYNTAX 1.3.6.1.4.1.146
6.115.121.1.15{64512} X-NDS_NAME 'Internet EMail Address' )

Reference: Novell TID # 10083520


Change: Remove Default ACL Template


Each object class in the schema can have one or more ACLs applied to newly created objects via a Template mechanism. The default ACL template is stored in the schema as part of the object class definition. As with the [Public] object rights applied by default, this may be helpful in a general purpose directory, but requires further security here.


To change the Default ACL Template, it is necessary to export the current schema definition, find the parts that require changing, and import a modified definition to change them.


Export the current schema to a file:


ldapsearch -x -H ldaps://192.168.1.1 -D "cn=admin,o=oname" -w password -b "cn=schema" -s base > schema.ldif


Then edit the schema.ldif file and find the definition for the User object class (inetOrgPerson). It will start with something like:


objectClasses: ( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson'


The object class definition spans several lines, and ends where the next “objectClassess:” line begins. The inetOrgPerson definition will look something like:




objectClasses: ( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' SUP organization
alPerson STRUCTURAL MAY ( groupMembership $ ndsHomeDirectory $ loginAllowedTi
meMap $ loginDisabled $ loginExpirationTime $ loginGraceLimit $ loginGraceRem
aining $ loginIntruderAddress $ loginIntruderAttempts $ loginIntruderResetTim
e $ loginMaximumSimultaneous $ loginScript $ loginTime $ networkAddressRestri
ction $ networkAddress $ passwordsUsed $ passwordAllowChange $ passwordExpira
tionInterval $ passwordExpirationTime $ passwordMinimumLength $ passwordRequi
red $ passwordUniqueRequired $ printJobConfiguration $ privateKey $ Profile $
publicKey $ securityEquals $ accountBalance $ allowUnlimitedCredit $ minimum
AccountBalance $ messageServer $ Language $ UID $ lockedByIntruder $ serverHo
lds $ lastLoginTime $ typeCreatorMap $ higherPrivileges $ printerControl $ se
curityFlags $ profileMembership $ Timezone $ sASServiceDN $ sASSecretStore $
sASSecretStoreKey $ sASSecretStoreData $ sASPKIStoreKeys $ userCertificate $
nDSPKIUserCertificateInfo $ nDSPKIKeystore $ rADIUSActiveConnections $ rADIUS
AttributeLists $ rADIUSConcurrentLimit $ rADIUSConnectionHistory $ rADIUSDefa
ultProfile $ rADIUSDialAccessGroup $ rADIUSEnableDialAccess $ rADIUSPassword
$ rADIUSServiceList $ audio $ businessCategory $ carLicense $ departmentNumbe
r $ employeeNumber $ employeeType $ givenName $ homePhone $ homePostalAddress
$ initials $ jpegPhoto $ labeledUri $ mail $ manager $ mobile $ pager $ ldap
Photo $ preferredLanguage $ roomNumber $ secretary $ uid $ userSMIMECertifica
te $ x500UniqueIdentifier $ displayName $ userPKCS12 ) X-NDS_NAME 'User' X-ND
S_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES ( '2#subtree#[
Self]#[All Attributes Rights]' '6#entry#[Self]#loginScript' '1#subtree#[Root
Template]#[Entry Rights]' '2#entry#[Public]#messageServer' '2#entry#[Root Tem
plate]#groupMembership' '6#entry#[Self]#printJobConfiguration' '2#entry#[Root
Template]#networkAddress') )

Though depending on the actual tree being modified, it may be different from the example here. The important parts are at the end of the block, in the section for X-NDS_ACL_TEMPLATES(...).


Edit out the remainder of the file, leaving just the objectClasses definition for inetOrgPerson. Use this to create a new LDIF file containing the definition desired, like:




dn: cn=schema
changetype: modify
delete: objectClasses
objectClasses: ( 2.16.840.1.113730.3.2.2 )
-
add: objectClasses
objectClasses: ( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' SUP organization
alPerson STRUCTURAL MAY ( groupMembership $ ndsHomeDirectory $ loginAllowedTi
meMap $ loginDisabled $ loginExpirationTime $ loginGraceLimit $ loginGraceRem
aining $ loginIntruderAddress $ loginIntruderAttempts $ loginIntruderResetTim
e $ loginMaximumSimultaneous $ loginScript $ loginTime $ networkAddressRestri
ction $ networkAddress $ passwordsUsed $ passwordAllowChange $ passwordExpira
tionInterval $ passwordExpirationTime $ passwordMinimumLength $ passwordRequi
red $ passwordUniqueRequired $ printJobConfiguration $ privateKey $ Profile $
publicKey $ securityEquals $ accountBalance $ allowUnlimitedCredit $ minimum
AccountBalance $ messageServer $ Language $ UID $ lockedByIntruder $ serverHo
lds $ lastLoginTime $ typeCreatorMap $ higherPrivileges $ printerControl $ se
curityFlags $ profileMembership $ Timezone $ sASServiceDN $ sASSecretStore $
sASSecretStoreKey $ sASSecretStoreData $ sASPKIStoreKeys $ userCertificate $
nDSPKIUserCertificateInfo $ nDSPKIKeystore $ rADIUSActiveConnections $ rADIUS
AttributeLists $ rADIUSConcurrentLimit $ rADIUSConnectionHistory $ rADIUSDefa
ultProfile $ rADIUSDialAccessGroup $ rADIUSEnableDialAccess $ rADIUSPassword
$ rADIUSServiceList $ audio $ businessCategory $ carLicense $ departmentNumbe
r $ employeeNumber $ employeeType $ givenName $ homePhone $ homePostalAddress
$ initials $ jpegPhoto $ labeledUri $ mail $ manager $ mobile $ pager $ ldap
Photo $ preferredLanguage $ roomNumber $ secretary $ uid $ userSMIMECertifica
te $ x500UniqueIdentifier $ displayName $ userPKCS12 ) X-NDS_NAME 'User' X-ND
S_NOT_CONTAINER '1' X-NDS_NONREMOVABLE '1' X-NDS_ACL_TEMPLATES (
'1#subtree#[Root Template]#[Entry Rights]' ) )

by removing the non-desired ACLs from the X-NDS_ACL_TEMPLATES section. Leave everything else in the inetOrgPerson definition alone. Once the file has been created, apply this change to the schema:


ldapmodify -x -H ldaps://192.168.1.1 -D cn=admin,o=oname -w password -f schema.ldif


Reference: Novell TID #10092621


Change: Remove Default ACLs from Existing Objects


If any objects have been created prior to the Default ACL Template being modified, then these objects will have ACLs that they should not. They can be removed with another LDIF import file. Examine a representative selction of objects to determine what ACLs are present:




dn: cn=User1,ou=Users,o=oname
acl: 2#subtree#cn=User1,ou=Users,o=oname#[All Attributes Rights]
acl: 6#entry#cn=User1,ou=Users,o=oname#loginScript
acl: 2#entry#[Public]#messageServer
acl: 2#entry#[Root]#groupMembership
acl: 6#entry#cn=User1,ou=Users,o=oname#printJobConfiguration
acl: 2#entry#[Root]#networkAddress

Then create an LDIF file to remove them:




dn: cn=User1,ou=Users,o=oname
changetype: modify
delete: acl
acl: 2#subtree#cn=User1,ou=Users,o=oname#[All Attributes Rights]
dn: cn=User1,ou=Users,o=oname
changetype: modify
delete: acl
acl: 6#entry#cn=User1,ou=Users,o=oname#loginScript
dn: cn=User1,ou=Users,o=oname
changetype: modify
delete: acl
acl: 2#entry#[Public]#lmessageServer
dn: cn=User1,ou=Users,o=oname
changetype: modify
delete: acl
acl: 2#entry#[Root]#groupMembership
dn: cn=User1,ou=Users,o=oname
changetype: modify
delete: acl
acl: 6#entry#cn=User1,ou=Users,o=oname#printJobConfiguration
dn: cn=User1,ou=Users,o=oname
changetype: modify
delete: acl
acl: 2#entry#[Root]#networkAddress

Export the current object DNS to a file:


ldapsearch -x -LLL -H ldaps://192.168.1.1 -D cn=admin,o=oname -w password -b ou=users,o=oname '(objectclass=user)' dn > object-dns


Then pass the DNS through an awk script:


awk -f remove-acls.awk < object-dns > remove-acls.ldif


using an AWK script like:




{
print $0
print "changetype: modify"
print "delete: acl"
print "acl: 2#subtree#" $2 "#[All Attributes Rights]"
print ""
print $0
print "changetype: modify"
print "delete: acl"
print "acl: 6#entry#" $2 "#loginScript"
print ""
print $0
print "changetype: modify"
print "delete: acl"
print "acl: 2#entry#[Public]#messageServer"
print ""
print $0
print "changetype: modify"
print "delete: acl"
print "acl: 2#entry#[Root]#groupMembership"
print ""
print $0
print "changetype: modify"
print "delete: acl"
print "acl: 6#entry#" $2 "#printJobConfiguration"
print ""
print $0
print "changetype: modify"
print "delete: acl"
print "acl: 2#entry#[Root]#networkAddress"
print ""
}

Then import the changes:


ldapmodify -x -H ldaps://192.168.1.1 -D cn=admin,o=oname -w password -c -f remove-acls.ldif


Change: eDirectory ACLs


Once the object ACLs have been cleaned up and the defaults taken care of, assign the rights actually necessary for this eDirectory tree to be useful. A good understanding of rights and inheritance is necessary here, as well as a reasonable understanding of the purpose this tree is supposed to be built for.


[Public]


By default, the [Public] object has [Entry Rights] of Browse/Inherit at the root of the tree. This allows unauthenticated connections to see the object names (DNs) of other objects. This is required in most cases.


[This]


By default, the [This] object has minimal rights at the root of the tree. Use the [This] object to define the rights that an object that is logged in should have to itself. This will vary depending on the purpose of the tree. Add whatever is necessary here, and remove whatever is not needed.


[O=Org]


By default, the O=Org object has minimal rights at the O=Org level of the tree. Use the O=Org object to define the rights that an object that is logged in should have to other objects in the tree.


[OU=OrgUnit]


By default, the OU=OrgUnit object has rights to the Login Script and Print Job Configuration attributes of itself. This can be ignored.


Change: LDAP Server Configuration


LDAP Server


Find the LDAP Server object in the tree. For a given server, the LDAP Server object is used to control settings for the LDAP server running on that server.


Changes:


General / LDAP Server General





  • Check the “Disable TCP Port” box – This blocks access to the insecure LDAP port (389).




SSL/TLS Configuration / LDAP Server SSL or TLS Configuration





  • Change the Server Certificate from the default SSL CertificateDNS to a newly created SSL Certificate LDAP




Restrictions





  • Change Search Entry Limit from 0 to 500




  • Change Search Time Limit from 0 to 3600




LDAP Group


Find the LDAP Group object. This is specified in the LDAP Server object.


Changes:


General / LDAP Group General





  • Establish the “Proxy Username:” object here – This will be used to define what rights an anonymous bind is given.




  • Check the “Require TLS for simple binds with password” box – This forces all authenticated binds to be secure.




LDAP Proxy User


The LDAP Proxy user defines the rights granted to anonymous (no password supplied) binds. Create a User object and give it the desired rights for anonymous binds. Then specify it in the LDAP Group object used for this server.


Reference: Novell TID #7000340


Certificates


Create a new NDSPKI:Key Material Object (KMO) called “SSL Certificate LDAP”.


Set the expiration to the maximum date.


Use this certificate object in the LDAP Server configuration instead of the default “SSL CertificateDNS” object created by the installation.

Labels:

How To-Best Practice
Comment List
Anonymous
Related Discussions
Recommended