Apache2 + Trac + LDAP authentication

Setting up Python easy_install:

Trac is a Python project, and if you are familiar with Python, you probably know about “easy_install”. This is a light package-management utility to easy some of the installation woes associated with software installation. Using “easy_install”, a Python project can distribute as source code, and compile against your version of Python, and install to a global Python cache. This would be very roughly analogous to “apt-get” for Debian and derivatives, or even “gem” for Ruby. The benefit is you have the most current version at the time of install, and are not limited by the version that your distribution may offer through their package management program. This can potentially cause conflicts, so weight the option carefully. Good articles comparing “easy_install” with “apt-get” can be found here, and here.

To install using “easy_install”, you will need the Python setup tools package. This can be downloaded and installed by hand, but don’t be silly. Just “apt-get install python-setuptools“. You will also need Python as a prerequisite to this package, and at the time of writing this, 2.4 is the most current version in Debian Etch.

Setting up Trac:

Next we need to get the Trac source code (if you go the “easy_install” route). Extract your source package, and inside, locate the “setup.py” package. This is the starting point. Run this with Python like so: python setup.py bdist_egg

This will create a distribution agnostic package called a Python Egg. Get it? Snakes, eggs… Anyways, This egg file is what “easy_install” handles for us. Execute the command “easy_install dist/Trac-0.11-xxx” where “xxx” is the exact build name of your Trac egg. This will copy the egg file over into a global python cache. On Debian this is “/usr/lib/python2.4/site-packages/”.

Running Trac through Apache2:

Trac can be run in stand-alone mode or through Apache. We used to go with standalone because bang, boom, you are done. However, as our requirements grew, we found it easier to go with Apache so that we can tap into our campus LDAP server. This way we eliminate the need for the “user.htgigest” file, with yet another set of arbitrary credentials.

Make sure that you have Apache2 installed, as well as the modules for python. On Debian, this can be accomplished by running:

apt-get install libapache2-mod-python libapache2-mod-python-doc

This will automatically load the modules into the Apache configuration as well, and will prompt you to restart the server to take effect. Patience young grasshopper – we will restart in a moment.

Next, lets create a new site, “sudo cp /etc/apache2/sites-available/default cp /etc/apache2/sites-available/trac“, or something to that extent. This will setup a new VirtualHost directive that you can then do with as you please. You will need to enable this new site configuration by executing “sudo a2ensite trac“.

In the VirtualHost context, copy the following:

NameVirtualHost *

  <VirtualHost *>
    <Location />
      SetHandler mod_python
      PythonInterpreter main_interpreter
      PythonHandler trac.web.modpython_frontend
      PythonOption TracEnvParentDir /var/trac/
      PythonOption TracUriRoot /

If you have setup Apache VirtualHost files before, this syntax should be familiar. You have a location inside your VirtualHost, and some directives to tell Apache that this is a Python project. The options starting with Python… are actually variables being sent to the Python environment.

I have multiple Trac projects, and the root is at “/var/trac/”. Suite yours to taste, and restart Apache with this new configuration. In this setup, my location is “/” meaning the root of my website should now show a list of available projects for Trac. Ensure that this is the case.

If you run into issues, you can add “LogLevel debug” to the VirtualHost context, and follow the file “/var/log/apache2/error.log” for more information if you run into issues.

Once Trac works (minus the “Login” bit), then its time to drop LDAP into this motha’.

Integrating LDAP with Apache and Trac:

In your same VirtualHost container, append the following code in the Location context:

Order deny,allow
Deny from all
Allow from
AuthType Basic
AuthName "Trac"
AuthBasicProvider "ldap"
AuthLDAPURL "ldap://your.ldap.instance:389/OU=Departments,DC=ccsunet,DC=clayton,DC=edu?sAMAccountName?sub?(objectClass=user)"
AuthLDAPBindDN "full,path,to,user"
AuthLDAPBindPassword "password"
Authzldapauthoritative Off
Require ldap-attribute memberOf="CN=CTS_Administrative Systems,OU=Administrative Systems,OU=Communications & Technology,OU=Office of Information Technology and Services,OU=Departments,DC=ccsunet,DC=clayton,DC=edu"

Lets start from the top:

Order deny, allow, Deny from all, Allow from… are all directives to control access to content. Here I have locked our site down to a range of IP address to limit access to just on campus. (Actually our firewall does this as well, but it makes me feel better to have it here too).

AuthType, AuthName, AuthBasicProvider instruct our project that LDAP will be the authoritative source for our Trac installation.

AuthLDAPURL is the address of your LDAP instance. Port 389 is standard, but you  can change it if needed. Also, we have spaces in our LDAP addresses, so I contain them inside double-quotes, despite the warnings not to do so in the Apache2 mod_authnz_ldap documentation. Another note: Apache could not find users in the default directory of LDAP. We had to specify “OU=Departments” to get it to find anyone. The ?sub bit is supposed to recursively check the LDAP trees, but no dice. Just put this and move on. sAMAccountName, as you probably know is the Microsoft LDAP Active Directory naming convention for the unique identifier. If you are not using AD, you may go with uid, or something similar.

AuthLDAPBindDN, and AuthLDAPBindPassword are a read-only account to access and search the LDAP tree with. You should have some kind of reader account information here.

Authzldapauthoritative allows fallthough authentication if provided. In other words, this makes failing LDAP not truly fatal.

Require specifies a ruleset for things to check for even if the user was successful in providing a correct combination of credentials. This is how you can restrict access to a subset of people. The options that you can use here is pretty awesome – just take a look at the official docs. I use ldap-attribute to check if they belong to our department.

After you specify all of this, restart Apache2 and nagvigate to your URL. With any luck, you will get a prompt from Apache2 for a username and password, and with even more luck, it will only accept a valid combination of credentials.

To troubleshoot here, remember to set your VirtualHost to LogLevel debug and tail your “/var/log/apache2/error.log” file for all the nitty-gritty details.

Good luck!


Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.