Instructions for making Zenoss use LDAP or ActiveDirectory for user and role information.
Notes
Zenoss Enterprise Subscribers
The majority of the setup and configuration is handled by the Enterprise ZenPacks installation. Please follow the updated directions in our Extended Monitoring Guide under the section "LDAP Authentication", or in the Enterprise Knowledge Base on the Support Portal.
Zenoss 3.x Users
A few new steps are needed for Zenoss 3.x and these are located here: Ubuntu 10.04, Zenoss 3.0, LDAP Use that link, along with the below information.
TODO: any community member who wants to join the information on the link above, into this doc, is encouraged to.
Introduction
Zenoss is built using Zope. Zope contains plugins for all aspects of authentication and authorization. We will install two plugins (LDAPUserFolder and LDAPMultiPlugins) which will enable this functionality and then we will configure the Zenoss Zope instance to use these plugins.
Note that this HowTo does not touch upon storing Zenoss data in an LDAP server (that requires some Zenoss hacking). The purpose of this HowTo is to address authentication and authorization (via roles) only.
Further note that this HowTo assumes that you are using RHEL/CentOS 5 or greater and that you have installed Zenoss via the available RPMs.
Theory
Before we get started, it will help to get a little theory out of the way. What is authentication? What is authorization? How are the different?
- Authentication is the process that identifies the user and verifies this identity.
- Authorization is the process which takes the identity and determines what a user has permission to do
In this tutorial we will first discuss how to setup authentication against LDAP and then you can optionally map certain users in your LDAP server to particular Roles in Zenoss. This allows some of your LDAP users to have different privileges than others.
Backup
Before making any changes, we will back up our current zope database (as root):
service zenoss stop
cp /opt/zenoss/var/Data.fs /opt/zenoss/var/Data.fs.bak
service zenoss start
Installation
NOTE: If you are an Enterprise user and have the LDAPAuthenticator ZenPack installed, you can skip to the Configuration section of this guide.
Download LDAPMultiPlugins and LDAPUserFolder (LDAPMultiPlugins-1.7.tgz and LDAPUserFolder-2.12.tgz)
As the zenoss user:
tar -zxvf LDAPUserFolder-<version>.tgz -C $ZENHOME/Products
tar -zxvf LDAPMultiPlugins-<version>.tgz -C $ZENHOME/Products
Install python-ldap
The last thing we need to install is python-ldap. However, this is a bit tricky. You will need to use one of the following mechanisms, based upon how you installed Zenoss.
Native RPM(s) (non RHEL5)
As root:
yum install python-ldap
Native RPM(s) (RHEL5 or derivative)
As root:
yum install openssl-devel openldap-devel
As zenoss user:
Download python-ldap-2.3.13 (do not install newer version as dependencies will fail)
Untar downloaded package, cd to its directory, and execute "python setup.py install"
Zenoss Appliance
As root:
conary update python-ldap=contrib.rpath.org@rpl:1
Stack Installer
The stack installer provides its own version of python. Because of this, you will need to install python-ldap from source.
Download the latest version of python-ldap from: http://python-ldap.sourceforge.net/download.shtml
We need to install python-ldap from source as it needs to be in the zenoss user's site-packages directory at $ZENHOME/lib/python2.4/site-packages. If you install python-ldap as root, it will live in your OS installation's site-packages directory, not the zenoss user.
*Note - python-ldap will require openldap2-devel in order to build.
As root:
yum -y install openldap2-devel
As zenoss user:
tar -zxvf python-ldap-<version>.tar.gz
cd python-ldap-<version> && python setup.py install
Some users on 64-bit systems may need to execute the following commands to get the plugins to show up in Zope:
ln -s /usr/lib64/python2.4/site-packages/ldap/ /usr/local/zenoss/python/lib/python2.4/site-packages/
ln -s /usr/lib64/python2.4/site-packages/ldapurl.py /usr/local/zenoss/python/lib/python2.4/site-packages/
ln -s /usr/lib64/python2.4/site-packages/ldapurl.pyc /usr/local/zenoss/python/lib/python2.4/site-packages/
ln -s /usr/lib64/python2.4/site-packages/_ldap.so /usr/local/zenoss/python/lib/python2.4/site-packages/
Stack Installer on Ubuntu 8.04
In summary, you need to link in the distribution's installed python-ldap components into the site packages path for Zenoss's local Python 2.4 runtime and compile them. Here are the steps (these assume you have already downloaded and placed the LDAPUserFolder and LDAPMultiPlugins packages in the path identified in the wiki instructions):Install python-ldap
(As root)
Link python-ldap components to Zenoss's site packages path
aptitude install python-ldap
We need the _ldap.so binary compiled against Python 2.4 and the source files. As the zenoss user:
Compile .py files
#The Zenoss local Python site package path is $ZENHOME/lib/python!
cd $ZENHOME/lib/python
mkdir ldap
mkdir ldap/schema
ln -s /usr/share/pyshared/ldif.py
ln -s /usr/share/pyshared/ldapurl.py
ln -s /usr/lib/python2.4/site-packages/_ldap.so
cd ldap
ln -s /usr/share/pyshared/ldap/async.py
ln -s /usr/share/pyshared/ldap/controls.py
ln -s /usr/share/pyshared/ldap/filter.py
ln -s /usr/share/pyshared/ldap/__init__.py
ln -s /usr/share/pyshared/ldap/modlist.py
ln -s /usr/share/pyshared/ldap/cidict.py
ln -s /usr/share/pyshared/ldap/dn.py
ln -s /usr/share/pyshared/ldap/functions.py
ln -s /usr/share/pyshared/ldap/ldapobject.py
ln -s /usr/share/pyshared/ldap/sasl.py
cd schema
ln -s /usr/share/pyshared/ldap/schema/__init__.py
ln -s /usr/share/pyshared/ldap/schema/models.py
ln -s /usr/share/pyshared/ldap/schema/subentry.py
ln -s /usr/share/pyshared/ldap/schema/tokenizer.py
Now that we have the files linked in from the global shared Python path (where the python-ldap deb installer put them), we need to compile all of the .py files using Zenoss's local python 2.4 installation:
cd $ZENHOME/lib/python
python /usr/local/zenoss/python/lib/python2.4/py_compile.py ldif.py
python /usr/local/zenoss/python/lib/python2.4/py_compile.py ldapurl.py
cd ldap
python /usr/local/zenoss/python/lib/python2.4/py_compile.py *.py
cd schema
python /usr/local/zenoss/python/lib/python2.4/py_compile.py *.py
Finally
Restart zope to make sure the changes have taken effect:
zopectl restart
Configuration
Everything should be installed at this point, so we just need to configure it. We will do this in several steps:
Login to http://zenoss_srv:8080/zport/manage as an administrator. Here you will notice two frames (called "left frame" and "right frame" from here on).
First, click "acl_users" in the left frame. This will load acl_users into the right frame. In the right frame, choose "Import/Export" and follow the instructions to perform an export. This will backup your current authentication/authorization scheme.
After exporting acl_users, you will be back at the acl_users object. In the upper right corner, next to "Add", select one of the Multi Plugins. If you are using ActiveDirectory, choose "ActiveDirectory Multi Plugin". Otherwise, choose "LDAP Multi Plugin".
ID: ActiveDirectory
Title: ActiveDirectory Authentication
LDAP Server: dc.domain.local (or just domain.local to use AD's round-robin DNS)
Use SSL: yes (or no if your setup doesn't support SSL) *see note (1)
Read-only: yes
Login Name Attribute: sAMAccountName
User ID Attribute: sAMAccountName
RDN Attribute: sAMAccountName
Users Base DN: OU=Users,DC=domain,DC=local
User password encryption: SHA
Manager DN:
Password:
User password encryption: SHA
Otherwise, do this for a normal LDAP setup:
ID: LDAP
Title: LDAP Authentication
LDAP Server[:port]: ldap.domain.local
Use SSL: yes (or no if your setup doesn't support SSL) *see note (1)
Read-only: yes
Login Name Attribute: uid
User ID Attribute: uid
RDN Attribute: uid
Users Base DN: OU=People,DC=domain,DC=local
Manager DN:
Password:
User password encryption: SHA
Now you have two choices to make. The first one is this: What role(s) should ALL LDAP/ActiveDirectory users have? This takes a bit of knowledge about Zenoss. However there are three common scenarios:
- LDAP users should have no privileges, unless explicitly granted otherwise:
Default User Roles:
- LDAP users should have read-only permission, unless explicitly granted otherwise:
Default User Roles: ZenUser
- LDAP users should have full permissions:
Default User Roles: Manager
The second choice you need to make is this: will you be using LDAP/ActiveDirectory to indicate what Roles a user has? If so, also set the following:
Group storage: Groups stored on LDAP server
Groups Base DN: OU=Groups,DC=domain,DC=local
Otherwise, do this:
Group storage: Groups not stored on LDAP server
Groups Base DN:
Finally, click Add. You will be taken back to the acl_users screen. We will now enable this plugin. Click on the plugin instance (named "LDAP" or "ActiveDirectory") and check Authentication and User_Enumeration, then click "Update".
If you didn't enable Groups stored in the LDAP server above, you are done!
If you enabled Groups stored on LDAP server above, first, enable Roles on this screen. Next, we will setup our Group/Role mappings. Click on the "Contents" tab at the top of the right frame. Select "acl_users" in the right frame. Make sure that "Group mapping" says "Manually map LDAP groups to Zope roles" (apply changes if necessary). Then, click on the "Groups" tab at the top. It should now list all the groups from your LDAP server. Go down to the section "LDAP group to Zope role mappings". This is where you add the configuration that says "If a user is in a certain group, add them to this role." I can't give more details here, because this is custom to your setup. Once you've done this, you should be done!
Enabling Caching
LDAPMultiPlugins has the ability to cache expensive LDAP look-ups and other operations. This ability, however, is not enabled by default. To enable caching:
- Login to the ZMI (Zope Management Interface) at http://servername:8080/zport/manage
- Click on 'acl_users(PAS)' from the center pane or the top-level 'acl_users' from the left navigation pane
- From the drop-down list in the upper right, select 'RAM Cache Manager' and click add.
- Give the RAM Cache Object a name; e.g. - LDAP Cache
- Click on the newly created object to configure it
- Tweak the properties as needed
- Click on the 'Associate' tab
- Click 'Locate'
- Your LDAPMultiPlugins object (whatever you named it) and userManager will appear as objects that you can associate with the RAM Cache.
- Check your LDAPMultiPlugin object and select 'Save Changes'.
Caching is now enabled for LDAP.
Fetching User Settings from LDAP
So now we have a functional LDAP authentication and authorization, what about retrieving default user values (such as email address, pager number, etc) from LDAP? This is possible as of Zenoss 2.2, however there are some caveats.
Architecture
In Zenoss, when an LDAP user logs in for the first time, a UserSettings object is created. This object stores all the users settings. As of Zenoss 2.2, during the UserSettings object creation process, user settings are copied from LDAP into the UserSettings object. Please note that this process WILL NOT modify the UserSettings object after its creation, so the values in LDAP only serve as defaults: changing the values in LDAP after the user has logged in will do nothing! Be forewarned...
Enabling LDAP Attribute Matching
Go to http://zenoss_srv:8080/zport/manage and, in the right frame, click on "acl_users", then "LDAP" (or "ActiveDirectory"). On this screen make sure "Properties" is enabled. Next, click Contents, then "acl_users", then "LDAP Schema". On this screen you are able to setup mappings between values in LDAP and the names in the UserSettings object. As of now, the current UserSettings values available for configuration are as follows:
pager
defaultPageSize
defaultEventPageSize
defaultAdminRole
defaultAdminLevel
oncallStart
oncallEnd
escalationMinutes
dashboardState
dashboardRefresh
dashboardTimeout
dashboardOrganizer
netMapStartObject
Notes
- In case you want a secure LDAP connection and your LDAP server is using a certificate issued by "untrusted" certificate authority or a self-signed certificate and you're getting errors similar to "SSL3_GET_SERVER_CERTIFICATE:certificate verify failed", follow this procedure in order to make python-ldap accept the certificate:
- Find openldap's client settings file. Usually, it's named ldap.conf. For RHEL setups, it's located at /etc/openldap/ldap.conf.
- Ensure it contains TLS_CACERTDIR setting, for example "TLS_CACERTDIR /etc/openldap/cacerts" on one line.
- Place your CA certificate in PEM format into TLS_CACERTDIR directory. For ex.: cp /root/mycacert.crt /etc/openldap/cacerts/;
- Hash it so that openldap/openssl can find it: cd /etc/openldap/cacerts/; ln -s mycacert.crt `openssl x509 -hash -noout -in mycacert.crt`.0
- Attention here. If openssl version is >= 1.0, it's using a new hash algo, so you might want to use "-subject_hash_old" instead of "-hash". If in doubt, create both symlinks.
- Test the connection with zenoss's supplied python interpreter on file src/demo.py in python-ldap source package. Don't forget to supply your own ldap server address and comment out "CACERTFILE" setting in that file.