FeministWiki:LDAP Schema: Difference between revisions

(Created page with "The member database of the FeministWiki is stored via LDAP. The basic structure looks like this: dc=feministwiki,dc=org ou=members - cn=''username'' objectCl...")
 
No edit summary
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
The member database of the FeministWiki is stored via LDAP.  The basic structure looks like this:
The member database of the FeministWiki is stored via LDAP.  This page explains some details about the setup.
 
=== Structure ===
 
The basic structure looks like this:


  dc=feministwiki,dc=org
  dc=feministwiki,dc=org
Line 34: Line 38:
* The <code>fwRecoveryMail</code> field may hold a mail address that will be used for password reset requests.  It's different from the primary mail address because that one may be the member's FeministWiki address, which they can't access if they've lost their password.
* The <code>fwRecoveryMail</code> field may hold a mail address that will be used for password reset requests.  It's different from the primary mail address because that one may be the member's FeministWiki address, which they can't access if they've lost their password.
* The <code>manager</code> contains the DN (distinguished name) of the member who added the member.  It may be empty for special member accounts like "Administrator" or the "Deleted" pseudo-account.
* The <code>manager</code> contains the DN (distinguished name) of the member who added the member.  It may be empty for special member accounts like "Administrator" or the "Deleted" pseudo-account.
=== Tips on the usage of ldap commands ===
Commands such as ldapsearch, ldapmodify, etc. require authentication.  The correct method depends on whether you want to interact with the configuration database found in {{C|/etc/ldap/slapd.d}}, or the actual data database found in {{C|/var/lib/ldap}}.
For configuration, use {{C|-Y external -H ldapi://}} to connect directly with root permissions, so no actual LDAP domain login is needed.
For data, use {{C|-xy ~/pwd/ldap}} to use the LDAP domain admin password.  The file {{C|~/.ldaprc}} should contain {{C|BINDDN cn=admin,dc=feministwiki,dc=org}} so you don't have to specify the domain admin explicitly every time.
=== Read-only user ===
For security purposes, it's a good idea to have a "read-only" user for LDAP read operations, instead of using the admin for everything.
# Add read-only user
ldapadd -xy ~/pwd/ldap <<EOF
dn: cn=readonly,dc=feministwiki,dc=org
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: readonly
description: Read-only user
userPassword: $(cat ~/pwd/ldap-readonly)
EOF
No fiddling with access control is needed, since read-only access is the default.


=== Custom objectClass ===
=== Custom objectClass ===


The following LDIF statement may be passed to 'ldapadd' to create the <code>fwMember</code> object class.
The following command creates the <code>fwMember</code> object class.


  # Entry to add, with e.g. 'ldapadd' tool
  ldapadd -Y external -H ldapi:// <<EOF
  dn: cn=feministwiki,cn=schema,cn=config
  dn: cn=feministwiki,cn=schema,cn=config
  objectClass: olcSchemaConfig
  objectClass: olcSchemaConfig
Line 54: Line 82:
     STRUCTURAL
     STRUCTURAL
     MAY ( fwRecoveryMail ) )
     MAY ( fwRecoveryMail ) )
EOF


=== Attribute permissions ===
=== Attribute permissions ===


We want members to be able to change some of their own settings without requiring privilege escalation. Additionally, we want the "readonly" dummy user to be able to find users via the combination of their username and recovery mail address.  (The password reset mechanism uses this.) The following LDIF statement may be passed to 'ldapmodify' to make the necessary access control changes:
We want to make the following changes to the default LDAP permissions:
 
* Members should be able to change their own display name (<code>sn</code>) and e-mail address (<code>mail</code>).
* The read-only user should be able to find users via the combination of their username and recovery mail address (<code>fwRecoveryMail</code>), but not actually see their recovery mail addresses.  (The password reset mechanism uses this.)
* Members should not be able to see who a member was added by (the <code>manager</code> field).
 
The following command makes the necessary access control changes:


  # Modifications to be made, e.g. via 'ldapmodify'
  ldapmodify -Y external -H ldapi:// <<EOF
  dn: olcDatabase={1}mdb,cn=config
  dn: olcDatabase={1}mdb,cn=config
  changetype: modify
  changetype: modify
Line 65: Line 100:
  olcAccess: {2}to attrs=sn,mail by self write
  olcAccess: {2}to attrs=sn,mail by self write
  olcAccess: {3}to attrs=fwRecoveryMail by self write by dn.exact="cn=readonly,dc=feministwiki,dc=org" search
  olcAccess: {3}to attrs=fwRecoveryMail by self write by dn.exact="cn=readonly,dc=feministwiki,dc=org" search
  -
  olcAccess: {4}to attrs=manager by self read
EOF
 
Note that <code>olcAccess</code> entries are evaluated in order, and the first match takes effect.  This can affect performance.  In the statement above, we start inserting entries from index 2, because indexes 0 and 1 already have some meaningful default entries.


=== Password hashing ===
=== Password policy ===


To make sure passwords are stored with the <code>{SSHA}</code> scheme rather than plain text, the <code>ppolicy</code> "password policy overlay" is used.  ZYTRAX has a very nice book about LDAP which documents how to enable this: http://www.zytrax.com/books/ldap/ch6/ppolicy.html
To make sure passwords are stored with the <code>{SSHA}</code> scheme rather than plain text, the <code>ppolicy</code> "password policy overlay" is used.  ZYTRAX has a very nice book about LDAP which documents how to enable this: http://www.zytrax.com/books/ldap/ch6/ppolicy.html
Line 73: Line 111:
In short, the steps go as follows (these commands ''should'' work verbatim):
In short, the steps go as follows (these commands ''should'' work verbatim):


  # Add the ppolicy schema
  # Only needed on old versions of slapd, to add the ppolicy schema
  ldapadd -Y external -H ldapi:/// < /etc/ldap/schema/ppolicy.ldif
  #ldapadd -Y external -H ldapi:// < /etc/ldap/schema/ppolicy.ldif
   
   
  # Enable the ppolicy dynamic module
  # Enable the ppolicy dynamic module
  ldapmodify -Y external -H ldapi:/// <<EOF
  ldapmodify -Y external -H ldapi:// <<EOF
  dn: cn=module{0},cn=config
  dn: cn=module{0},cn=config
  changetype: modify
  changetype: modify
Line 85: Line 123:
   
   
  # Add the ppolicy overlay with olcPPolicyHashCleartext set to TRUE
  # Add the ppolicy overlay with olcPPolicyHashCleartext set to TRUE
  ldapadd -Y external -H ldapi:/// <<EOF
  ldapadd -Y external -H ldapi:// <<EOF
  dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
  dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
  objectClass: olcPPolicyConfig
  objectClass: olcPPolicyConfig
  olcOverlay: ppolicy
  olcOverlay: ppolicy
  olcPPolicyHashCleartext: TRUE
  olcPPolicyHashCleartext: TRUE
EOF
Further, <code>ppolicy</code> is used to enable brute-force protection.  For this, we need to add an entry of the object class <code>pwdPolicy</code> to the directory, add attributes related to brute-force protection, and then set it as the default password policy:
# Add an OU for password policies
ldapadd -xy ~/pwd/ldap <<EOF
dn: ou=pwdPolicies,dc=feministwiki,dc=org
objectClass: organizationalUnit
ou: pwdPolicies
EOF
# Add the pwdPolicy object
ldapadd -xy ~/pwd/ldap <<EOF
dn: cn=default,ou=pwdPolicies,dc=feministwiki,dc=org
objectClass: applicationProcess
objectClass: pwdPolicy
cn: default
pwdAttribute: userPassword
pwdLockout: TRUE
pwdLockoutDuration: 3600
pwdMaxFailure: 10
pwdFailureCountInterval: 3600
EOF
# Set it as the default password policy
ldapmodify -Y external -H ldapi:// <<EOF
dn: olcOverlay={0}ppolicy,olcDatabase={1}mdb,cn=config
changetype: modify
add: olcPPolicyDefault
olcPPolicyDefault: cn=default,ou=pwdPolicies,dc=feministwiki,dc=org
EOF
With these settings, ten consecutive authentication failures with a username will lock the account for an hour.  Login failures are also cleared after an hour.  This means it's possible to try ten passwords per hour during a brute-force attack, which won't get the attacker very far.
=== Time of last login ===
The <code>lastbind</code> module of OpenLDAP keeps track of when a user last logged in.
# Load the module
ldapmodify -Y external -H ldapi:// <<EOF
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: lastbind
EOF
# Enable the overlay
ldapadd -Y external -H ldapi:// <<EOF
dn: olcOverlay=lastbind,olcDatabase={1}mdb,cn=config
objectClass: olcLastBindConfig
olcOverlay: lastbind
olcLastBindPrecision: 60
  EOF
  EOF

Latest revision as of 00:49, 12 January 2024

The member database of the FeministWiki is stored via LDAP. This page explains some details about the setup.

Structure

The basic structure looks like this:

dc=feministwiki,dc=org
  ou=members
    - cn=username
      objectClass: fwMember
      cn: username
      uid: username
      sn: Display name
      userPassword: {SSHA}saltedhash
      mail: username@feministwiki.org
      fwRecoveryMail: user@example.org
    - cn=username2
      objectClass: fwMembe
      cn: username2
      uid: username2
      sn: Display name
      userPassword: {SSHA}saltedhash2
      mail: username2@feministwiki.org
      manager: cn=username,ou=members,dc=feministwiki,dc=org
    - ...
  ou=groups
    cn=members
    objectClass: groupOfNames
    cn: members
    member: username
    member: username2
    member: ...

Notes:

  • The cn (common name) and uid (user ID) fields both contain the username. This is because some software is preconfigured to look at uid, while most look at cn.
  • The sn (surname) field is used to hold a display name that may be different from the username. The field is filled with the username by default.
  • The mail field holds the primary mail address for communication with the member. It's filled with the FeministWiki mail address of the member by default, but can be changed freely.
  • The fwRecoveryMail field may hold a mail address that will be used for password reset requests. It's different from the primary mail address because that one may be the member's FeministWiki address, which they can't access if they've lost their password.
  • The manager contains the DN (distinguished name) of the member who added the member. It may be empty for special member accounts like "Administrator" or the "Deleted" pseudo-account.

Tips on the usage of ldap commands

Commands such as ldapsearch, ldapmodify, etc. require authentication. The correct method depends on whether you want to interact with the configuration database found in /etc/ldap/slapd.d, or the actual data database found in /var/lib/ldap.

For configuration, use -Y external -H ldapi:// to connect directly with root permissions, so no actual LDAP domain login is needed.

For data, use -xy ~/pwd/ldap to use the LDAP domain admin password. The file ~/.ldaprc should contain {{{1}}} so you don't have to specify the domain admin explicitly every time.

Read-only user

For security purposes, it's a good idea to have a "read-only" user for LDAP read operations, instead of using the admin for everything.

# Add read-only user
ldapadd -xy ~/pwd/ldap <<EOF
dn: cn=readonly,dc=feministwiki,dc=org
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: readonly
description: Read-only user
userPassword: $(cat ~/pwd/ldap-readonly)
EOF

No fiddling with access control is needed, since read-only access is the default.

Custom objectClass

The following command creates the fwMember object class.

ldapadd -Y external -H ldapi:// <<EOF
dn: cn=feministwiki,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: feministwiki
olcAttributeTypes: {0}( 1.3.6.1.4.1.42.2.27.99.1.1
   NAME 'fwRecoveryMail'
   DESC 'FeministWiki password recovery mail'
   EQUALITY caseIgnoreMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
olcObjectClasses: {1}( 1.3.6.1.4.1.42.2.27.99.2.1
   NAME 'fwMember'
   DESC 'FeministWiki member'
   SUP inetOrgPerson
   STRUCTURAL
   MAY ( fwRecoveryMail ) )
EOF

Attribute permissions

We want to make the following changes to the default LDAP permissions:

  • Members should be able to change their own display name (sn) and e-mail address (mail).
  • The read-only user should be able to find users via the combination of their username and recovery mail address (fwRecoveryMail), but not actually see their recovery mail addresses. (The password reset mechanism uses this.)
  • Members should not be able to see who a member was added by (the manager field).

The following command makes the necessary access control changes:

ldapmodify -Y external -H ldapi:// <<EOF
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {2}to attrs=sn,mail by self write
olcAccess: {3}to attrs=fwRecoveryMail by self write by dn.exact="cn=readonly,dc=feministwiki,dc=org" search
olcAccess: {4}to attrs=manager by self read
EOF

Note that olcAccess entries are evaluated in order, and the first match takes effect. This can affect performance. In the statement above, we start inserting entries from index 2, because indexes 0 and 1 already have some meaningful default entries.

Password policy

To make sure passwords are stored with the {SSHA} scheme rather than plain text, the ppolicy "password policy overlay" is used. ZYTRAX has a very nice book about LDAP which documents how to enable this: http://www.zytrax.com/books/ldap/ch6/ppolicy.html

In short, the steps go as follows (these commands should work verbatim):

# Only needed on old versions of slapd, to add the ppolicy schema
#ldapadd -Y external -H ldapi:// < /etc/ldap/schema/ppolicy.ldif

# Enable the ppolicy dynamic module
ldapmodify -Y external -H ldapi:// <<EOF
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: ppolicy
EOF

# Add the ppolicy overlay with olcPPolicyHashCleartext set to TRUE
ldapadd -Y external -H ldapi:// <<EOF
dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
objectClass: olcPPolicyConfig
olcOverlay: ppolicy
olcPPolicyHashCleartext: TRUE
EOF

Further, ppolicy is used to enable brute-force protection. For this, we need to add an entry of the object class pwdPolicy to the directory, add attributes related to brute-force protection, and then set it as the default password policy:

# Add an OU for password policies
ldapadd -xy ~/pwd/ldap <<EOF
dn: ou=pwdPolicies,dc=feministwiki,dc=org
objectClass: organizationalUnit
ou: pwdPolicies
EOF

# Add the pwdPolicy object
ldapadd -xy ~/pwd/ldap <<EOF
dn: cn=default,ou=pwdPolicies,dc=feministwiki,dc=org
objectClass: applicationProcess
objectClass: pwdPolicy
cn: default
pwdAttribute: userPassword
pwdLockout: TRUE
pwdLockoutDuration: 3600
pwdMaxFailure: 10
pwdFailureCountInterval: 3600
EOF

# Set it as the default password policy
ldapmodify -Y external -H ldapi:// <<EOF
dn: olcOverlay={0}ppolicy,olcDatabase={1}mdb,cn=config
changetype: modify
add: olcPPolicyDefault
olcPPolicyDefault: cn=default,ou=pwdPolicies,dc=feministwiki,dc=org
EOF

With these settings, ten consecutive authentication failures with a username will lock the account for an hour. Login failures are also cleared after an hour. This means it's possible to try ten passwords per hour during a brute-force attack, which won't get the attacker very far.

Time of last login

The lastbind module of OpenLDAP keeps track of when a user last logged in.

# Load the module
ldapmodify -Y external -H ldapi:// <<EOF
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: lastbind
EOF
# Enable the overlay
ldapadd -Y external -H ldapi:// <<EOF
dn: olcOverlay=lastbind,olcDatabase={1}mdb,cn=config
objectClass: olcLastBindConfig
olcOverlay: lastbind
olcLastBindPrecision: 60
EOF