=====Overview===== {auth, auth1, auth2, ... authN}.offbyone.lan, .lair.lan, and .dslab.lan are the authentication servers in use in the BITS universe. ^ hostname ^ RAM ^ disk ^ swap ^ OS ^ Kernel ^ | auth1.offbyone.lan | 128MB | 2GB (/) | 128MB | Debian 6.0 "Squeeze" (AMD64) | 2.6.32-5-xen-amd64 | | auth2.offbyone.lan | 128MB | 2GB (/) | 128MB | Debian 6.0 "Squeeze" (AMD64) | 2.6.32-5-xen-amd64 | | auth3.lair.lan | 128MB | 2GB (/) | 128MB | Debian 6.0 "Squeeze" (AMD64) | 2.6.32-5-xen-amd64 | =====News===== * Created auth1.offbyone.lan and auth2.offbyone.lan, a new set of VMs to replace the aging auth. (20101226) * Migrated LAIR LDAP data over to auth1, made it the primary LAIR LDAP server (20101228) * Created auth3.lair.lan, an LDAP consumer living on the lair.lan domain. Also reachable as auth3.offbyone.lan; all pertinent DNS records updated (20110102) =====TODO==== * rig up replication * explore DNS Service Discovery * how to rig up virtual/aliased/ghost dc's (ie map dc=offbyone,dc=lan always to dc=lair,dc=bits) * DNS service discovery would work * finish getting auth2 up and running * build new DSLAB LDAP Servers (2, to have redundancy and replication) * investigate referrals, or replication+referrals between LAIR and DSLAB =====Xen Config===== The Xen config files for one of the auth-class VMs follows: ====auth1==== auth1.offbyone.lan was created by running: halfadder:~# xen-create-image --hostname=auth1 --mac 00:16:3E:3C:83:50 --role=udev Its Xen configuration file is as follows: ########################################################################## # LAIR Xen VM configuration file (auth1.offbyone.lan) ########################################################################## ################################################# # Kernel + memory size # bootloader = '/usr/lib/xen-default/bin/pygrub' vcpus = '1' memory = '128' ################################################# # Disk device(s). # root = '/dev/xvda1 ro' disk = [ 'file:/xen/images/auth1.disk,xvda1,w', 'file:/xen/images/auth1.swap,xvda2,w' ] ################################################# # Hostname # name = 'auth1' ################################################# # Networking # dhcp = 'dhcp' vif = [ 'mac=00:16:3E:3C:83:50' ] ################################################# # Behaviour # on_poweroff = 'destroy' on_reboot = 'restart' on_crash = 'restart' =====Network Configuration===== ^ Machine ^ Interface ^ IP Address ^ MAC Address ^ Other Names ^ | auth.offbyone.lan | eth0 | 10.80.2.8 | N/A | | | auth.lair.lan | eth0 | 10.80.1.8 | N/A | | | auth1.offbyone.lan | eth0 | 10.80.2.9 | 00:16:3E:3C:83:50 | auth1.lair.lan | | auth2.offbyone.lan | eth0 | 10.80.2.10 | 00:16:3E:3C:83:51 | auth2.lair.lan | | auth3.lair.lan | eth0 | 10.80.1.11 | 00:16:3E:42:EE:4A | auth3.offbyone.lan | =====Configuring LDAP (slapd)===== The method followed here is derived (and heavily so) from the [[http://www.rjsystems.nl/en/2100-d6-openldap-provider.php|OpenLDAP provider on Debian Squeeze]] tutorial at http://www.rjsystems.nl/en/2100-d6-openldap-provider.php ... Information here is summarized from that document and adapted to fit the LAIR/BITS environment. ====Overview==== LDAP services are provided via **slapd**. This used to be configured in a file known as **/etc/ldap/slapd.conf**, but with Debian Squeeze, the version of OpenLDAP used (2.4.23-7), configuration information is now stored in an LDAP database, and manipulated via the various LDAP command-line tools (think registry). Because we are also interested in configuring replication and having multiple LDAP servers, these instructions will by default include such instructions. One immediate benefit of this new structure is that slapd can remain running... we no longer need to shut it down to perform various operations. ====Prerequisite packages==== To verify correct operation and validate various aspects of operational success, we will start off by installing the following (on all auth machines): ===configure for LAIR packages=== We'll want to install lair-std and lair-vm, and likely eventually lrrd-node, so do the following on both auth's: all_auth:~# echo "deb http://mirror/lair squeeze main" >> /etc/apt/sources.list all_auth:~# aptitude update ... all_auth:~# swapon /dev/xvda2 all_auth:~# aptitude install lair-std lair-vm ntp ... All auth-class systems should now be at a good initial state. ====Working with the Debian scripts: Setting the FQDN==== lair-std seems to have a bug that prevents proper domain name formatting in /etc/hosts... until this is fixed, be sure to manually check **/etc/hosts** to ensure that all domain names are set, and properly. Additionally, to make Debian's slapd install scripts bootstrap with the desired "dc", we're going to intentionally add an extra domain. As a result, the correct **/etc/hosts** files on auth1 and auth2 should be as follows: ###LAIRCONF### 127.0.0.1 localhost.localdomain localhost 10.80.2.38 lab46.corning-cc.edu lab46.offbyone.lan lab46.lair.lan lab46 10.80.2.3 nfs.offbyone.lan nfs 10.80.2.9 auth1.lair.bits auth1.offbyone.lan auth1 10.80.2.10 auth2.lair.bits auth2.offbyone.lan auth2 10.80.1.11 auth3.lair.bits auth3.lair.lan auth3 Once **slapd** is installed and running, we can remove the **auth[12].lair.bits** phrases. ====Reboot==== At this point, to ensure everything is in order, give both systems a reboot. ====Install LDAP bits (normal)==== Since we are going to serve LDAP, we'll now do the following: all_auth:~# aptitude install slapd ldap-utils ... There will be a prompt for an administrator password. ====Install LDAP bits (consumer)==== As it turns out, there's currently a bug in the OpenLDAP code, as shipped by both Debian and still residing within the vanilla OpenLDAP releases, that causes errors (even affecting the ability for slapd to run) when enabling the chaining functionality, as is the case with LDAP consumers. For this reason, the Debian packages were manually rebuilt, and a patch applied which resolves this issue. Until the fix is officially provided by the Debian packages, we'll have to rely on these packages instead. Either rebuild the packages from source (follow the directions in the rjsystems.nl tutorial) or grab an existing copy from other prior efforts. So instead of installing slapd and ldap-utils above, we'll instead want to do this: auth_consumer:~# aptitude install libsasl2-2 libltdl7 libperl5.10 libslp1 unixodbc ... auth_consumer:~# dpkg -i ldap-utils_2.4.23-7patched1_amd64.deb libldap-2.4-2_2.4.23-7patched1_amd64.deb slapd_2.4.23-7patched1_amd64.deb ... ====Result of successful LDAP installation==== Following the installation, we can check to make sure everything is in order. The intent is to use "dc=lair,dc=bits" for our LDAP database, so let's see if our hack to **/etc/hosts** has paid off: all_auth:~# slapcat hdb_db_open: database "dc=lair,dc=bits": unclean shutdown detected; attempting recovery. hdb_db_open: database "dc=lair,dc=bits": recovery skipped in read-only mode. Run manual recovery if errors are encountered. dn: dc=lair,dc=bits objectClass: top objectClass: dcObject objectClass: organization o: lair.bits dc: lair structuralObjectClass: organization entryUUID: fadb154e-a654-102f-9d47-4b2dc132a5e2 creatorsName: cn=admin,dc=lair,dc=bits createTimestamp: 20101227223249Z entryCSN: 20101227223249.652609Z#000000#000#000000 modifiersName: cn=admin,dc=lair,dc=bits modifyTimestamp: 20101227223249Z dn: cn=admin,dc=lair,dc=bits objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: LDAP administrator userPassword:: e1NTSEF9VG1LV2FDK1QxVkNTSk16MGlCWUQxTnVuOHFkeXdyTEU= structuralObjectClass: organizationalRole entryUUID: fadb71d8-a654-102f-9d48-4b2dc132a5e2 creatorsName: cn=admin,dc=lair,dc=bits createTimestamp: 20101227223249Z entryCSN: 20101227223249.654994Z#000000#000#000000 modifiersName: cn=admin,dc=lair,dc=bits modifyTimestamp: 20101227223249Z all_auth:~# If you see any "dc=nodomain" or things other than "dc=lair,dc=bits" (or the desired name), then you'll likely want to remove (purge), twiddle settings, and reinstall slapd until this becomes correct. With further LDAP knowledge and experience, this could likely be fixed with a customized ldif file. ====Configure /etc/ldap/ldap.conf==== Hook up the rest of the system with our new LDAP service: ===auth1=== BASE dc=lair,dc=bits URI ldap://auth1.offbyone.lan/ ===auth2=== BASE dc=lair,dc=bits URI ldap://auth2.offbyone.lan/ ====Remove auth[12].lair.bits from /etc/hosts==== Before we go any further, we should remove the hack we put in place to facilitate (trick) the Debian installation scripts into giving us precisely what we want. It would of course been easier had we just used our default domain, but since the LAIR runs 3 different domains, and the long-term intent is to hook up the authentication domains at all BITS endpoints, I opted to adopt the .bits "domain" for authentication services. So, go and edit **/etc/hosts** on BOTH auth's, and remove the reference to **.lair.bits**. The resulting file should look like this: ###LAIRCONF### 127.0.0.1 localhost.localdomain localhost 10.80.2.8 auth.offbyone.lan auth.lair.lan auth 10.80.2.38 lab46.corning-cc.edu lab46.offbyone.lan lab46.lair.lan lab46 10.80.2.3 nfs.offbyone.lan nfs 10.80.2.9 auth1.offbyone.lan auth1 10.80.2.10 auth2.offbyone.lan auth2 =====Configure LDAP provider (auth1)===== ====Tweak settings in cn=config==== To aid in debugging, the rjsystems.nl tutorial has us apply the following changes (I put in a file called olc1.ldif): # 1. dn: cn=config changetype: modify replace: olcLogLevel olcLogLevel: stats # 2.1. dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcDbIndex olcDbIndex: uid eq - # 2.2. add: olcDbIndex olcDbIndex: cn eq - # 2.3. add: olcDbIndex olcDbIndex: ou eq - # 2.4. add: olcDbIndex olcDbIndex: dc eq We then apply it as follows: auth1:~# ldapmodify -QY EXTERNAL -H ldapi:/// -f ~/olc1.ldif modifying entry "cn=config" modifying entry "olcDatabase={1}hdb,cn=config" auth1:~# Because we're on the machine running the server, we can "get around" the need for authentication to make changes here to cn=config (which would make sense-- why would we want to allow modifications to cn=config over the network?). ====Push LDAP tree structure to LDAP database==== We'll now push the initial structure we'd like to maintain in our LDAP tree. ===Create structure=== To do this, we need the information in an ldif file (see structure.ldif): dn: ou=people,dc=lair,dc=bits objectClass: organizationalUnit ou: people dn: ou=groups,dc=lair,dc=bits objectClass: organizationalUnit ou: groups dn: ou=hosts,dc=lair,dc=bits objectClass: organizationalUnit ou: hosts ===Add structure to database=== With which we can use **ldapadd** to place it in our database: auth1:~# ldapadd -xWD cn=admin,dc=lair,dc=bits -f structure.ldif Enter LDAP Password: adding new entry "ou=people,dc=lair,dc=bits" adding new entry "ou=groups,dc=lair,dc=bits" adding new entry "ou=hosts,dc=lair,dc=bits" auth1:~# ====Migrate LDAP user data==== With the database in an amenable format to support our data, we will now transition our existing LDAP user data into the new one. There are some mild format changes that need to take place, in addition to some additions and deletions of data. ===Dump existing LDAP database into LDIF=== Hopping onto auth (the current LDAP server), we will obtain a copy of the LDAP database as follows: auth:~# ldapvi --out --discover -D "cn=admin,dc=lair,dc=lan" > ldapdb.ldif --- Login Type M-h for help on key bindings. Filter or DN: cn=admin,dc=lair,dc=lan Password: auth:~# This will produce a file in the current directory called **ldapdb.ldif**. ===Remove unnecessary entries=== There are some entries in this LDIF that are not needed (due to the fact they already exist in the new LDAP database). Specifically, we want to remove the following from the top of the file: dn: dc=lair,dc=lan objectClass: top objectClass: dcObject objectClass: organization o: lair_lan dc: lair dn: cn=admin,dc=lair,dc=lan objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: LDAP administrator userPassword: {SSHA}kjsdhfjksdf/sdlfkjsdf+223kKOA dn: ou=People,dc=lair,dc=lan ou: People objectClass: organizationalUnit dn: ou=Group,dc=lair,dc=lan ou: Group objectClass: organizationalUnit Because we've already defined our distinguished name, admin is there, and we've just added our **ou**'s for people and groups. So just remove this data. This will leave us starting with the lair group. ===remove replica=== We'll also want to remove the 'replica' object, which was used in the old LDAP replication. We'll be creating a new object to perform this functionality. So search for and remove the following lines: dn: cn=replica,dc=lair,dc=bits objectClass: simpleSecurityObject objectClass: organizationalRole cn: replica description: LDAP replicator userPassword: {SSHA}sdjkfhWadsFSdg+hs/a4 ===Change spelling and dc data=== Now on to some substitutions (doesn't have to be done on old auth... we can copy our file somewhere and perform the changes): auth:~# cat ldapdb.ldif | sed 's/dc=lan/dc=bits/g' \ > | sed 's/ou=Group/ou=groups/g' | sed 's/ou=People/ou=people/g' \ # correct our ou's > | sed 's/^objectClass: account/objectClass: top\nobjectClass: person/g' \ # fix objectClasses > | sed 's/^cn: \([a-zA-z]*\) \([a-zA-Z]*\)$/cn: \1\nsn: \2/g' \ # cn/sn fix 1 (first/last) > | sed 's/^cn: \([a-zA-z]*\) \([a-zA-Z]\.\) \([a-zA-Z]*\)$/cn: \1 \2\nsn: \3/g' \ # cn/sn fix 2 (initials) > | sed 's/^cn: \([a-zA-z]*\) \([a-zA-Z]*\) \([a-zA-Z]*\)$/cn: \1\nsn: \2 \3/g' \ # cn/sn fix 3 (3 words) > | sed 's/^objectClass: posixGroup/objectClass: top\nobjectClass: posixGroup/g' \ # fix group objectClasses > | sed '/^shadowLastChange/d' | sed '/^host: /d' > ldapdbnew.ldif # remove unneeded things auth:~# A few accounts will be pruned by hand (since there are so few of these exceptions that don't warrant a regex). When done with pruning, be sure the resultant file is copied over to **auth1**. ====Commit LDAP user data to new LDAP database==== Time to add the data to our new database: auth1:~# ldapadd -cxWD cn=admin,dc=lair,dc=bits -f ~/ldapdbnew.ldif Enter LDAP Password: adding new entry "cn=lair,ou=groups,dc=lair,dc=bits" adding new entry "uid=wedge,ou=people,dc=lair,dc=bits" adding new entry "uid=ian,ou=people,dc=lair,dc=bits" adding new entry "uid=squirrel,ou=people,dc=lair,dc=bits" ... auth:~# Any errors in the entry, and that account would not be added. Luckily, we can just scan the output of the ldapadd to look for errors, make the appropriate corrections, and run the command again (we'll then get a bunch of "ldap_add: Already exists (68)" messages, but these are harmless) to add the corrected entries. ====Test/Verify data==== Once the data is added, we can do some quick checks to ensure it is there and works. ===General LDAP search=== Does 'wedge' exist? auth1:~# ldapsearch -xLLL uid=wedge dn: uid=wedge,ou=people,dc=lair,dc=bits uid: wedge cn: Matthew sn: Haas objectClass: top objectClass: person objectClass: posixAccount objectClass: shadowAccount loginShell: /bin/bash uidNumber: 1020 gidNumber: 1000 homeDirectory: /home/wedge gecos: Matthew Haas auth1:~# Check. ===User Authentication=== Can 'wedge' authenticate and verify its identity? auth:~# ldapwhoami -xD uid=wedge,ou=people,dc=lair,dc=bits -W Enter LDAP Password: dn:uid=wedge,ou=people,dc=lair,dc=bits auth1:~# Also good. ====Initial LDAP install complete==== At this point, LDAP (via slapd) should be installed and running. =====LDAP Consumers (auth2 and auth3)===== The method followed here is derived (and heavily so) from the [[http://www.rjsystems.nl/en/2100-d6-openldap-consumer.php|OpenLDAP consumer on Debian Squeeze]] tutorial at http://www.rjsystems.nl/en/2100-d6-openldap-consumer.php ... Information here is summarized from that document and adapted to fit the LAIR/BITS environment. With a basic slapd database on auth2 and auth3, and a fully functional LDAP server on auth1, we will be moving to configure auth2 and auth3 as an LDAP consumers (slave servers), so we'll have some level of redundancy/availability of LDAP services in the LAIR. ====Create replicator object==== As in our past replicating instantiations, we need an LDAP object to bind as to perform the synchronization activities. The aim is to have an LDAP consumer in both the offbyone.lan and lair.lan domains, so we'll end up with an auth2 and auth3 VM. For our purposes we'll create objects called **auth2repl** and **auth3repl**, which need to be added to the existing LDAP database on **auth1**. Its LDIF is as follows: dn: cn=auth2repl,dc=lair,dc=bits objectClass: simpleSecurityObject objectClass: organizationalRole cn: authrepl description: LDAP auth2 replicator userPassword: chosen_password - dn: cn=auth3repl,dc=lair,dc=bits objectClass: simpleSecurityObject objectClass: organizationalRole cn: authrepl description: LDAP auth3 replicator userPassword: chosen_password And then to add it to the database (note we're on **auth1**): auth1:~# ldapadd -cxWD cn=admin,dc=lair,dc=bits -f ~/authrepl.ldif Enter LDAP Password: adding new entry "cn=auth2repl,dc=lair,dc=bits" adding new entry "cn=auth3repl,dc=lair,dc=bits" auth1:~# ====Configure syncrepl on auth1==== Also as in prior LDAP synchronization attempts, we'll be making use of the **syncrepl** functionality. The LDIF to provide this functionality is as follows (I put in a file called **syncrepl.ldif**: # Remove olcAccess ACL (since it only allows admin to write) dn: olcDatabase={1}hdb,cn=config changetype: modify delete: olcAccess olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=lair,dc=bits" write by * none - # Add it back in, only also add in the ability for the authrepl object to read data add: olcAccess olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by dn="cn=admin,dc=lair,dc=bits" write by dn="cn=auth2repl,dc=lair,dc=bits" read by dn="cn=auth3repl,dc=lair,dc=bits" read by anonymous auth by * none - # add new indexing option add: olcDbIndex olcDbIndex: entryUUID eq - # avoid verbose logs later through optimization add: olcDbIndex olcDbIndex: uid,uidNumber,gidNumber,memberUid,uniqueMember,objectClass,cn eq - # add another indexing option add: olcDbIndex olcDbIndex: entryCSN eq # enable the syncprov module dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: {1}syncprov # specify syncprov attributes dn: olcOverlay=syncprov,olcDatabase={1}hdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: {0}syncprov olcSpCheckpoint: 100 10 olcSpSessionlog: 100 And then adding it (on **auth1**): auth1:~# ldapmodify -QY EXTERNAL -H ldapi:/// -f ~/syncrepl.ldif modifying entry "olcDatabase={1}hdb,cn=config" modifying entry "cn=module{0},cn=config" adding new entry "olcOverlay=syncprov,olcDatabase={1}hdb,cn=config" auth1:~# ====Configure syncrepl on auth2==== Now that **auth1** has been configured to be a provider, we now turn to configuring **auth2** to act as an LDAP consumer. We'll need to apply some information to the LDAP database on **auth2**, the LDIF (**replconsume.ldif**): # for debugging purposes, crank up logging on auth2 dn: cn=config changetype: modify replace: olcLogLevel olcLogLevel: stats # remove the current olcAccess {0} ACL dn: olcDatabase={1}hdb,cn=config changetype: modify delete: olcAccess olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=lair,dc=bits" write by * none - # set the olcAccess {0} ACL add: olcAccess olcAccess: {0}to attrs=userPassword,shadowLastChange by anonymous auth by * none - # remove the {2} olcAccess ACL delete: olcAccess olcAccess: {2}to * by self write by dn="cn=admin,dc=lair,dc=bits" write by * read - # alter the olcAccess ACL add: olcAccess olcAccess: {2}to * by * read - # replace olcRootDN replace: olcRootDN olcRootDN: cn=manager - # remove olcRootPW delete: olcRootPW - # indexing option (by entryCSN) add: olcDbIndex olcDbIndex: entryCSN eq - # indexing option (by entryUUID) add: olcDbIndex olcDbIndex: entryUUID eq - # indexing option (by uid) add: olcDbIndex olcDbIndex: uid eq - # indexing option (by cn) add: olcDbIndex olcDbIndex: cn eq - # indexing option (by ou) add: olcDbIndex olcDbIndex: ou eq - # indexing option (by dc) add: olcDbIndex olcDbIndex: dc eq - # syncrepl definition (who are we synchronizing with) add: olcSyncrepl olcSyncrepl: rid=102 provider="ldap://auth1.offbyone.lan:389/" type=refreshAndPersist retry="60 30 300 +" searchbase="dc=lair,dc=bits" bindmethod=simple binddn="cn=auth2repl,dc=lair,dc=bits" credentials=chosen_password And add it to the LDAP database on **auth2**: auth2:~# ldapmodify -QY EXTERNAL -H ldapi:/// -f ~/replconsume.ldif modifying entry "cn=config" modifying entry "olcDatabase={1}hdb,cn=config" auth2:~# ====prep auth2 for synchronization==== Because there is default data residing in the LDAP database on **auth2**, we'll want to clear it out before engaging in full replication activities. Shut down slapd on auth2, remove the LDAP database, and restart: auth2:~# /etc/init.d/slapd stop Stopping OpenLDAP: slapd. auth2:~# rm -f /var/lib/ldap/* auth2:~# /etc/init.d/slapd start Starting OpenLDAP: slapd. auth2:~# ====potential problem==== After resuming slapd operations, I noticed the following appear in the logs: Dec 30 18:20:31 auth2 slapd[1232]: do_syncrep2: rid=123 LDAP_RES_SEARCH_RESULT (4) Size limit exceeded Dec 30 18:20:31 auth2 slapd[1232]: do_syncrep2: rid=123 (4) Size limit exceeded Dec 30 18:20:31 auth2 slapd[1232]: do_syncrepl: rid=123 rc -2 retrying (29 retries left) As it turns out, because we're not binding as an admin user, there are limits applied, and with the full size of the LAIR LDAP database, we easily exceed those default limits. So what we'll need to do is disable those limits. The following LDIF file (**size.ldif**) applied to the LDAP database on **auth1** should do the trick: # fix "Size limit exceeded" message in logs dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcLimits olcLimits: dn.exact="cn=auth2repl,dc=lair,dc=bits" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited - add: olcLimits olcLimits: dn.exact="cn=auth3repl,dc=lair,dc=bits" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited auth1:~# ldapmodify -Y external -H ldapi:/// -f ~/size.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 modifying entry "olcDatabase={1}hdb,cn=config" auth1:~# This appears to have resolved the problem. ====Relocating LDAP database==== Getting a sense of success with the recent LDAP efforts, certain actions should be taken to prepare the way for replication with other BITS peers. The one big thing that will need to happen is the relocation of LDAP data to a specific directory-- **/var/lib/ldap/lair** for LAIR LDAP, **/var/lib/ldap/dslab** for DSLAB LDAP, etc. We'll handle this change on **auth2** since it is more expendable in the case of a problem. First up, the LDIF that will change the location of the LDAP database (dbdir.ldif): # change where the LDAP database is located dn: olcDatabase={1}hdb,cn=config changetype: modify delete: olcDbDirectory - add: olcDbDirectory olcDbDirectory: /var/lib/ldap/lair And then, prepping auth2 and actually performing the change: auth2:~# mkdir /var/lib/ldap/lair /var/lib/ldap/dslab auth2:~# chown openldap:openldap /var/lib/ldap/lair auth2:~# chown openldap:openldap /var/lib/ldap/dslab auth2:~# ldapmodify -Y external -H ldapi:/// -f ~/dbdir.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 modifying entry "olcDatabase={1}hdb,cn=config" auth2:~# /etc/init.d/slapd stop Stopping OpenLDAP: slapd. auth2:~# rm -f /var/lib/ldap/* rm: cannot remove `dslab': Is a directory rm: cannot remove `lair': Is a directory auth2:~# /etc/init.d/slapd start Starting OpenLDAP: slapd. auth2:~# If we now check, **/var/lib/ldap/** should be free of LDAP database files, whereas **/var/lib/ldap/lair** should now be populated with the files (in fact it will have transferred all the data fresh from **auth1**). Success! ====Referrals==== Right now, replication has established a provider and consumer... they both contain complete replicas of the LAIR LDAP database. But as it is, the provider (auth1) is the only resource that can commit writes, although both can read. So when the various LAIR LDAP clients are configured, they'll have free selection over either auth1 or auth2, but if they reach auth2 and need to perform a write, we'll need to rig up some functionality so this will succeed. What we want to rig up are LDAP referrals. Basically, what that will do is forward the write request from auth2 to auth1, enabling the action to go through despite auth2's inability to write. The beauty is, the end client should notice no difference whether they are communicating with auth2 or auth1... it should just work. Here is the LDIF (referral.ldif): # set referral host dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcUpdateref olcUpdateref: "ldap://auth1.offbyone.lan:389/" # load module for referring/chaining dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: {1}back_ldap # configuring chaining, which will force chasing of referrals dn: olcOverlay=chain,olcDatabase={-1}frontend,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcChainConfig olcOverlay: {0}chain olcChainReturnError: TRUE # more chaining configuration (to enable proxy-like behavior) dn: olcDatabase=ldap,olcOverlay={0}chain,olcDatabase={-1}frontend, cn=config changetype: add objectClass: olcLDAPConfig objectClass: olcChainDatabase olcDatabase: {0}ldap olcDbURI: "ldap://auth1.offbyone.lan:389/" olcDbRebindAsUser: TRUE olcDbIDAssertBind: bindmethod=simple binddn="cn=auth2repl,dc=lair,dc=bits" credentials=chosen_password mode=self and adding it (we're on auth2): auth2:~# ldapmodify -QY EXTERNAL -H ldapi:/// -f ~/referral.ldif modifying entry "olcDatabase={1}hdb,cn=config" modifying entry "cn=module{0},cn=config" adding new entry "olcOverlay=chain,olcDatabase={-1}frontend,cn=config" adding new entry "olcDatabase=ldap,olcOverlay={0}chain,olcDatabase={-1}frontend,cn=config" auth2:~# ====Referral/Proxy authorization==== The last step that needs to take place is to establish the proper authorization on auth1 so that it knows to trust these incoming connections from auth2 (since it'll be using the **auth2repl/auth3repl** objects). So, we'll start on **auth1**... first file up is **authorize.ldif**: # Enable ability for authrepl to proxy dn: cn=auth2repl,dc=lair,dc=bits changetype: modify add: authzTo authzTo: {0}dn.regex:^uid=[^,]+,ou=people,dc=lair,dc=bits$ authzTo: {1}dn.exact:cn=admin,dc=lair,dc=bits And to add it: auth1:~# ldapmodify -xWD "cn=admin,dc=lair,dc=bits" -f ~/authorize.ldif Enter LDAP Password: modifying entry "cn=auth2repl,dc=lair,dc=bits" auth1:~# Finally, in a file called **policy.ldif**, we have the following, which enables acceptance of proxy requests: # Enable proxy access dn: cn=config changetype: modify add: olcAuthzPolicy olcAuthzPolicy: to Then to add it: auth1:~# ldapmodify -QY EXTERNAL -H ldapi:/// -f ~/policy.ldif modifying entry "cn=config" auth1:~# At this point, proxy access should be working! A write to auth2 should be properly forwarded and processed by auth1. =====LDAP client connectivity===== Due to the various structure changes to the LDAP database, there are some changes required to accomplish client LDAP access in the LAIR. To facilitate matters, I have updated the **lair-ldap** package.. doing an "aptitude update" then upgrade or direct install of lair-ldap will bring it in... it is tested and known working with etch, lenny, and squeeze systems. Here will be a breakdown of the various files and their settings needed to establish proper LDAP client access. ====/etc/ldap/ldap.conf==== ###LAIRCONF### # # $OpenLDAP: pkg/ldap/libraries/libldap/ldap.conf,v 1.9 2000/09/04 19:57:01 kurt Exp $ # # LDAP Defaults # BASE dc=lair,dc=bits URI ldap://auth1 ldap://auth2 ldap://auth3 ====/etc/pam_ldap.conf==== ###LAIRCONF### # # @(#)$Id: ldap.conf,v 1.36 2005/03/23 08:29:59 lukeh Exp $ # # This is the configuration file for the LDAP nameservice # switch library and the LDAP PAM module. # base dc=lair,dc=bits uri ldap://auth1 ldap://auth2 ldap://auth3 ldap_version 3 pam_password exop nss_base_passwd ou=people,dc=lair,dc=bits?one #nss_base_passwd ou=People,dc=dslab,dc=lan?one #nss_base_passwd ou=People,dc=sunyit,dc=lan?one nss_base_shadow ou=people,dc=lair,dc=bits?one #nss_base_shadow ou=People,dc=dslab,dc=lan?one #nss_base_shadow ou=People,dc=sunyit,dc=lan?one nss_base_group ou=groups,dc=lair,dc=bits?one #nss_base_group ou=Group,dc=dslab,dc=lan?one #nss_base_group ou=Group,dc=sunyit,dc=lan?one ====/etc/libnss_ldap.conf==== ###LAIRCONF### # # @(#)$Id: ldap.conf,v 2.47 2006/05/15 08:13:44 lukeh Exp $ # # This is the configuration file for the LDAP nameservice # switch library and the LDAP PAM module. # base dc=lair,dc=bits ldap_version 3 uri ldap://auth1 ldap://auth2 ldap://auth3 bind_policy soft nss_base_passwd ou=people,dc=lair,dc=bits?one #nss_base_passwd ou=People,dc=dslab,dc=lan?one #nss_base_passwd ou=People,dc=sunyit,dc=lan?one nss_base_shadow ou=people,dc=lair,dc=bits?one #nss_base_shadow ou=People,dc=dslab,dc=lan?one #nss_base_shadow ou=People,dc=sunyit,dc=lan?one nss_base_group ou=groups,dc=lair,dc=bits?one #nss_base_group ou=Group,dc=dslab,dc=lan?one #nss_base_group ou=Group,dc=sunyit,dc=lan?one ====/etc/nsswitch.conf==== ###LAIRCONF### # # /etc/nsswitch.conf # passwd: files [SUCCESS=return] ldap group: files [SUCCESS=return] ldap shadow: files [SUCCESS=return] ldap hosts: files dns networks: files protocols: files services: files ethers: files rpc: files netgroup: files ====/etc/pam.d/common-account==== ###LAIRCONF### # # /etc/pam.d/common-account - authorization settings common to all services # # try password file first, then ldap account [success=2 new_authtok_reqd=done default=ignore] pam_unix.so account [success=1 default=ignore] pam_ldap.so account requisite pam_deny.so account required pam_permit.so ====/etc/pam.d/common-auth==== ###LAIRCONF### # # /etc/pam.d/common-auth - authentication settings common to all services # # try password file first, then ldap auth [success=2 default=ignore] pam_unix.so nullok_secure try_first_pass auth [success=1 default=ignore] pam_ldap.so use_first_pass auth requisite pam_deny.so auth required pam_permit.so ====/etc/pam.d/common-password==== ###LAIRCONF### # # /etc/pam.d/common-password - password-related modules common to all services # # try password files first, then ldap. enforce use of very strong passwords. password [success=2 default=ignore] pam_unix.so obscure sha512 password [success=1 user_unknown=ignore default=die] pam_ldap.so try_first_pass password requisite pam_deny.so password required pam_permit.so __NOTE:__ if the option **use_authtok** is present, especially on the line for pam_ldap.so, users will be able to log in, but a failure will take place when a write action to LDAP records occurs, such as in changing passwords. Removal of **use_authtok** will resolve this problem. ====/etc/pam.d/common-session==== ###LAIRCONF### # # /etc/pam.d/common-session - session-related modules common to all services # session [default=1] pam_permit.so session requisite pam_deny.so session required pam_permit.so session required pam_unix.so session optional pam_ldap.so =====LDAP client access===== Prior to this LDAP update, we accomplished access to machines via the host: attribute stored in each user's LDAP entry. This functionality wasn't enabled this time around, so we're resorting to another method. To control access to the systems, **/etc/pam.d/sshd** and **/etc/security/access.conf** are configured: ====/etc/pam.d/sshd==== The default file has everything we need, just uncomment the following line: account required pam_access.so ====/etc/security/access.conf==== Depending on the level of access, we'll want to add a line like the following to this file: -:ALL EXCEPT root lair:ALL EXCEPT LOCAL What this line does is exclude access to anyone not root or in the lair group (we can add additional usernames or groups to this list to enable access. =====slapd cn=config tweaks===== ====Change slapd log level==== To alter the level or type of information that slapd reports, we adjust the **olcLogLevel** attribute in the **cn=config** tree. This can be done as follows: auth1:~# ldapmodify -Y external -H ldapi:/// < Where olcLogLevel's old value is replaced with the new (in this case, **sync** and **none**). We actually have a logical OR going on here to report this. The possible logging levels available are: ^ int ^ hex and symbol ^ description | ^ 0 | (0x0) | logging is disabled | ^ 1 | (0x1 trace) | trace function calls | ^ 2 | (0x2 packets) | debug packet handling | ^ 4 | (0x4 args) | heavy trace debugging (function args) | ^ 8 | (0x8 conns) | connection management | ^ 16 | (0x10 BER) | print out packets sent and received | ^ 32 | (0x20 filter) | search filter processing | ^ 64 | (0x40 config) | configuration file processing | ^ 128 | (0x80 ACL) | access control list processing | ^ 256 | (0x100 stats) | stats log connections/operations/results | ^ 512 | (0x200 stats2) | stats log entries sent | ^ 1024 | (0x400 shell) | print communication with shell backends | ^ 2048 | (0x800 parse) | entry parsing | ^ 16384 | (0x4000 sync) | LDAPSync replication | ^ 32768 | (0x8000 none) | only messages that get logged whatever log level is set | ===Source of Information=== * http://www.techienuggets.com/Comments?tx=103265 (for the ldapmodify logic and ldif) * slapd-config(5) manual page (search for **olcLogLevel**) ====(uniqueMember) not indexed==== auth1 was spewing into the logs the following quite often: Dec 29 09:22:30 auth1 slapd[1236]: <= bdb_equality_candidates: (uidNumber) not indexed Dec 29 09:22:30 auth1 slapd[1236]: <= bdb_equality_candidates: (uidNumber) not indexed Dec 29 09:22:30 auth1 slapd[1236]: <= bdb_equality_candidates: (uidNumber) not indexed Dec 29 09:22:30 auth1 slapd[1236]: <= bdb_equality_candidates: (uidNumber) not indexed Dec 29 09:22:30 auth1 slapd[1236]: <= bdb_equality_candidates: (uidNumber) not indexed Dec 29 09:22:30 auth1 slapd[1236]: <= bdb_equality_candidates: (uidNumber) not indexed Dec 29 09:22:30 auth1 slapd[1236]: <= bdb_equality_candidates: (uidNumber) not indexed Dec 29 09:22:30 auth1 slapd[1236]: <= bdb_equality_candidates: (uidNumber) not indexed Dec 29 09:22:30 auth1 slapd[1236]: <= bdb_equality_candidates: (uidNumber) not indexed I resolved it by doing the following: auth1:~# ldapmodify -Y external -H ldapi:/// < This appeared to immediately resolve the problem. ===Source of Information=== * http://yetanotherubuntublog.blogspot.com/2010/03/bdbequalitycandidates-memberuid-not.html ====Viewing slapd settings==== It will likely be desired to view the settings in place on slapd, especially if we wish to change them, we need to know how to identify what we wish to change. The following will perform a dump (to STDOUT) of the **cn=config** database: auth1:~# slapcat -b cn=config | less We can then do a search for what it is we are interested in "dn: cn=config", "dn: olcDatabase={1}hdb,cn=config", "dn: olcOverlay={0}syncprov,olcDatabase={1}hdb,cn=config", etc. =====Packages===== At the end of the configuration process, the following packages have been installed on auth{1,2}: * lair-std lair-vm lair-ldap lair-nfs lair-autofs lair-mail lair-backup * ldap-utils slapd * ldapvi * ntp =====References===== ====Most Influential==== * http://www.rjsystems.nl/en/2100-d6-openldap-provider.php * http://www.rjsystems.nl/en/2100-d6-openldap-consumer.php * http://wiki.debian.org/LDAP/PAM ====Kerberos and LDAP (Debian Lenny)==== * http://www.rjsystems.nl/en/2100-d6-kerberos-openldap-provider.php (tested and works) * http://www.rjsystems.nl/en/2100-kerberos-openldap-provider.php * http://www.rjsystems.nl/en/2100-openldap-provider-kerberos.php (using an existing kerberos system) ====LDAP documentation==== * http://www.zytrax.com/books/ldap/ch6/slapd-config.html * http://www.zytrax.com/books/ldap/ch7/ * http://www.openldap.org/doc/admin24/access-control.html * http://www.yolinux.com/TUTORIALS/LinuxTutorialLDAP.html * http://www.yolinux.com/TUTORIALS/LinuxTutorialLDAP-LDIF-example1.html * http://www.rjsystems.nl/en/2100-d6-openldap-client.php ====PAM configuration==== * http://wiki.debian.org/LDAP/PAM * http://www.rjsystems.nl/en/2100-pam-debian.php * https://filer.case.edu/wiki/notes/linux_authentication ====Debian-specific information==== * http://www.rjsystems.nl/en/2100-d6-openldap-consumer.php * http://www.rjsystems.nl/en/2100-d6-openldap-provider.php * http://wiki.debian.org/LDAP ====Setting up LDAP==== * http://en.gentoo-wiki.com/wiki/OpenLDAP_Server_with_Mirrormode * http://tuxnetworks.blogspot.com/2010/06/howto-ldap-server-on-1004-lucid-lynx.html ====Configuring cn=config==== * http://www.zarafa.com/wiki/index.php/OpenLdap:_Switch_to_dynamic_config_backend_%28cn%3Dconfig%29 ====Replication==== * http://www.rjsystems.nl/en/2100-d6-openldap-provider.php * http://www.rjsystems.nl/en/2100-d6-openldap-consumer.php * http://www.fxp0.org.ua/2006/sep/22/ldap-replication-setup-using-syncrepl/ * http://www.openldap.org/doc/admin24/replication.html * http://itsecureadmin.com/wiki/index.php/OpenLDAP_Multi-Master_Replication * http://www.piirakka.com/misc_help/Linux/Slapd-Ldap/Openldap-mirror-mode-replication.html * http://blog.khax.net/2009/04/03/notes-on-ubuntu-810-serverguide-openldap/ * https://help.ubuntu.com/community/OpenLDAPServer