Wikis - Page

eDirectory Restoration – A Case of Perfect Replication of a Change

0 Likes

You’ve followed all the best practices and documentation. Your eDirectory trees are healthy and replicating with no errors. Time is in synchronization and ndsrepair shows no errors or external references hanging out there.

So, what do you do when eDirectory gets a request to remove 20,000 members from a group and replicates the change to all of the replicas?

What do you do when eDirectory has performed as designed?

Most people prepare for the more catastrophic scenarios. Loss of a replica server, synthetic time, hung replica add or delete. Search the eDirectory forums and that’s the usual “stuff” you see. Not, “Help! I just removed a bunch of stuff by mistake and I only have a server backup”

This document will walk you through the steps in restoring a single leaf object from a known backup of both eDirectory or a full server backup of a partition member server.

I will divide this into the two sections.

  • Restore a single leaf object from an eDirectory backup using ndsbackup
  • Reimport a leaf object from a server backup using an LDIF file

I mention both because I see more and more people who think that a server backup is sufficient to protecting eDirectory, compared to the addition of also performing an ndsbackup. Although, this is partly true, the time to restore between the two scenarios could determine whether you leave at the normal time or you’re calling your significant other to tell them you will “be here a while”.

Let’s look at the very simple solution of restoring from an ndsbackup first. This assumes that you actually have a recent ndsbackup.

Restore a single leaf object using the ndsbackup utility.

I use a script and cron to perform a full backup of eDirectory nightly, from the Master of the Root Partition. Due to disk space conservation, I retain the backup files and logs for 30 days. (the script I use is at the end of this document)

Use ndstrace and or iMonitor to ensure there are no errors in your tree. You might want to use iMonitor to view the object in question and note, screenshot, the Last
Modification Time and Last Modifier for forensic purposes.

In this example the Group, restoreme was last modified by Admin.

Open an SSH session and login to the server that backup was performed, usually the Master Replica server. Change to the directory where the backup file is located.

Before we restore the leaf object from the backup file, I want to mention one very important note that is not emphasized in the documentation or man file. In the command for restoring an object, you must put the Fully Distinguished Name (FDN) of that object at the end of the command.

# ndsbackup xvf ndsbackupfile –a admin-account.container –p passstore full-name-of-object
NOTE: If you omit the “full-name-of-object” at the end, ndsbackup will restore the ENTIRE tree!

For our example, we’re restoring cn=restoreme.ou=groups.o=Corp.
So our command would be:

# ndsbackup xvf ndsbackupfile.20101203 -a admin.Corp -p passstore cn=restoreme.ou=groups.o=Corp

[1] Instance at /etc/opt/novell/eDirectory/conf/nds.conf: myserver.OU=Servers.O=Corp.
MYTREE
x .CN=restoreme.OU=Groups.O=Corp.MYTREE
#

Verify the object has been replicated and to check the object while we’re SSH’ed to the server, run an ldapsearch to view the contents.

# ldapsearch -h localhost -x -D cn=admin,o=Corp -W -b o=Corp 'cn=restoreme'
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <o=Corp> with scope subtree
# filter: cn=restoreme
# requesting: ALL
#

# restoreme, Groups, Corp
dn: cn=restoreme,ou=Groups,o=Corp
owner: cn=admin,o=Corp
objectClass: groupOfNames
objectClass: Top
member: uid=user00,ou=People,o=Corp
member: cn=user01,ou=People,o=Corp
member: uid=user02,ou=People,o= Corp
member: cn=user03,ou=People,o=Corp
member: uid=user04,ou=People,o= Corp
member: cn=user05,ou=People,o=Corp
member: cn=user06,ou=People,o=Corp
member: cn=user07,ou=People,o=Corp
member: uid=user08,ou=People,o=Corp
member: cn=user09,ou=People,o=Corp
member: cn=user10,ou=People,o=Corp
member: uid=user00,ou=People,o= Corp

....
member: uid=user20122,ou=People,o= Corp
member: uid=user20123,ou=People,o= Corp
member: uid=user20124,ou=People,o= Corp
cn: restoreme
ACL: 2#entry#[Root]#member

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
#

And I’ve abbreviated the output to omit most of the 20,000 or so members.
Now that we’ve successfully restored the object and it is intact, run another full ndsbackup to be safe.

# ndsbackup cvf ndsbackupfile.20101205-1 -a admin.corp -p passstore [Root]

If you don’t know how to use the “-p passstore” option, see the man page for the ndspassstore utility.

Wasn’t too difficult was it?

Now let’s examine a restore of the same group object, but without an ndsbackup.

Re-import a leaf object from a server backup using an LDIF file

It is to be noted that my servers are virtual and the standard backups are performed using no special backup configuration or that the VMDK files are used. Restoring using a physical server may increase this process’ time considerably.

The Master of the Root partition server has a full backup as of the night before.

Because it is a virtual server, we can clone it with the following restrictions:

Once the server is cloned, do not power it on until you remove the Network Interface Cards in the virtual console manager. Remember that this clone is of the Master and it will try to synchronize with the other replicas, which would be bad. (I had it happen at another company. Very messy clean up)

Power up the cloned server and shutdown the eDirectory daemon. (ndsd). Once you verify it is not running, use “yast runlevel” or “chkconfig –del ndsd” to disable eDirectory from running on boot.

Then, using temporary IP addresses, re-add the NIC configure it for the restore.

Restore the DIBs to overwrite the existing. The default path is /var/opt/novell/eDirectory/data/dib/

Once the restore is complete, disable the NIC, but do not remove it, and ensure that the server cannot communicate on the network. We’ll need it to copy the LDIF files later.

Start the eDirectory daemon:

/etc/init.d/ndsd start

When it has completed loading, we’ll need to export the group object using LDAP.

Similarly to the ldapsearch command above that we used to verify that the members were present, we’ll need to redirect the output to a file that we can manipulate for the import into the tree.

# ldapsearch -h localhost -x -D cn=admin,o=Corp -W -b o=Corp 'cn=restoreme' > /tmp/restoreme.ldif
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <o=Corp> with scope subtree
# filter: cn=restoreme
# requesting: ALL
#

# restoreme, Groups, Corp
dn: cn=restoreme,ou=Groups,o=Corp
owner: cn=admin,o=Corp
objectClass: groupOfNames
objectClass: Top
member: uid=user00,ou=People,o=Corp
member: cn=user01,ou=People,o=Corp
member: uid=user02,ou=People,o= Corp
member: cn=user03,ou=People,o=Corp
member: uid=user04,ou=People,o= Corp
member: cn=user05,ou=People,o=Corp
member: cn=user06,ou=People,o=Corp
member: cn=user07,ou=People,o=Corp
member: uid=user08,ou=People,o=Corp
member: cn=user09,ou=People,o=Corp
member: cn=user10,ou=People,o=Corp
member: uid=user00,ou=People,o= Corp

....
member: uid=user20122,ou=People,o= Corp
member: uid=user20123,ou=People,o= Corp
member: uid=user20124,ou=People,o= Corp
cn: restoreme
ACL: 2#entry#[Root]#member

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
#

This file will need to be edited to remove everything after the final ”member: cn ….”

Also, ldapmodify or other import type utilities will not allow multiple modifications in a single command, meaning that each “member” you add to the group must be an individual LDAP request. Here’s what I mean:

Good LDIF

dn: cn=restoreme,ou=groups,o=corp
changetype: modify
add: member
member: cn=User00,ou=people,o=corp

dn: cn=restoreme,ou=groups,o=corp
changetype: modify
add: member
member: cn=User01,ou=people,o=corp

dn: cn=restoreme,ou=groups,o=corp
changetype: modify
add: member
member: cn=User02,ou=people,o=corp

Bad LDIF – Will error on second member.

dn: cn=restoreme,ou=groups,o=corp
changetype: modify
add: member
member: cn=User00,ou=people,o=corp
member: cn=User01,ou=people,o=corp
member: cn=User02,ou=people,o=corp
member: cn=User03,ou=people,o=corp

To make life much easier, use a text editor that supports macros and will modify each line to add the LDAP command parameters.

If you are going to import this LDIF file from the Linux command line, run dos2unix against it first to remove any “notepad” type characters that will cause errors.

Once you have your exports and are ready to copy them to the true Master for import, stop the eDirectory daemon.

# /etc/init.d/ndsd stop

Copy the file(s) to the target import server and then disable the NIC on the clone.

Once you’ve manipulated the LDIF file and are ready for import into the tree, use the following LDAP command or ICE in iManager or whatever LDAP tool you prefer. Command line ldapmodify will be faster.

# ldapmodify –c –v –h localhost –x –D cn=admin,o=corp –W –f /path/to/ldif-file/restoreme.ldif
Enter LDAP Password:

-c tells the utility to continue on error.
-v Verbose
-h Host
-x Use Simple Authentication
-D binddn – admin account
-W prompt me for the admin password
-f import file

Once complete, and depending on the number of entries to modify it might take a while, run an ndstrace and watch until the other replicas are “All Processed Yes”.

Perform an ldapsearch again and verify the members were imported. Or you can use iManager and look at the group, the Members Tab shows the total number of members.

Now I would suggest incorporating an ndsbackup into your daily backup regime. By the way, the above process took five hours to complete. The ndsbackup restore process took 8.47 seconds, including object synchronization.

Conclusion

Of course we know that backups are important and necessary for our customers’ livelihood. Supplementing your backups with an eDirectory ndsbackup will improve that livelihood in recovery, should you ever need it. Accidents do happen. We must be prepared to recover the missing data as quickly as possible while maintaining the integrity of the existing environment.

Enjoy.

Simple ndsbackup script to perform backups of eDirectory. Feel free to use it, improve it and share it.

/opt/novell/eDirectory/bin/edirbakup.sh

#!/bin/bash

timestamp="$(date '%m-%d-%I:%M')" #get timestamp to use on files

### Find eDirectory backup files and logs older than 30 days and delete them.
find /root/edirbak -type f -mtime 30 -exec rm {} \;
find /root/edirbak/log -type f -mtime 30 -exec rm {} \;

### Backup eDirectory (full) and save it to /root/edirbak/
## Change the admin account to match your env.

/opt/novell/eDirectory/bin/ndsbackup cvf /root/edirbak/ndsbackupfile.$timestamp -a admin.corp –p passstore [Root] >> /root/edirbak/log/edirback.$timestamp.log

exit 0
### End of edirbakup.sh

I add a cron job in root’s crontab to start at 12:01 AM

01 00 * * *     /opt/novell/eDirectory/bin/edirbakup.sh

--------------------------------
Editor's Note: When it comes to disaster recovery, Novell has some extraordinary offerings. Check it out.

Labels:

How To-Best Practice
Comment List
Related
Recommended