This section discusses the overall architecture of the major components and how they interact. This is necessarily high level and the idea is to provide a context for the more detailed discussion of each component that is discussed below. The major components of the system are MIT Kerberos and OpenLDAP. These were chosen because they were both open source, widely deployed, and are under active development. At the core of the system is MIT's Kerberos secret key network authentication system. This system was designed to provide single sign-on in a potentially hostile academic environment and is widely supported on Mac, PC, and Linux desktops. The key idea behind Kerberos is the idea that a trusted third party can provide mutual authentication between clients and servers without passing passwords over the network. The way this works is that the trusted third party generates a special token (called a ticket) and encrypts the ticket with the password for the user or service (called a principal). If the user or application can decrypt it, then they have the proper password and have been correctly authenticated. The initial step in the process is for the client to obtain a Ticket Granting Ticket (TGT) which provides for the initial authentication. The TGT is an encrypted credential that can be used to request service tickets from the Kerberos server, which is acting as the trusted third party. The service tickets are encrypted in the service principal's password as well as the client's. The client can then decrypt the resulting ticket and present it to the service. If the service can decrypt it, then it can trust the client because only the client could have gotten the ticket. This is a simplification of the actual algorithm, which includes a number of features to defend against man-in-the-middle attacks, network snooping, etc. A good concise reference that describes the Kerberos protocol can be found in Designing an Authentication System: a Dialogue in Four Scenes by Bill Bryant or The Moron's Guide to Kerberos by Brian Tung.
From the above discussion, some of the components of Kerberos are clear. There must be a server that is available on the network to destribute the tickets, there must be a data store of information about principals and their associated keys, and there must be some secure means of synchronizing the keys stored by the server and stored by the service (or in the user's memory). Less obvious is that Kerberos requires all of the clocks on the client, server, and service to be synchronized. This requirement comes from one of the approaches Kerberos uses to defeat network interception attacks. Another obvious requirement is for tools to maintain the Kerberos repository, which might be the same as whatever is used to synchronize keys.
High availability is provided by both Kerberos and LDAP through a replication process. While the details of the process differ, both technologies provide means to replicate all or selected data to other nodes, which can provide the functionality in the event of a primary server outage. The replication technologies employed by both Kerberos and LDAP are not dependent on highly available servers. In the case of Kerberos, the client libraries support a list of Kerberos servers, and will failover to the next server in the list if the first one is unavailable. In the case of LDAP, the recommended approach is to use round-robin DNS to cycle between the multiple LDAP servers.
The overall system architecture is shown in Figure 1. As can be seen in the figure, the underlying core is the authentication functionality provided by Kerberos. Kerberos depends on a number of important technologies such as NTP, DNS, etc., but does not depend on any of the other components in CGLAUTH. Kerberos maintains its own database of principals and keys, and does not rely on either the system nor the LDAP repositories for information during normal operations. Note however, that during the initial configuration and "bootstrap" of the Kerberos repository, local account information was used to set up user principals.
Figure 1. CGLAUTH High-Level Architecture
Kerberos provides the main authentication layer in the CGLAUTH system, but it is not the only authentication technology. For login services to socrates, our main server, CGLAUTH will attempt to authenticate the user using Kerberos first. If that does not succeed, CGLAUTH will fallback to the standard Tru64 UNIX SIA mechanism. This approach is also taken for access to secure web services provided on socrates, which also acts as our primary web server platform. The fallback approach should is a temporary, transitional mechanism, particularly for web services, however, there is no extreme urgency to deprecate it.
One additional authentication mechanism that should be mentioned are the passwords stored as part of our SAMBA implementation. At this point, due to the form of the one-way crypt utilized by Microsoft for their SMB implementation, SAMBA is not compatible with Kerberos or any other plug-in technology in the absence of a Windows 2000 domain controller. As a result a separate password repository must be used. A future version of SAMBA will support Kerberos by providing support for Windows 2000 domain services as part of SAMBA itself, removing the need for a separate domain controller.
The next layer up in the system is the authorization and directory services technologies provided by LDAP. Note that while LDAP provides both of these services, they are logically separate, and are, in fact, implemented in separate parts (trees) within LDAP. LDAP is fundamentally a hierarchical database, providing a protocol for access, searching, and updating the information within the repository. CGLAUTH utilizes LDAP primarily to support Web authorization groups. Other information is stored within LDAP for access by E-mail and address book clients. LDAP is maintained in two ways: automated scripts, and manual updates. These are discussed in more detail below.
This section presents the details of each of the major components in the CGLAUTH system. As shown in Figure 1, the lowest layer is the authentication component, with the authorization component layered on top of that. The directory services/identity component is used mostly for user convenience at CGL, and is not currently a critical component, but is presented here in case general directory services becomes more important to the resource operation over time.
Kerberos forms the core of our authentication environment. We currently run Kerberos on two servers. The first is our main Tru64 cluster: socrates and we have implemented the Kerberos KDC and admin servers as cluster services using the Tru64 CAA capability. The master KDC service is called kdc and the admin server is called kadmin. These services are designed to failover to other nodes in the cluster with no loss in service. The failover is handled entirely by the Tru64 CAA mechanism. For the purposes of our kerberos implementation, we have provided an IP alias: kdc-1.cgl.ucsf.edu that points to socrates should we ever change hosts, or want to migrate these services off of the cluster.
The second host is cgl.ucsf.edu, our primary gateway, and it has an IP alias: kdc-2.cgl.ucsf.edu for the reaons stated above. This is our secondary server and is available to answer requests should our primary server fail for some reason. These servers are pointed to by the /etc/krb5.conf file, which is shown below.
[logging] default = FILE:/var/adm/krb5libs.log kdc = FILE:/var/adm/krb5kdc.log admin_server = FILE:/var/adm/kadmind.log [libdefaults] ticket_lifetime = 24000 default_realm = CGL.UCSF.EDU dns_lookup_realm = false dns_lookup_kdc = false noaddresses = true [realms] CGL.UCSF.EDU = { kdc = kdc-1.cgl.ucsf.edu:88 kdc = kdc-2.cgl.ucsf.edu:88 admin_server = kdc-1.cgl.ucsf.edu:749 default_domain = cgl.ucsf.edu } [domain_realm] .cgl.ucsf.edu = CGL.UCSF.EDU cgl.ucsf.edu = CGL.UCSF.EDU .compbio.ucsf.edu = CGL.UCSF.EDU compbio.ucsf.edu = CGL.UCSF.EDU
/etc/krb5.conf
The /etc/krb5.conf file shown above is used for Unix and Linux sytems. MacOS X uses a file with the exact same format, but has a different name and location: /Library/Preferences/edu.mit.Kerberos. Windows 2000 and Windows XP systems use a different mechanism to support a "kerberized" workstation.
The key components for all of the platforms are the presence of the two entries for kdc's and the default_realm of CGL.UCSF.EDU. It is important to include both kdc entries since the Kerberos libraries use these to manage the software failover process. In practice the constraint that there can be only one admin server should not be problematic for two reasons. First, the admin server is only used for password or account changes, which is not as time critical as authentication requests. Second, in our environment, the admin server is running on a cluster of computers and is relatively immune to a hardware failure on any single computer. In the event of a major problem on the cluster, the secondary, or slave server, can be "upgraded" to a master server with full admin functionality very easily.
From a Tru64 cluster standpoint, Kerberos runs as a pair of CAA services, kdc and kadmin. The scripts for these services are maintained in the standard CAA path: /var/cluster/caa/script/. There are no resource depencies and while we attempt to keep the kdc and kadmin services on the same node, that is certainly not required, and there are no node depencies in the implementation so these services can be run on any node within the cluster.
The database for both the master and slave nodes is stored in the standard path: /usr/local/var/krb5kdc/. The database itself is in the file principal and the configuration file kdc.conf is shown below.
[kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] CGL.UCSF.EDU = { kadmind_port = 749 } [logging] kdc = FILE:/var/adm/kdc.log admin_server = FILE:/var/adm/kadmind.log
/usr/local/var/krb5kdc/kdc.conf
Other key files in the /usr/local/var/krb5kdc/ directory are the access control list for the admin server (/usr/local/var/krb5kdc/kadm5.acl), the Kerberos keytab file for the admin services, and the script used to replicate the kerberos database, /usr/local/var/krb5kdc/propogate.
Replication for Kerberos is handled by a process that runs out of periodic, currently every ten minutes. Periodic just runs a small script, /usr/local/etc/periodic/scripts/kdc_prop that calls the propogate script. propogate starts by using a Kerberos utility program to create an encrypted dump of the database, then using a list of slave servers, it uses the kprop program to send the database to each of the slave servers. The slave servers must be running the kpropd service, and must be configured with the same master key as the master server. Once the new database is received on a slave, it replaces the database on the slave server.
One additional note about the ongoing operation of the Kerberos component. The Kerberos logs provide all of the information about authentication to all CGLAUTH components. As such they are both critical and grow very large. In order to rotate the logs, it is necessary to "convince" the processes to close and reopen their logs. This is handled by a weekly periodic script: 10.rotlog.system which actually stops and restarts the services using the CAA commands.
Kerberos forms the key component of the authentication portion of CGLAUTH but not all applications are Kerberized. The main server computing platform at CGL is our Tru64 Cluster, socrates, and seemless authentication on this platform is critical to our ongoing operation. Tru64 provides a security plug-in technology similar in intent to the Linux and Solaris PAM. In Tru64, the technology is known as the Secutiry Integration Architecture, or SIA. As an overall part of CGLAUTH, we have implemented an SIA module which delegates authentication to Kerberos. Because all system authentication goes through SIA (due to conflicting encryption algorithms, SAMBA does not use SIA or PAM), this provides "instant" integration with Kerberos. The SIA plugin is configured through the file: /etc/sia/matrix.conf. The previous CGL configuration relied heavily on the Tru64 "Enhanced" Security, which can be made to be C2 compliant. The configuration file is shown below, showing how the Kerberos plugin (KRB5) is added before the C2 component (OSFC2) so that Kerberos authentication would be attempted first, followed by the "normal" Tru64 Enhanced Security.
# # ***************************************************************** # * * # * Copyright 2002 Compaq Information Technologies Group, L.P. * # * * # * The software contained on this media is proprietary to * # * and embodies the confidential technology of Compaq * # * Computer Corporation. Possession, use, duplication or * # * dissemination of the software and media is authorized only * # * pursuant to a valid written license from Compaq Computer * # * Corporation. * # * * # * RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure * # * by the U.S. Government is subject to restrictions as set * # * forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, * # * or in FAR 52.227-19, as applicable. * # * * # ***************************************************************** # # HISTORY # # @(#)$RCSfile: CGLAUTH_Internal_Documentation.html,v $ $Revision: 1.1 $ (DEC) $Date: 2005/08/05 17:19:13 $ # # sia matrix configuration file (BSD only) siad_setpwent=(BSD,libc.so) siad_endpwent=(BSD,libc.so) siad_getpwent=(BSD,libc.so) siad_getpwnam=(BSD,libc.so) siad_getpwuid=(BSD,libc.so) siad_chg_finger=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so) siad_chg_password=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so) siad_chg_shell=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so) siad_chk_user=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so) siad_setgrent=(BSD,libc.so) siad_endgrent=(BSD,libc.so) siad_getgrent=(BSD,libc.so) siad_getgrnam=(BSD,libc.so) siad_getgrgid=(BSD,libc.so) siad_ses_init=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so) siad_chk_invoker=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so) siad_ses_authent=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so) siad_ses_suauthent=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so) siad_ses_reauthent=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so) siad_ses_estab=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so) siad_ses_launch=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so) siad_ses_release=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so) siad_init=(KRB5,/usr/shlib/libsiakrb5.so) (OSFC2,/usr/shlib/libsecurity.so)
/etc/sia/matrix.conf
In today's environment, the web has become a critical component of any IT system or infrastructure. An authentication environment must provide support for all of the various web activities which require user's to authenticate. Ideally, this support should provide a single-sign on capability, freeing users from having to reauthenticate to multiple web sites without constraining the rules for authorizing specific users access to specific web sites. The apache web software provides an extensive plug-in architecture that allows for a cascade of authentication and authorization modules to be traversed. For authentication (see the LDAP discussion for web authorization) Kerberos interaction is provided by mod_auth_kerb, an open-source module that supports Kerberos, GSS-API, as well as SPNEGO, the web single sign-on mechanism that was proposed by Microsoft and is supported by Internet Explorer, Firefox, and (more recently) Safari.
In addition to mod_auth_kerb CGL had already deployed a custom module that supports SIA for authentication. The SIA plug-in was used in a manner that combed authentication as well as authorization. Authorized users were placed in an htaccess file, and if a password was not included, the SIA plug-in would authenticate the user using the SIA api. If a password was included in the file, the user was authenticated against that password. If, on the other hand, a user's login id was not included in the file, they were not provided access. Enabling authentication and authorization is handled using the apache require valid-user primitive.
For the purposes of authenticating using Kerberos, authentication and authorization have been separated. Authentication is provided by Kerberos and authorization by LDAP. This implies that rather than using the presence or absence of a user's name in a file, authorization is handled by the require group primitive.
There are a number of configuration options to mod_auth_kerb that are set using the standard apache configuration approach. To simplify the use of both Kerberos and LDAP, a separate configuration directory has been created to all inclusion of the "standard" set of configuration options. The standard configuration file for Kerberos is shown below, and has been annotated to describe the function for each configuration option.
# Kerberos authentication AuthType Kerberos # Enables Kerberos authentication AuthName "Kerberos Login" # User prompt KrbAuthRealms CGL.UCSF.EDU # Kerberos Realm KrbSaveCredentials on # Save credentials for child processes KrbDelegateBasic off # Whether or not to delegate basic auth to another process KrbAuthoritative off # Whether or not we are the only mechanism KrbMethodNegotiate on # Whether or not to use SPNEGO and/or GSSAPI Krb5Keytab /etc/web.keytab # The location of the keytab file KrbStripRealm on # LOCAL: strip the realm of the principal name KrbTransition on # LOCAL: set up transition between SIA and Kerberos NoNegotiate Safari # LOCAL: disable negotiation for certain broken browsers
conf.d/Auth/krbAuth.conf
This file is included for each site or directory for which authentication is required. To make things simple, all of the authorization and authentication stanzas are combined into files appropriate to their function. To implement the "normal" authentication and authorization functions, a file conf.d/Auth/standardAuth.conf brings together all of the files and configuration stanzas into a single file, shown below.
# Standard way of doing authentication/authorization # Enable Kerbeos Include conf.d/Auth/krbauth.conf # Enable SIA Include conf.d/Auth/sia.conf # Enable SIA failover to Kerberos SIAAlternativeAuthType "Kerberos" # Enable LDAP Include conf.d/Auth/ldapauthz.conf # We want to make LDAP authoritative for groups AuthzLDAPAuthoritative On
conf.d/Auth/standardAuth.conf
A sample configuration stanza for an authenticated group of web pages is shown below. This configuration shows the use of standardAuth.conf to enable authentication and authorization. In this case, the web site allows any authenticated user.
<Location "/admin/chpass.py"> Include conf.d/Auth/standardAuth.conf require valid-user </Location>
Sample Authenticated Web Directory
The single sign-on capability of mod_auth_kerb is based on the use of an extention to the HTTP authentication protocol: WWW-Negotiate. This extension allows a browser to include information in the authentication header passed to the web server. If the underlying protocol is the Kerberos 5 version of the GSSAPI (Generic Security Services API) the information provided in the authentication header provides a service ticket that provides authentication credentials for a specific user. If the web server is able to decrypt that service ticket, then the user's authenticity is proven. In order for the server to be able to decrypt the service ticket provided by the browser it must have access to its private key. This key can be provided by either specifying it when the kerberos web service principal (HTTP/fqdn@CGL.UCSF.EDU) is created, and then providing it in a file or at startup, or by saving the key in a file. The latter mechanism allows us to create the service principals with a random key, which is much more difficult to guess. The file containing an encrypted version of the private key is called a keytab file (see the Krb5Keytab configuration parameter in the mod_auth_kerb configuration above).
There are three different approaches to determining exactly which fqdn to include in the ticket request. The browser could request a ticket for the fully resolved fqdn. For example, consider a web server that responds to URLs beginning with wwwtest.cgl.ucsf.edu. The address wwwtest.cgl.ucsf.edu is an alias for www.cgl.ucsf.edu, which resolves to IP addresses 169.230.22.3 and 169.230.22.49. The host that serves this web server is socrates.cgl.ucsf.edu, which also has IP addresses 169.230.22.3 and 169.230.22.49. Given this situation, the browser could send tickets for three possible principals:
The first principal is formed by taking the reported name of the web site. The second principal is formed by determining the canonical name of the web site by resolving any alias names. The third is formed by determining the canonical name of the web site by resolving any names to the underlying IP address and then by doing a reverse DNS lookup to determine the canonical name.
In practice, only two of these are ever used. Browsers running on Microsoft based operating systems will request and send a ticket for the second ticket. Browsers running on Unix (including Linux) or Macintosh operating systems will send the third. In order to provide single sign-on for Windows XP as well as Unix and Macintosh the web server much have keys for both principals within the keytab file. The original version of the mod_auth_kerb module only supported the third form of the web principal. As a result, Macintosh and Linux users were able to achieve web single sign-on, but Windows users were not. The current version has been modified to try both versions before failing.
One of the side benefits of utilizing Kerberos for authentication is that mod_auth_kerb includes the ability to save the user's credentials on the web server. In this manner, services that are themselves Kerberized are able to act on behalf of the user without requiring additional authentication steps or sophisticated priviledged applications. This can be used to greatly simplify the development of web-based applications and infrastructures.
Another important application that is in broad use within the CGL environment is SSH. SSH is used to provide access to all of our systems for both staff and users. Historically, staff has utilized SSH agents and pairs of public/private keys to allow single sign-on to systems. New versions of SSH include the capability to utilize GSSAPI to authenticate users. As in the discussion above reguarding web authentication, the SSH client must utilize the user's initial ticket (Ticket Granting Ticket, or TGT) in order to obtain a ticket for the service. In the case of utilizing either SSH or telnet to access a host, the service ticket must be for the principal: host/fqdn@CGL.UCSF.EDU. As before, the key for this principal must be stored on the server, traditionally in /etc/krb5.keytab. In order for GSSAPI authentication to be enabled the client and server must both support it, and it must be enabled in their respective configuration files, traditionally sshd_config and ssh_config. Sample configuration files are shown below.
# This is the sshd server system-wide configuration file. See sshd(8) # for more information. Port 22 Protocol 2,1 PidFile /var/run/sshd.pid HostKey /etc/openssh/ssh_host_key HostKey /etc/openssh/ssh_host_dsa_key ServerKeyBits 1024 LoginGraceTime 600 KeyRegenerationInterval 3600 PermitRootLogin yes # Don't read ~/.rhosts and ~/.shosts files IgnoreRhosts no StrictModes yes X11Forwarding yes X11DisplayOffset 10 PrintMotd yes KeepAlive yes # Logging SyslogFacility AUTH LogLevel INFO # For this to work you will also need host keys in /usr/local/etc/ssh_known_hosts RhostsRSAAuthentication yes RSAAuthentication yes # To disable tunneled clear text passwords, change to no here! PasswordAuthentication yes PermitEmptyPasswords no # Uncomment to disable s/key passwords ChallengeResponseAuthentication no # To change Kerberos options KerberosAuthentication yes KerberosOrLocalPasswd yes KerberosTicketCleanup yes # Enable single sign-on through GSSAPI GSSAPIAuthentication yes GSSAPICleanupCredentials yes Subsystem sftp /usr/local/libexec/sftp-server UsePrivilegeSeparation no
Sample SSH Server Configuration File
# This is ssh client systemwide configuration file. See ssh(1) for more # information. This file provides defaults for users, and the values can # be changed in per-user configuration files or on the command line. # Site-wide defaults for various options Host * ForwardX11 yes UsePrivilegedPort yes RhostsAuthentication yes RhostsRSAAuthentication yes RSAAuthentication yes PasswordAuthentication yes Protocol 2,1 StrictHostKeyChecking no GSSAPIDelegateCredentials yes GSSAPIAuthentication yes
Sample SSH Client Configuration File
All of the previous discussion has focused on the underlying architecture utilized to support authentication to CGL services. Of course, this all hinges on the users' ability to provide their username and Kerberos password in order to obtain their initial ticket. One of the first steps is for the user to set their Kerberos password. This represents a transitional challenge, since initially all users have SIA passwords, but not Kerberos passwords, yet the web page that changes passwords must necessarily be authenticated. The password change page ( https://www.cgl.ucsf.edu/admin/chpass.py) is configured to accept either Kerberos or SIA authentication. The user may then provide a new password, which is utilized to set both their Kerberos as well as their SAMBA password. If a SAMBA account does not exist for the user, it is created as part of this process. Of course, particularly in a single sign-on environment, the user is required to provide their current password again to avoid the circumstance where a user leaves their workstation and another person attempts to hijack their account by changing their password.
Figure 2. CGL Password Change Page
The major clients have already been discussed, but enabling single sign-on for the web browsers: Internet Explorer, Firefox, and Safari have not been presented here. The detailed instructions are included in the user's configuration instructions, which is available on line.
One other main category of application that has not been discussed are E-mail clients. While the IMAP server utilized by CGL supports single sign-on using GSSAPI, none of the available E-mail clients support it. This is something that we hope is rectified as new versions of the clients become available.
There are relatively few scripts that run for the specific support of the Kerberos authentication environment. The Kerberos logs ( /var/adm/krb5kdc.log and /var/adm/kadmind.log) are rotated as part of the normal log rotation procedures. The script to replicate the database between the master and slave Kerberos servers has already been discussed. The last of the scripts that run on an ongoing basis is the script that harvests information about user's successful and unsuccessful authentication attempts. This script reads the /var/adm/krb5kdc.log log and looks for entries of the form PREAUTH_FAILED and ISSUE. A PREAUTH_FAILED entry indicates that a user (or service) did not have the key necessary to decrypt an initial "preauthentication" challenge. This is an unsuccessful authentication attampt. The ISSUE entry indicates that the user or service did have the correct key and that authentication was successful. The script is run nightly and updates two databases that are keyed by the user's name: /usr/local/etc/kerbauth.db which includes the user's last successful authentication and /usr/local/etc/kerbnoauth.db, which has the user's last unsuccessful authentication.
The following procedures are provided as quick-reference guides only. It is assumed that operational administrators of the Kerberos environment are familiar with the management and operation of Kerberos enough to be able to perform any of thse operations with little assistance. Each of these procedures (except the last two) require Kerberos administrative priviledges.
As Kerberos forms the basis of our approach to authentication, LDAP forms the basis of our approach to authorization. The LDAP technology we use is the OpenLDAP server, which can be found at http://www.openldap.org. This open source package is extremely robust and forms the core of many commercial products and is explicitly supported by several vendors. This broad level of support and ongoing development by a significant community results in a variety of documented uses on the Internet, including serveral "HOWTO's". For our implementation, we have deployed the OpenLDAP servers on two hosts, similar to our deployment approach to Kerberos. Like Kerberos, our master server runs on socrates.cgl.ucsf.edu in a clustered environment under CAA control. The division of functionality is somewhat different in an LDAP environment than in a Kerberos environment. OpenLDAP provides two different servers, slapd, which answers all LDAP queries, including updates and new entries, and slurpd, which replicates data between the master server and the slave. All functions are controlled by the main configuration file, slapd.conf, which is shown below.
# # See slapd.conf(5) for details on configuration options. # This file should NOT be world readable. # loglevel 256 # # Load all schemas # include /usr/local/etc/openldap/schema/core.schema include /usr/local/etc/openldap/schema/misc.schema include /usr/local/etc/openldap/schema/cosine.schema include /usr/local/etc/openldap/schema/inetorgperson.schema include /usr/local/etc/openldap/schema/nis.schema include /usr/local/etc/openldap/schema/kerberosobject.schema include /usr/local/etc/openldap/schema/eduPerson.schema include /usr/local/etc/openldap/schema/ucsfPerson.schema include /usr/local/etc/openldap/schema/cglaccount.schema include /usr/local/etc/openldap/schema/mozilla.schema # Define global ACLs to disable default read access. # Global directives allow bind_v2 sizelimit 10000 pidfile /var/run/slapd.pid argsfile /var/run/slapd.args # Load dynamic backend modules: modulepath /usr/local/libexec/openldap moduleload pw-kerberos.so # Sample security restrictions # Require integrity protection (prevent hijacking) # Require 112-bit (3DES or better) encryption for updates # Require 63-bit encryption for simple bind # security ssf=1 update_ssf=56 simple_bind=56 defaultsearchbase dc=cgl,dc=ucsf,dc=edu # SASL directives # srvtab /etc/krb5.keytab sasl-realm CGL.UCSF.EDU sasl-host socrates.cgl.ucsf.edu # TLS directives TLSCertificateFile /usr/local/etc/openldap/slapd.crt/server.crt TLSCertificateKeyFile /usr/local/etc/openldap/slapd.key/server.key # # Provide ability for owners to edit their own group # access to dn.subtree="ou=Web Groups,ou=Groups,dc=cgl,dc=ucsf,dc=edu" attr=memberUid,owner,description,entry by dnattr=owner write by group="cn=LDAPAdmin,dc=cgl,dc=ucsf,dc=edu" write by * read # Access control for private fields in People # Should be readable by staff, writable by LDAPAdmin or the user access to dn.subtree="ou=UCSF,ou=People,dc=cgl,dc=ucsf,dc=edu" filter=(cglPrivate=TRUE) attr=homePhone,homeTelephoneNumber,mobile,mozillaHomeCountryName,mozillaHomeLocalityName,mozillaHomePostalCode,mozillaHomeState,mozillaHomeStreet,mozillaHomeStreet2,mozillaHomeUrl,mozillaNickname by dnattr=seeAlso write by group="cn=LDAPAdmin,dc=cgl,dc=ucsf,dc=edu" write by group="cn=staff,ou=UNIX Groups,ou=Groups,dc=cgl,dc=ucsf,dc=edu" read by users none by anonymous none # Access control for private fields in People that are set as non-Private access to dn.subtree="ou=UCSF,ou=People,dc=cgl,dc=ucsf,dc=edu" filter=(cglPrivate=FALSE) attr=homePhone,homeTelephoneNumber,mobile,mozillaHomeCountryName,mozillaHomeLocalityName,mozillaHomePostalCode,mozillaHomeState,mozillaHomeStreet,mozillaHomeStreet2,mozillaHomeUrl,mozillaNickname by dnattr=seeAlso write by group="cn=LDAPAdmin,dc=cgl,dc=ucsf,dc=edu" write by * read # Sample access control policy: # Root DSE: allow anyone to read it # Subschema (sub)entry DSE: allow anyone to read it # Other DSEs: # Allow self write access # Allow authenticated users read access # Allow anonymous users to authenticate # Directives needed to implement policy: access to dn.base="" by * read access to dn.base="cn=Subschema" by * read access to * by self write by group="cn=LDAPAdmin,dc=cgl,dc=ucsf,dc=edu" write by users read by anonymous read sasl-regexp uid=(.*),cn=cgl.ucsf.edu,cn=gssapi,cn=auth uid=$1,ou=Accounts,dc=cgl,dc=ucsf,dc=edu # # if no access controls are present, the default policy # allows anyone and everyone to read anything but restricts # updates to rootdn. (e.g., "access to * by * read") # # rootdn can always read and write EVERYTHING! ####################################################################### # ldbm database definitions ####################################################################### database bdb suffix "dc=cgl,dc=ucsf,dc=edu" rootdn "cn=Manager,dc=cgl,dc=ucsf,dc=edu" # Cleartext passwords, especially for the rootdn, should # be avoid. See slappasswd(8) and slapd.conf(5) for details. # Use of strong authentication encouraged. rootpw ************************ # The database directory MUST exist prior to running slapd AND # should only be accessible by the slapd and slap tools. # Mode 700 recommended. directory /usr/local/var/openldap-data mode 700 # Indices to maintain index uid pres,eq,approx,sub index cn,sn,mail pres,eq,approx,sub index eduPersonPrincipalName pres,eq,approx,sub index mailRoutingAddress pres,eq,approx index krbName pres,eq,approx index givenName pres,eq,sub index ucsfIDNumber pres,eq index objectClass eq index memberUID eq index gidNumber eq # # Tuning # cachesize 5000 # Checkpoint every 10K or 60 minutes checkpoint 10000 60 idlcachesize 5000 # Don't use memory mapped files shm_key 119 ####################################################################### # Set up database replication ####################################################################### replica uri=ldap://cgl.ucsf.edu:389 bindmethod=sasl saslmech=GSSAPI replogfile /usr/local/var/openldap-data/replog
CGL LDAP Configuration File (/usr/local/etc/openldap/slapd.conf)
The LDAP schema employed by CGL is designed to provide for Web Authorization requirements as well possible future uses for system level authorization, user identity information, and possibly system and printer information. Some of the more general directory services and identity management functions are discussed in more detail below. This section will focus on web authorization, which was our primary requirement for LDAP.
An LDAP repository is essentially a hierarchically organized data store whose contents are restricted by a set of object classes. Each object class defines a set of required and optional attributes, which themselves are defined to adhere to a specific data format or content. The hierarchical organization is not enforced by any specific data elements, rather, the Distinguished Name (DN) of a record in the database is hierarchically defined. For example, the DN for the web group sacs is: cn=sacs,ou=Web Groups,ou=Groups,dc=cgl,dc=ucsf,dc=edu. All elements contained within the CGL LDAP repository end with dc=cgl,dc=ucsf,dc=edu, which is the BASE of the server. The ou (Organizational Unit) elements after that define the actual hierarchy. The data in the Web Groups organizational unit is keyed by the cn (Common Name), which in this case is sacs.
Figure 3 - CGL LDAP Schema
The organization of the CGL LDAP repository is shown in Figure 3. For the purposes of web authorization, we are only concerned with the Web Groups and the Accounts organizational units. These are the two branches of the LDAP repository that are referenced by the apache web server to determine if an authenticated user is a member of an authorized web group. An example Accounts data entry is shown below. The primary source for this data is the /etc/passwd file on socrates, but it has been enhanced with a number of additional data items, including the ucsfIDNumber, which provides a link into the People branch of the repository.
# scooter, Accounts, cgl.ucsf.edu dn: uid=scooter,ou=Accounts,dc=cgl,dc=ucsf,dc=edu objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: inetLocalMailRecipient objectClass: posixAccount objectClass: cglAccount objectClass: kerberosSecurityObject # posixAccount attributes uid: scooter uidNumber: 170 gidNumber: 10 homeDirectory: /home/socr/a/scooter gecos: Scooter Morris loginShell: /usr/local/bin/bash # person attributes cn: Scooter Morris cn: John "Scooter" Morris givenName: Scooter sn: Morris # inetOrgPerson attributes mail: scooter@cgl.ucsf.edu # inetLocalMailRecipient attributes mailRoutingAddress: scooter@cgl.ucsf.edu mailHost: socrates.cgl.ucsf.edu # kerberosSecurityObject attributes krbName: scooter@CGL.UCSF.EDU # cglAccount attributes apple-authAuthority: ;Kerberosv5;;scooter@CGL.UCSF.EDU;CGL.UCSF.EDU; isLocked: FALSE irixHomeDirectory: /home/spin/scooter ucsfIDNumber: 023387608
Example Accounts Data Entry
Each of the objectClass attributes enables certain data attributes within the entry, which have been designated with comments in the example. As much as possible the Accounts objectClass attributes reflect standard and excepted usage for Unix systems. Two additional object classes have been added to support specific applications at CGL. The first is the kerberosSecurityObject, which provides the definition for the krbName attribute to provide a link to the Kerberos principal that goes along with this account. The second object class is the cglAccount object class, which provides the definitions for some attributes which we use specifically within the CGL environment. The first of these is apple-authAuthority, which is defined by Apple Computer and is used to provide information to MacOS X computers that indicates how this user should be authenticated. The second is isLocked which is used to signal that this account has been disabled for administrative purposes. The third is irixHomeDirectory which is used to indicate where this user's home directory should reside on our Irix workstations. The final addition is the ucsfIDNumber which provides a link into the People branch, as well as providing a key which can be used to link into the UCSF LDAP repository.
# sacs, Web Groups, Groups, cgl.ucsf.edu dn: cn=sacs,ou=Web Groups,ou=Groups,dc=cgl,dc=ucsf,dc=edu objectClass: top objectClass: posixGroup gidNumber: 101 cn: sacs owner: uid=johns,ou=Accounts,dc=cgl,dc=ucsf,dc=edu owner: uid=scooter,ou=Accounts,dc=cgl,dc=ucsf,dc=edu memberUid: tef memberUid: conrad memberUid: burling memberUid: gerlt memberUid: babbitt memberUid: ortiz memberUid: pett memberUid: bic memberUid: barondes memberUid: brc memberUid: ccwang memberUid: craik memberUid: zemin memberUid: jengel memberUid: faynboym memberUid: inada memberUid: goddard memberUid: yoshi memberUid: salter memberUid: scanlan memberUid: yizhang memberUid: pcaldera memberUid: valerie ... description: SACS Web Group
Example Web Groups Data Entry
The Web Groups branch is simple in comparison to the Accounts or People branches. The posixGroup object class provides the definition for all of the attributes. The key attributes are the owner attributes, and memberUid attributes, and the description attribute. The entry is keyed by the cn attribute, as discussed above. The owner attributes and the description attribute are used by the LDAP group maintenance web page discussed below. The memberUid attributes are used to determine group membership. The LDAP server utilizes the SASL plug-in security architecture to authenticate users. One of the mechanisms supported by SASL is the KRB5-GSSAPI mechanism. This allows LDAP to utilize Kerberos to authenticate, and enables single sign-on for LDAP modifications and priviledges.
As with authentication, web authorization is mediated in the apache server through an apache module, mod_authz_ldap. Authorization is enabled when a require group clause is included in the configuration for a specific group of web pages. The LDAP portion of the conf.d/Auth/standardAuth.conf file is shown below.
# LDAP Authorization AuthzLDAPAuthoritative off # Other authorization mechanisms are allowed AuthzLDAPServer "socrates.cgl.ucsf.edu" # The LDAP server AuthzLDAPMethod ldap # The method to use AuthzLDAPSetAuthorization user # How are we authorizing AuthzLDAPMapUserToAttr uid # What the user named is mapped to AuthzLDAPGroupBase "ou=Groups,dc=cgl,dc=ucsf,dc=edu" # The DN to get the group name AuthzLDAPGroupScope subtree # How to search for a group AuthzLDAPGroupKey "cn" # The group name AuthzLDAPMemberKey "memberUID" # How to find a member name
conf.d/Auth/ldapauthz.conf
To see how this might be used, an example set of web pages that require group membership is shown below.
<Location "/admin/nih-ar-admin.py"> Include conf.d/Auth/standardAuth.conf require group nih-ar-admin </Location>
Example Web Page Requiring Authorization
To facilitate management of Web authorization a web application was developed that allows users to easily add and delete users from Web Groups that they are designated as one of the owners. A special group, LDAPAdmin contains all of the CGL LDAP administrators, who are allowed to edit any group, including adding and deleting owners as well as creating new groups. This combination of capabilities allows CGL admininistrators to delegate maintenance of web authorization to the owners of the web site, which greatly reduces overhead. All access to LDAP through the web depends on delegated Kerberos credentials, so tickets must be proxiable on Linux and MacOS X and forwardable on Windows.
Figure 4 - CGL LDAP Group Maintenance Page
There are two periodic scripts that run that are related to LDAP. The first of these is the LDAP update script. This script is run from periodic every night. As can be seen from the script code below, the script gets credentials, then runs a python program that reads the unix group file, the unix password file, and pulls information from the UCSF LDAP repository. This information is used to create updated Account, People, and unixGroup files, which are then imported into the LDAP repository. The results of all of the imports are stored in /var/adm/ldapUpdate.log.
#! /bin/ksh -p # This script updates the cgl LDAP repository from the # passwd, group, and UCSF LDAP store # Get our identity /usr/local/bin/kinit -k -t /usr/local/etc/.rootkeys -p ldapbot # scribble in tmp cd /tmp # First, run the ldap script, this will output the files # account.ldif, people.ldif, unixGroup.ldif, and wAccount.ldif # At this point, we only use the first three /usr/local/etc/ldap_getPeople.py -t ldap # Now update the data rm -f /var/adm/ldapUpdate.log /usr/local/bin/ldapmodify -c -f account.ldif > /var/adm/ldapUpdate.log /usr/local/bin/ldapmodify -c -f people.ldif >> /var/adm/ldapUpdate.log /usr/local/bin/ldapmodify -c -f unixGroup.ldif >> /var/adm/ldapUpdate.log
/usr/local/etc/periodic/daily/05.ldapUpdate.local
The second important script is run directly from periodic to control the exact timing of its execution. This script stops both the slapd daemon (LDAP server) and the slurpd daemon (replication server) so that the log files can be reset, and the unused Berkeley DB database log files can be purged. This is important as these files have a tendency to build up over time, use a great deal of disk space.
#!/bin/sh PATH=/usr/bin:/usr/sbin export PATH host=`caa_stat slapd | grep STATE=ONLINE | awk '{ print $NF }'` caa_stop -f slapd # Not sure why this sometimes needs to be run twice rsh $host "/usr/local/BerkeleyDB.4.2/bin/db_recover -h /usr/local/var/openldap-data/" rsh $host "/usr/local/BerkeleyDB.4.2/bin/db_recover -h /usr/local/var/openldap-data/" rsh $host "/usr/local/BerkeleyDB.4.2/bin/db_archive -d -h /usr/local/var/openldap-data/" caa_start slapd -c $host caa_start slurpd -c $host
/usr/local/etc/periodic/scripts/ldap_clean
Maintenance of the ldap server is relatively straightforward. The CAA commands caa_start and caa_stop can usually be relied on to stop and start the server. In rare circumstances, the database may need to be recovered to get the server to restart cleanly. As can be seen in the ldap_clean script above, this is usually done automatically, but occaisionally, the db_recover command may need to be run manually. In this circumstance, it may fail once or twice before it succeeds. It should always be run on the node you intend to start the slapd daemon on. This is because the Berkeley DB package uses shared memory to communicate and actually encodes the node name as part of the memory partition. The db_recover resets this value and allows things to continue.
In addition to the database maintenance, there are a couple of tools that are very useful for managing and maintaining LDAP. The first of these is ldapsearch which can be used, not surprisingly, to search the LDAP repository. Any user can run ldapsearch, but they must have authenticated with Kerberos, or they will receive an error. LDAP administrators should all be in the LDAPAdmin group within LDAP. Members of this group have permission to modify any entry in LDAP. The second tools is ldapmodify which can be used to modify (or add) ldap entries. Some examples of using these tools are shown below:
OpenLDAP has been described in some detail above as the basis for Web authorization. The same OpenLDAP repository contains information about UNIX Accounts, UNIX Groups, and entries providing information about people such as their department, phone number, office address, etc. Taken together, the information about who people are and what they can do is considered "Identity Management". We've already described how web authorization is handled. Identity information comes from a variety of different source. An example, annotated entry is provided below.
# 023387608, UCSF, People, cgl.ucsf.edu dn: ucsfIDNumber=023387608,ou=UCSF,ou=People,dc=cgl,dc=ucsf,dc=edu ############################################################ # Provided as part of schema setup ############################################################ objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: eduPerson objectClass: ucsfPerson objectClass: mozillaAddressBookEntry ############################################################ # These entries are pulled from the UCSF LDAP # repository by searching for entries with # matching 'mail' and matching 'cn'. ############################################################ uid: jhmorris cn: Scooter Morris ou: Pharmaceutical Chemistry (552501) sn: Morris givenName: John ucsfIDNumber: 023387608 eduPersonNickname: Scooter eduPersonPrincipalName: John.H.Morris@ucsf.edu eduPersonAffiliation: staff eduPersonPrimaryAffiliation: staff eduPersonOrgUnitDN: ucsfDepartmentCode=552501,ou=departments,dc=ucsf,dc=edu eduPersonPrimaryOrgUnitDN: ucsfDepartmentCode=552501,ou=departments,dc=ucsf,dc=edu title: Programmer/Analyst V mail: scooter@cgl.ucsf.edu telephoneNumber: (415) 514-4406 ucsfCampusBox: 2240 ucsfBuildingCode: 3002 ucsfBuildingAddress: 600 16th street, San francisco, CA, 94143 ############################################################ # These entries are derived from the UCSF entries and # are provided to be consistent with applications that # are not likely to deal with 'ucsfBuildingAddress' in # a meaningful way ############################################################ displayName: Scooter Morris postalAddress: 600 16th St. street:: NjAwIDE2dGggU3RyZWV0IA== postOfficeBox:: NjAwIDE2dGggU3RyZWV0IA== o: University of California st: California l: San Francisco postalCode: 94143 ############################################################ # The next two entries are CGL-specific. The # first is a linking entry the provides information # about the account (or accounts) this user is # responsible for. The second entry has to # do with the visibility of private information ############################################################ seeAlso: uid=scooter,ou=Accounts,dc=cgl,dc=ucsf,dc=edu cglPrivate: FALSE ############################################################ # User-entered values, only visible if # cglPrivate is FALSE, or if this record # belongs to the requesting user ############################################################ facsimileTelephoneNumber: (415) 502-1755 roomNumber: N476A nsAIMid: scootermorris3 mozillaHomeStreet: xxxx SomeStreet St. mozillaHomeLocalityName: Pacifica mozillaHomePostalCode: 94044 mozillaHomeCountryName: US homePhone: (650) 555-0000 mobile: (650) 555-0000 mozillaHomeState: CA
Example person entry in LDAP
Most of this information results from a nightly script that executes the program /usr/local/etc/ldap_getPeople.py. This program reads information from /etc/passwd, /etc/group, and the UCSF LDAP repository to output three files:
The nightly update script mentioned above is shown below. This script is run out of periodic as part of the daily script execution.
#! /bin/ksh -p # This script updates the cgl LDAP repository from the # passwd, group, and UCSF LDAP store # Get our identity /usr/local/bin/kinit -k -t /usr/local/etc/.rootkeys -p ldapbot # scribble in tmp cd /tmp # First, run the ldap script, this will output the files # account.ldif, people.ldif, unixGroup.ldif, and wAccount.ldif # At this point, we only use the first three /usr/local/etc/ldap_getPeople.py -t ldap # Now update the data rm -f /var/adm/ldapUpdate.log /usr/local/bin/ldapmodify -c -f account.ldif > /var/adm/ldapUpdate.log /usr/local/bin/ldapmodify -c -f people.ldif >> /var/adm/ldapUpdate.log /usr/local/bin/ldapmodify -c -f unixGroup.ldif >> /var/adm/ldapUpdate.log
/usr/local/etc/periodic/daily/05.ldapUpdate.local
Detailed instructions on how to use various clients with the CGL LDAP repository is beyond the scope of this document. We have tested Thunderbird, Apple's Address Book, and a couple of other address book and LDAP clients and all work quite well. In general, in order to configure your client, you will need the following information:
Apple's Directory Services and we're told, the new version of the Thunderbird address book features will provide the ability to map entries to the various fields in user Cards. The attributes are described above in the sample entry.
One of the requirements for operation of the Identity portion of CGLAUTH is the ability for users to maintain their own information -- i.e. so-called self-service. This capability is provided through the LDAP Lookup page shown below. The two images show the top and bottom half of the page, respectively.
Figure 5 - CGL LDAP Lookup Page (top half)
Figure 6 - CGL LDAP Lookup Page (bottom half)
The next image demonstrates that lookups do not have to be unique. If the LDAP server returns multiple entries, the entries are presented as a link along with some identifying information. Pressing on the link will take you to the appropriate page for that entry.
Figure 7 - CGL LDAP Lookup Page (Multiple hits)