LDAP

From Wikitech
(Difference between revisions)
Jump to: navigation, search
(Building the server package)
Line 1: Line 1:
{{fixme|There's almost no server info here}}
 
{{fixme|What about client startup when servers are flaky?}}
 
 
 
== Building the server package ==
 
== Building the server package ==
  

Revision as of 04:03, 29 September 2010

Contents

Building the server package

Currently, the server package requires Java 1.5 to build. This should be fixed soon in a newer version of OpenDS (2.2.1), however, for now you'll need to get the java 1.5 packages from jaunty, and set alternatives to point to 1.5:

  1. Edit /etc/apt/sources.list, and add the jaunty repositories:
    # For installing java1.5
    deb http://us.archive.ubuntu.com/ubuntu/ jaunty multiverse
    deb http://us.archive.ubuntu.com/ubuntu/ jaunty-updates multiverse
  2. Run: apt-get update
  3. Run: apt-get install sun-java5-jdk
    • If you are using pbuilder, you'll need to install this after running: pbuilder login --save-after-login
    • To install this inside of pbuilder, first set:
      • DEBIAN_FRONTEND=teletype
    • After installing it, set:
      • DEBIAN_FRONTEND=noninteractive
  4. Run: update-alternatives --config java
    • Select the java 1.5 option
  5. Edit /etc/apt/sources.list, comment out the jaunty repositories

After building the package, you should re-run update-alternatives, and set the default back to 1.6, otherwise it may confuse others.

Installing/Configuring the server manually

Install required packages

apt-get install openjdk-6-jre openjdk-6-jdk ldap-utils opends-wmf

Initial installation

  1. Run /usr/local/OpenDS/bin/setup
    • You need to forward an X11 session for this
    • Ensure you use the FQDN for any hostnames requested!
    • Enable SSL support during the install

Install self-signed certificate and enable SSL

This is only required if you didn't do this at install time; see the OpenDS doc for this.

Disable anonymous read access

Change the following aci:

aci: (targetattr!="userPassword||authPassword")(version 3.0; acl "
Anonymous read access"; allow (read,search,compare) userdn="ldap:///anyone";)

to:

aci: (targetattr!="userPassword||authPassword")(version 3.0; acl "
Anonymous read access"; allow (read,search,compare) userdn="ldap:///all";)

This causes the directory server to require authentication for read access.

To do this, use /usr/local/OpenDS/bin/dsconfig:

  1. Select the "Access Control Handler"
  2. Select "View and edit the Access Control Handler"
  3. Select the "global-aci"
  4. Select "Remove one or more values"
  5. Select the aci to be removed
  6. Select "Add one or more values", add the new entry, hit enter
  7. Select "Use these values"
  8. Select "finish - apply..."
  9. quit

You may also be able to (carefully!) modify these via the ds-cfg-global-aci attribute in the cn=Access Control Handler,cn=config entry.

For more info, see the OpenDS documentation on this.

Create a Basic Directory Information Tree (DIT)

Top level structure

Our aim is for a DIT that is as flat as possible. Adding hierarchy adds complexity, and isn't as flexible as one would first imagine. Using attributes to imply hierarchy is more effective. Below is a basic OU and automount hierarchy:

dn: ou=people,<basedn>
changetype: add
objectClass: top
objectClass: organizationalUnit
ou: people
 
dn: ou=group,<basedn>
changetype: add
objectClass: top
objectClass: organizationalUnit
ou: group
 
dn: ou=netgroup,<basedn>
changetype: add
objectClass: top
objectClass: organizationalUnit
ou: netgroup
 
dn: ou=sudoers,<basedn>
changetype: add
objectClass: top
objectClass: organizationalUnit
ou: sudoers
 
dn: ou=hosts,<basedn>
changetype: add
objectClass: top
objectClass: organizationalUnit
ou: hosts
 
dn: ou=profile,<basedn>
changetype: add
objectClass: top
objectClass: organizationalUnit
ou: profile
 
dn: nisMapName=auto.master,<basedn>
changetype: add
objectClass: top
objectClass: nisMap
nisMapName: auto.master
 
dn: nisMapName=auto.home,<basedn>
changetype: add
objectClass: top
objectClass: nisMap
nisMapName: auto.home
 
dn: nisMapName=/home,nisMapName=auto.master,<basedn>
changetype: add
objectClass: top
objectClass: nisObject
cn: /home
nisMapEntry: ldap:nisMapName=auto.home,<basedn>
nisMapName: auto.master
 
dn: cn=*,nisMapName=auto.home,<basedn>
changetype: add
nisMapEntry: <homedirserver>:/home/&
objectClass: nisObject
objectClass: top
nisMapName: auto.home
cn: *

Object classes and attributes for objects

Users

Objectclasses:

  • top
  • person
  • inetorgperson
  • posixaccount
  • shadowaccount

Attributes:

  • Required:
    • sn
    • cn
    • uid
    • uidnumber
    • gidnumber
    • homedirectory
  • Optional:
    • userpassword
    • loginshell
    • description

In practice, loginshell should always be defined.

Groups

Objectclasses:

  • top
  • posixgroup

Attributes:

  • Required:
    • cn
    • gidnumber
  • Optional:
    • memberuid
    • description

We may want to use the groupofuniquenames objectclass to define the members here, while using posixgroup to define the gidnumber. Doing so would allow us to use full DNs for the group members, which would give us referential integrity.

Netgroups

Objectclasses:

  • top
  • nisnetgroup

Attributes:

  • Required:
    • cn
  • Optional:
    • membernisnetgroup
    • nisnetgrouptriple
    • description

In practice, every entry should either have membernisnetgroup or nisnetgrouptriple.

nisnetgrouptriple attributes are defined as:

(host,user,domainname)

In practice, it is preferred to have netgroups that only define user or host, never both. domainname is never defined. User netgroups are used for controlling access to sudo, ssh login, console login, etc. Host netgroups are used for controlling network access to nfs shares, ssh, etc.

NisMap entries (autofs)

Objectclasses:

  • top
  • nismap

Attributes:

  • Required:
    • nismapname
  • Optional:
    • description

From the perspective of automount, nismaps are like auto.master, and the other files that define mounts. If you have an auto.master file that looks like this:

/home           /etc/auto.home
/data           /etc/auto.data
/scratch        /etc/auto.scratch
+auto.master

You would have nismaps that look like this:

dn: nisMapName=auto.master,<basedn>
objectClass: top
objectClass: nisMap
nisMapName: auto.master
 
dn: nisMapName=auto.home,<basedn>
objectClass: top
objectClass: nisMap
nisMapName: auto.home
 
dn: nisMapName=auto.data,<basedn>
objectClass: top
objectClass: nisMap
nisMapName: auto.data
 
dn: nisMapName=auto.scratch,<basedn>
objectClass: top
objectClass: nisMap
nisMapName: auto.scratch
NisObject entries (autofs)
  • Required:
    • cn
    • nismapentry
    • nismapname
  • Optional:
    • description

Nisobjects exist inside of nismaps. From the perspective of automount, nisobjects are the entries inside of the files. So, the above auto.master file would require the following nisobject entries:

dn: nisMapName=/home,nisMapName=auto.master,<basedn>
objectClass: top
objectClass: nisObject
cn: /home
nisMapEntry: ldap:nisMapName=auto.home,<basedn>
nisMapName: auto.master
 
dn: nisMapName=/home,nisMapName=auto.master,<basedn>
objectClass: top
objectClass: nisObject
cn: /home
nisMapEntry: ldap:nisMapName=auto.home,<basedn>
nisMapName: auto.master
 
dn: nisMapName=/home,nisMapName=auto.master,<basedn>
objectClass: top
objectClass: nisObject
cn: /home
nisMapEntry: ldap:nisMapName=auto.home,<basedn>
nisMapName: auto.master

An example of an entry you'd fine in auto.home would be:

dn: cn=*,nisMapName=auto.home,<basedn>
nisMapEntry: <server>:/home/&
objectClass: nisObject
objectClass: top
nisMapName: auto.home
cn: *
Sudo entries

Objectclasses:

  • top
  • sudorole

Attributes:

  • Required:
    • cn
  • Optional:
    • sudouser
    • sudohost
    • sudocommand
    • sudorunas
    • sudorunasuser
    • sudorunasgroup
    • sudooption
    • description

In practice, most entries will define sudouser, sudohost, and sudocommand. cn=defaults,ou=sudoers should be added with sudooption attributes that should apply globally (like mailto address, etc.).

Security groups

Objectclasses:

  • top
  • groupofnames

Attributes:

  • Required:
    • cn
    • member
  • optional
    • description
Host entries

Objectclasses:

  • top
  • iphost
  • device

Attributes:

  • Required:
    • cn
    • iphostnumber
  • Optional:
    • description

In practice, we should avoid using host entries. DNS is much more suited for this. The only real consideration for using host entries is naming backend systems that aren't in DNS.

Add a proxy agent

Since we are requiring authentication by default, the clients need a user to do authenticated lookups. We create a proxyagent user for this:

dn: cn=proxyagent,ou=profile,<basedn>
changetype: add
objectclass: top
objectclass: inetorgperson
objectclass: person
sn: agent
givenName: proxy
userpassword: <aPasswordGoesHere>
cn: proxyagent

Add the sudoers schema

cp /usr/share/doc/sudo-ldap/schema.iPlanet /usr/local/OpenDS/config/schema/98sudo.ldif
  • Note: This should be a function of our opends package; the package should have a dependency on the sudo-ldap package, or we should include this schema file in the package.

Enable replication

Install/configure phpldapadmin

Installing/Configuring the client manually

Install required packages

apt-get install ldap-utils sudo-ldap libpam-ldap libnss-ldap nss-updatedb libnss-db autofs5 autofs5-ldap nscd

Install the server certificate's CA

  1. Install to /etc/ssl/certs/ldapca.crt
  2. Run:
pushd /etc/ssl/certs
ln -s ldapca.crt $(openssl x509 -hash -noout -in ldapca.crt).0
popd

Configure openldap's ldap.conf

Add the following options to /etc/ldap/ldap.conf:

BASE            <basedn>
URI             ldap://<servername>:389
SSL             start_tls
TLS_CHECKPEER   yes
TLS_REQCERT     demand
TLS_CACERTDIR   /etc/ssl/certs
TLS_CACERTFILE  /etc/ssl/certs/ldapca.crt
TLS_CACERT      /etc/ssl/certs/ldapca.crt
SUDOERS_BASE    ou=sudoers,<basedn>
  • Note: TLS_CACERTDIR is likely ignored, since gnutls doesn't support the directive, but for future compatibility, it should be defined.
  • Note: Though we define the URI as ldap/389, we should always use encryption, so all clients should use StartTLS

Configure libnss's ldap.conf

uri             ldap://<server1>:389 ldap://<server2>:389
base            <basedn>
binddn          cn=proxyagent,ou=profile,<basedn>
bindpw          <proxyagentPasswordInTheClear>
pam_filter      objectclass=posixAccount
nss_base_passwd ou=people,<basedn>
nss_base_shadow ou=people,<basedn>
nss_base_group  ou=group,<basedn>
nss_base_hosts  ou=hosts,<basedn>
nss_base_netgroup     ou=netgroup,<basedn>
tls_checkpeer   yes
tls_cacertfile   /etc/ssl/certs/ldapca.crt
tls_cacertdir   /etc/ssl/certs
ssl             start_tls
pam_password    clear

Configure nss

passwd:         files ldap
group:          files ldap
shadow:         files ldap
 
hosts:          files dns ldap
networks:       files
 
protocols:      db files
services:       db files
ethers:         db files
rpc:            db files
 
netgroup:       ldap
automount:      files ldap
sudoers:        files ldap

The above works for clients with DNS access. For hosts without DNS access, the following line works better for hosts:

hosts:          files ldap dns

Configure pam

common-auth:

# here are the per-package modules (the "Primary" block)
auth    [success=2 default=ignore]      pam_unix.so nullok_secure
auth    [success=1 default=ignore]      pam_ldap.so use_first_pass
# here's the fallback if no module succeeds
auth    requisite                       pam_deny.so
# limit access to specific users
auth    required                        pam_access.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth    required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
# end of pam-auth-update config

common-account:

# here are the per-package modules (the "Primary" block)
account [success=2 new_authtok_reqd=done default=ignore]        pam_unix.so
account [success=1 default=ignore]      pam_ldap.so
# here's the fallback if no module succeeds
account requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
account required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
# end of pam-auth-update config

common-password:

# here are the per-package modules (the "Primary" block)
password        [success=2 default=ignore]      pam_unix.so obscure sha512
password        [success=1 user_unknown=ignore default=die]     pam_ldap.so try_first_pass
# here's the fallback if no module succeeds
password        requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
password        required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
# end of pam-auth-update config

common-session:

# here are the per-package modules (the "Primary" block)
session [default=1]                     pam_permit.so
# here's the fallback if no module succeeds
session requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
session required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
session required        pam_unix.so
session optional                        pam_ldap.so
# end of pam-auth-update config

common-session-noninteractive:

# here are the per-package modules (the "Primary" block)
session [default=1]                     pam_permit.so
# here's the fallback if no module succeeds
session requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
session required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
session required        pam_unix.so
session optional                        pam_ldap.so
# end of pam-auth-update config

Configure autofs

Configure /etc/autofs_ldap_auth.conf

Autofs's ldap configuration needs to be set to require tls, and authentication, and to use SASL PLAIN authentication with a DN and password. The following configuration provides that:

<?xml version="1.0" ?>
<autofs_ldap_sasl_conf
        usetls="yes"
        tlsrequired="yes"
        authrequired="yes"
        authtype="PLAIN"
        user="dn:cn=proxyagent,ou=profile,<basedn>"
        secret="<proxyagentPassword>"
/>

Be sure to fill in <basedn> and <proxyagentPassword> with real values.

Configuring overrides

nsswitch.conf is configured to use files, then ldap. It is possible, but not necessary to do this per map. It is required to do this at least for auto.master. If we want to pull all maps from ldap, the only line needed in /etc/auto.master is:

+auto.master

The above line tells automount to pull its maps from whichever service is configured in nss after files. If you wish to override LDAP, you can place entries above the + line. You can override individual entries for individual maps by doing something like the following:

  • In auto.master:
/data    /etc/auto.data
+auto.master
  • In auto.data:
overridenentry    <server>:/export
+auto.data

The above would still pull all auto.data entries, but would override the specific entry "overrideentry".

Configure sudo

sudo is configured via the nsswitch. As long as the sudo-ldap package is installed, and nsswitch.conf has ldap listed for sudoers, it will automatically pull from ldap.

Troubleshooting

Corrupt nscd cache

The nscd cache is a bdb database, and can (rarely) become corrupt when a system shuts down uncleanly. You can forcibly clear the cache by doing the following:

/etc/init.d/nscd stop
rm -f /var/cache/nscd/*
/etc/init.d/nscd start

Invalid nscd cache

To purge an invalid cache, you can do the following:

nscd -i <database>

Where <database> is passwd, group, or services.

Debugging sudo-ldap

Sudo will print ldap debugging information, if you add the following to /etc/ldap/ldap.conf:

SUDOERS_DEBUG 2

Debugging autofs

Autofs will print debugging information to /var/log/syslog, if you add the following to /etc/default/autofs:

LOGGING="debug"
Personal tools
Namespaces

Variants
Actions
Navigation
Ops documentation
Wiki
Toolbox