eDirectory supportconfig plugin

The supportutils RPM (part of SLES and OES) is a great default RPM to have for troubleshooting all kinds of Linux issues.  The supportconfig tool, contained within that RPM, is made to gather information on all facets of SLES, and has been including OES and other Novell product data gathering features over time.  Lately the solution has also included functionality to allow plugins to be trivially added, using a variety of scripting languages trivially, to extend the supportconfig utility and gathered data to support anything imaginable.

While the supportconfig utility currently implements functionality to gather some basic eDirectory data, it is capable of doing a lot more.  To that end, I have built a plugin that is dedicated to zooming in on what eDirectory really has available to offer from the command line.  Included in this is the ability to easily handle multiple instances, check data within eDirectory using some authentication options, and of course running a variety of commands available to get general eDirectory information to speed up issue resolution times.

To use the script one simply needs to have the supportutils package present on a server with eDirectory, and then to extract the attached file (edirectory.bz2) to the /usr/lib/supportconfig/plugins directory.  Eventually I'll package this in its own RPM, but for now extracting the script on its own is fine.  Be sure to make it executable using the following command:
chmod  x /usr/lib/supportconfig/plugins/edirectory

With that done, simply run supportconfig and notice that additional information is gathered about the eDirectory environment in a new file called plugin-edirectory.txt contained within the resulting supportconfig data archive.  Now that the basics are figured out, let's get into some advanced functionality.  Because this tool is made to gather as much information as possible from eDirectory I decided to configure it to, optionally, authenticate to the directory to retrieve additional information.

There are a few caveats to how this works.  First, because authentication usually happens with usernames/passwords, keep in mind that this requires some understanding of how to keep credentials safe.  The script, by default, sets the file with credentials as accessible to only the 'root' user.  If somebody somehow figures out how to control the 'root' user then the entire system (including the eDirectory DIB with enterprise-wide information) is lost anyway, so this is not an additional security risk.  Along with this I highly encourage creating a new user to be used by the plugin, even though using the tree 'admin' will work by default; the reason for this recommendation is that a new user can be setup which is very limited (no ability to write/modify/delete anything) so that if somebody with server 'root' access reads the file with credentials somehow then nothing of value is lost (no ability to retrieve passwords, modify other users/groups/containers, set ACLs, etc.).  Rights required are simple to setup and covered later.

A common concern at this point is around these credentials.  If stored on a system, they should be encrypted, people often argue.  I agree with that to a point, but have not implemented that yet for a couple of reasons:

1.  It does not help things.

2.  It took more time than I wanted to invest for a first version of the plugin.

What do I mean by it does not help things?  When you think about how stored credentials are retrieved, it should quickly become evident that the only way to retrieve saved, encrypted credentials, is by having the password/passphrase/private-key also saved somewhere that the script can easily use without user interaction.  If the script can do this, so can anybody else with permissions (the utility already runs as 'root', so there are no system ACLs to slow down a real user while allowing the script to do things).  The reason hashing of passwords is more-secure for things like authenticating directly to the Linux system (in the /etc/shadow or /etc/passwd file) is because hashing, not reversible encryption, is used.  Reversible encryption is required in the plugin's case since the plaintext password is required to be sent to eDirectory to do the data gathering.  As a result of this the only option that seems feasible is to store the password in the clear as has been implemented, and then to recommend creating a basic proxy user which then does not have the ability to do "Bad Things" (tm) in the first place.  Eventually I'll probably add options to use gpg or  openssl to somehow encrypt the password, but it won't do anything more than slow down somebody who can read the file no matter what the value.  Another option may be to have the passwords be prompted-for during plugin execution, though that means a lot of user interaction and may not work in the supportconfig architecture.

In order to configure authentication to eDirectory a -genpropfile argument can be passed to the script.  For example, run the following as 'root':
/usr/lib/supportconfig/plugins/edirectory -genpropfile

The script will then prompt for configuration data for any configured instances.  This will include an IP address and port used for connection, username (LDAP format) used for binding, and a password for that user.  It also asks about what to do if the eDirectory instance is down when the script runs, primarily for clustered setups where this node's eDirectory instance may be legitimately stopped for periods of time while other nodes host the running instance.  When finished the script writes its own properties file and sets permissions to make it as secure as possible by default.  If the properties file is generated again the current version is renamed but kept around in case something is forgotten going forward.  The method used to generate the properties file can also allow free-form entry of all information, including the nds.conf file which configures an eDirectory instances.  Verification of the nds.conf file's existence takes place in this case to ensure that there was not a typo when specifying the data.  When passwords are entered for authentication the credentials are tested using the ndslogin command to ensure that they are correct.  For this reason, the password is only requested once and, if incorrect, can be entered again.  Note that currently the script only supports IPv4 addresses.

The properties file itself is basically a shell script that should NOT be executable.  It is sourced by the 'edirectory' plugin script but if made executable, as it resides in the same directory as the plugin itself, supportconfig may try to run it as a plugin directly (undesirable as it is not a plugin, but is a plugin's properties file).  Still, for those familiar with bash scripting, the edirectory.properties file contents are simple to understand as setting up an array of values for the various eDirectory instances on the system.

The full edirectory plugin is also merely a bash script.  Reviewing the code, or watching it execute, can be done simply using a favorite text editor or running the plugin in debugging mode as shown below (as the 'root' user), respectively:
bash -xv /usr/lib/supportconfig/plugins/edirectory

When executed as part of supportconfig all output from a plugin is written in the supportconfig tarball archive as plugin-<scriptname>.txt, and this plugin is no exception.  The 'plugin-edirectory.txt' file is created with the output from the script; if executed on its own all output is written to STDOUT so it will show up on the screen.  Feel free to redirect the output to a file, or if you have a large enough shell buffer then you can scroll back to see the output.  If using debugging mode (see above) the output grows considerably, so keep that in mind if using a shell/terminal with a small buffer.

In order to be as secure as possible, even though the connection is normally made to the local system from the script (no across-the-wire connections unless configured by the administrator for some reason), LDAPS is used for authentication.  In order to do this the script dynamically retrieves the certificate from the LDAPS interface and then uses that via the ldapsearch command in order to retrieve data directly from eDirectory.   This ensures that the passwords used are encrypted on the wire, or at least going from the local system to the local system's listening LDAPS socket, and may be required in environments where clear text authentication is not allowed.  The script also tries using TLS (via STARTTLS) if using the cleartext port, so only after both of these options fail will it try a direct, cleartext connection (which is, by default, not allowed in eDirectory).  The certificate output is stored in the /tmp directory and survives beyond the execution of the script itself, though this is public information and not required to be secured in any way.

Passwords used by the system should NEVER appear in the plugin's output.  Some fun hacking with environment variables is used so that while the complete command for things using passwords are shown, the password is never revealed in the output.  This is in line with the normal setting of supportconfig generally in that it never retrieves passwords from any part of the analyed system.

The LDAP output, in case somebody peers closely, is unfolded by default.  Normally LDAP output is "folded" meaning at about seventy-eight characters the line is split and moved to the subsequent line and prepended with a single space (0x20) to indicate it is a folded line.  Because this can interfere with subsequent analysis in an automated way (a desire of subsequent tools that use the output from this plugin) I have used a bit of 'sed' to unfold the lines on the fly.  Line folding is done for convenience and LDAP servers should take unfolded data without any problems; some ldapsearch clients actually have an option to set the number of characters at which a line will be folded, including disabling folding altogether.  For more details on line folding see the LDAP RFCs.

Throughout the plugin, including when requesting credentials from the -genpropfile parameter, conversion of the specified or discovered DNs takes place from LDAP to NDAP or vice versa.  The code that does this is decent and works for several combinations of complex, unlikely-to-be-seen, usernames, but it may not be foolproof.  If problems arise where the conversion does not work properly for a given object please submit that DN as an example where the code needs to be updated.  Updated code examples are appreciated if you have the time/ability.  Similarly, passwords throughout the tool, when used, are wrapped in double-quotes.  As a result if a password uses double-quotes or other bash special characters the script will likely fail at some point.  I may fix this at some point, but since I strongly recommend creating a proxy user for use with this plugin I would also strongly recommend using a complex password that does not include any of the following characters:
$ - dollar sign

` - backtick

" - double-quote

' - single-quote; this is really probably fine, but I have not tested it extensively-enough yet

\ - backslash

Creating sufficiently complex passwords should still be possible, such as the following password example which is long, complex, and includes a variety of types of characters:

Finally, regarding permissions of the user used for authentication, a few points come to mind.  First, the plugin looks for collision rename objects, so being able to browse the entire tree (or at least any part where looking for these objects, or other types of objects for troubleshooting purposes) is desirable.  Having browse rights to the tree is usually a given, but locked-down environments may have this revoked.  If so, or if IRFs block rights at some point, please make sure that the proxy user has rights to browse the entire tree.  Also, the user should have the ability to read the 'CN' attributes on all objects, which is not a default.

Next the user should be able to see the Object Class of all objects in the tree.  By default this is normally given to anybody, but again a locked-down tree may have this revoked.  Further, it is highly recommended, for any eDirectory environment whether using this script or not, to have 'Object Class' indexes of the 'Value' type defined on all servers.  This will increase performance of all types of applications from the IDM plugins through tools that are generally used in eDirectory via LDAP or NDAP.  Defining this index is safe but sometimes incorrectly requires a restart of eDirectory for some reason.  If not implemented then searches for objects by class will take substantially longer, but will still work in default cases.

Finally the proxy user should have the ability to read all attributes on the NCP Server object for which it is gathering data.  It should also be able to read the 'LDAP Group'  attribute from the linked LDAP Server object, and should be able to read all attributes on the linked LDAP Group object.  The script will not fail without these, but it will also not gather information fully without these options.  A helpful test may be to ensure that the proxy user can run the `ldapconfig get` command from the command line for any desired eDirectory instances, and still get the exact same output as the command returns when using the tree administrative user.


Comment List