CTS-2333 (Unix/Linux Networking) Project #6
LDAP

 

Due: by the start of class on the date shown on the syllabus

Background:

LDAP Is a popular, standard way to access information and includes excellent security and fine-grained access control.  It is usually used to provide fast search and lookup of “directories” (a type of “database”), including DNS data, calendar data, and data about people.  It is often used as a central data store to support single sign-on, replacing other stores such as the traditional Unix account files.

LDAP organizes data as “objects” (or other terms such as entries, records, etc.).  Each object is a collection of named attributes, each with zero, one, or more values.  Attributes may be optional or required; it depends on the type of the object.  (An object can have multiple types; it must contain all the attributes required of any of them, and can contain any optional attributes defined by any of the types.)  The types are defined in one or more schema files.

The objects in a directory or organized in a hierarchy.  There is a “root” object at the top, which is a container type (that is, it can contain other objects).  Originally the top-most objects represented a geographical location: a country object at the top, then (possibly) a state object, then an organization object.  The lower part of the tree consists of organizational units (“ou”) which contain the actual (useful) data objects.  For example it is common (and the default with OpenLDAP) to keep objects about users in an ou named “People”.

A problem of this organization is the difficulty of having globally unique names for an organization's records.  The modern trend is to name the top-most branches after an organization's DNS name, using domainComponent (or “dc”) for each part of the DNS name.

Every object has a unique name based on the names of each object from the root to the object, analogous to the absolute pathname of a file in a file system.  This is called the object's distinguished name, which is of the form “type=name,type=name,...”, where “type” is the object's type and “name” is the (common) name of that object, and a comma is used as a separator.

For an organization with the DNS name of kaos.coop, you should name the top objects in the hierarchy “dc=kaos,dc=coop,ou=People”.

OpenLDAP server is configured by editing the file slapd.conf.  The file starts with directives that apply to all directories served by this daemon.  This is followed by one or more database definitions, each starting with a “database” directive.  The client tools that ship with OpenLDAP have default settings (so you don't have to enter them on the command line every time) in the file /etc/openldap/ldap.conf.  This file should not be confused with the /etc/*ldap.conf, which are used for PAM and the name service switch.

Security of LDAP

LDAP supports powerful security but by default uses plain-text passwords (not safe to send across a network, but safe enough for localhost use).  To use these with the OpenLDAP client tools, you must include the option “-x” on the command line.  In addition, a special user name with “cn=Manager” in the base of the directory (in our case, “dc=kaos,dc=coop”) is the only user with write access to the directory.  This user is called the “rootdn”.

All other users have read-only access.  To make changes to the directory, you must connect as the rootdn (or some other user to whom you have granted access) using the option “-D cn=Manager,dc=kaos,dc=coop”.  You will also need to supply “-W” so the command will prompt you to enter the matching password.

You can change the defaults by adding access directives of the form:

access to what
   by who list-of-rights
   ...

Each access directive ends with an implicit “by * none”, so if you don't explicitly allow access to someone to something it will be denied.  In addition, there is a “first match” rule, so you must list the more specific access directives before the more general ones.

Once you add any “access” directives, the default read-only acces by all users (except the rootdn) doesn't apply.  Instead, there is an implicit rule that denies all access.  So if you want to add back the read access, you must add this directive at the end:

access to * by * read

Requirements:

In this project you will setup the OpenLDAP server, use it to serve as a single sign-on directory for your server.  Then you will run some experiments and fix the access permissions.

Perform the following tasks and answer the following questions:

Part I — Basic server setup:

  1. Make sure you have the correct (and updated packages installed via yum: openldap-clients, openldap-servers, openldap, nss_ldap, migrationtools, and gq.
  2. Create the directory “/var/lib/ldap/kaos.coop” to hold the data files.  This directory must be mode “0700” (that is, accessible by owner only), with owner “ldap” and group “ldap”.
  3. Create an empty file named “DB_CONFIG” in that directory with mode “0600” (that is, read-write by owner only), with owner “ldap” and group “ldap”.
  4. Next set up the system log daemon to save LDAP messages to a separate log file, “ldap.log”.  LDAP messages are sent to “local4” facility.  Reload or restart the system log daemon and check the system log; if any errors result, fix and repeat.  What changes did you make to /etc/rsyslog.conf (the syslog version used by Fedora)?
  5. Now add a configuration file to /etc/logrotate.d to rotate your new log file.  What is the name and contents of your new logrotate.d file?
  6. With the preliminaries out of the way, it is time to configure the LDAP server and client tools.  OpenLDAP no longer ships with a sample slapd.conf file.  The newer versions use a folder hierarchy containing many .ldif files.  You can edit those files, or use the sample slapd.conf file I provide.  (See the hints section below for the link).  Note if both the directory and the file are present, slapd will use the directory!  You should rename the “slapd.d” directory.  Then the server will fall back on using the slapd.conf file.

    It is easy to convert the old-style file to the new-style directories, if you wish (not required):

    mv slapd.d/ slapd.d-ORIG
    mkdir slapd.d
    chown ldap.ldap slapd.d
    slaptest -f slapd.conf -F slapd.d/
    chown -R ldap.ldap slapd.d/

    If this works, you can remove the slapd.conf file.

    Edit /etc/openldap/slapd.conf and make the following changes:

    1. Add the following to log at least these items (you can add others):
      loglevel conns filter config
    2. Change the suffix from
      "dc=my-domain,dc=com"
      to
      "dc=kaos,dc=coop"
    3. Change the rootdn (the privileged LDAP administrator) to:
      "cn=Manager,dc=kaos,dc=coop"
    4. Generate a new SHA password for the rootdn using the slappasswd command.  DO NOT provide your new password on the command line.  What exact command did you use?  Use the resulting password hash as the value for rootpw.
    5. Set the directory to the pathname of the directory created earlier.
  7. Test you configuration by running the command slaptest -uv.  If any errors, fix and repeat.
  8. Now you need to configure the client tool defaults.  Edit the file “/etc/openldap/ldap.conf” and change the BASE to the correct value for our organization.  What changes did you make to this file?
  9. Start the server, then examine the LDAP log file.  What errors or warning messages did you get? 
  10. If no errors, make sure the LDAP daemon will start automatically at boot time.  How did you do this?
  11. Test your service by running some searches (of course, there isn't any data yet):
    ldapsearch -xW -D 'cn=Manager,dc=kaos,dc=coop' -b cn=monitor
    ldapsearch -x

    Were the results what you expected?

    If this doesn't work, what security service(s) might be blocking access?  Verify they all allow access.  Remember to check log files if you encounter unknown problems.

Part II — Migrate existing user data:

  1. Create a new user account, to be used for testing:
     useradd -c "LDAP User" -m luser
     passwd luser
  2. Test your new account, by logging in as luser.  (You can use a virtual terminal for this, or try “ssh luser@localhost”.)
  3. OpenLDAP comes with some Perl scripts that can be used to convert your user files to the appropriate “LDIF” files, suitable for importing into your LDAP server.  In Fedora these are in a separate package named “migrationtools”, and are documented in the file /usr/share/doc/migrationtools*/migration-tools.txt.  Change your directory to where the scripts were installed, /usr/share/migrationtools/.  These tools all have pointless defaults that must be changed.  You can over-ride the defaults (set in the file “migrate_common.ph”) by exporting the following environment variables, then run as root the following commands:
    export LDAP_EXTENDED_SCHEMA="1"
    export LDAP_DEFAULT_MAIL_DOMAIN="kaos.coop"
    export LDAP_BASEDN="dc=kaos,dc=coop"
    
    ./migrate_base.pl > ~/base.ldif
    ./migrate_group.pl /etc/group ~/group.ldif
    ./migrate_passwd.pl /etc/passwd ~/passwd.ldif
  4. Change directories to root's HOME.  Use the command ldapadd to import the ldif files.  The order you add them matters.  You can't add an object to some container, if that container object hasn't been created yet!  Check the man page for this command to see what options you might need to use.  What are the exact commands you used to add the three files?  (Hint: You don't have SASL configured, so you will need to use the “-x” option.  Since only the “rootdn” user has “write” privileges initially, you must connect to (called “binding with”) the server using that distinguished name.  Since that user has a password set, you will need the option to have the command prompt you for a password.)
  5. If all goes well you should be able to search for some data.  Run the following commands:
    ldapsearch -x uid=luser
    ldapsearch -x uid=luser mail

    Explain the results of each command.

  6. Completely remove user luser from the password files, with the command “userdel luser”.  Note this doesn't affect the LDAP data, and leaves the user's home directory.
  7. Verify that you can no longer log in as user “luser”.
  8. Now configure your system to use the LDAP server to authenticate users.  First make copies of the files that may be changed: /etc/*ldap.conf, /etc/nsswitch.conf, and all of /etc/pam.d/.

    Next run the GUI tool system-config-authentication.  Make sure to configure both for “User Information” and “Authentication” to use LDAP.  You will also need to configure LDAP to use the correct organization name (“kaos.coop”).  For security reasons, this tool won't let you authenticate using plain-text passwords over a network.  Rather than do this correctly and security, pretend to use LDAPS in the tool, and aftwards, edit each file modified by this tool by replacing “ldaps://” with “ldap://”.  The screen for Fedora 15 looks like this:

    a screen-shot of the system-config-authentication window

    Note: make sure you also set the password crypt mechanism to “sha512” (it may default to “md5”).  This change should be seen in all the *ldap.conf files.

    What files were changed by this tool?  What was changed (if anything) in the files /etc/ldap.conf and /nsswitch.conf?  What was changed (if anything) in the PAM configuration files?  Which files (if any) did you have to edit, to change the scheme from “ldaps://” to “ldap://”?

    With modern Fedora, the name service switch (nsswitch.conf) file no longer directly needs to use LDAP.  Instead it uses “sss”, for System Security Services, for both PAM and nsswitch.  This in turn uses a daemon “sssd”.  Make sure this daemon is running!

    If you make any changes to your configuration, or add new users, or even simply update a password, daemons such as sssd and nscd must be restarted, to flush their caches.  For testing purposes, I recommend you don't run nscd.

  9. Now it's time for the big test: login as user luser.  If that works, you are using single sign-on!  Assuming this works, what security changes would you need to make to allow other hosts to use your new LDAP server?  (Just in general; you don't need to list specific file changes.)
  10. Configure your second host to use LDAP the same way you just did for your first host.  (Don't install an LDAP server on the second host, just make it use the server on the first host.)  You may need to open firewall holes (including TCP Wrappers).  You will also need to create a home directory for luser.  Now on the second host, confirm you can log in as luser.  (In reality, you would also use NFS to remotely mount users' home directories, but we will skip that for this project.)

Part III — Configure access controls:

  1. Logged in as luser, try to change your password using the passwd command.  I bet this didn't work!  Now try this search:
    ldapsearch -x uid=root userPassword

    You have now read the hashed password for root!

  2. The reason is we have not configured any access controls to the data.  The default allows any user “read” access, but not “write” access.  What we want is to allow similar access as to what was granted by the shadow suite: any attributes from the passwd or group files can be read by anyone, root can read or write attributes from the shadow file, and all other users can only authenticate using the userPassword attribute, or change their own password.

    In addition to these access controls, you can define others.  also you can define other security parameters so that passwords are never sent from an LDAP client to the server.  A complete security setup is beyond the scope of this assignment.

  3. Add the following access controls to your slapd.conf file, in either the general area or in the directory-specific area of the file:
    # Restrict access to shadow attributes:
    access to dn.children="ou=People,dc=kaos,dc=coop"
      attrs=userPassword,shadowLastChange,shadowMax,shadowWarning
        by self write
        by dn.exact="uid=root,ou=People,dc=kaos,dc=coop" write
        by * auth
    
    # Root has write access to everything else too (others have read):
    access to *
        by dn.exact="uid=root,ou=People,dc=kaos,dc=coop" write
        by * read
  4. Run the slaptest -v command and make sure there are no errors.  Then restart the LDAP daemon.
  5. Now log in as luser again, and change the password using the passwd command.  If this works, log out and become root.  Change luser's password using the command passwd luserWhat happened?
  6. Normally it is sufficient to be root, to change someone's password.  However the simple access rules we are using means that root is being “mapped” to the user with write privileges, cn=Manager,dc=kaos,dc=coop.  and that user requires a password.  Try changing the luser password as root again, and this time supply the correct password.

Hints:

View sample configuration and LDIF data files.  For each configuration file I have provided the before version (file-ORIG), the result after changes (file), and a diff listing (file.diff).

To be turned in:

A copy of your relevant system journal entries, and the answers to the questions asked above.  You can send as email to (preferred).  If email is a problem for some reason, you may turn in a hard-copy.  In this case the pages should be readable, dated, and stapled together.  Your name should appear on the first page.

Please see your syllabus for more information about submitting projects.