PAM Authentication for Apache, Trac and SVN

I’m going to describe how to get two of my favourite development tools, Trac and Subversion, to authenticate against PAM (Pluggable Authentication Module). For those who might not be familiar, Trac is a wiki that has integrated SCM and issue tracking. It’s written in Python and it’s incredibly useful. I’ve been using Subversion for version control for a long time and Trac is perfect for documenting a project as you go, and for keeping track of tasks and bugs. It’s access control settings allow you to specify levels of access for different users, so I often create one group for me and any other developers, and another group for my clients. The clients group can update the wiki, create tickets and get reports or look at milestones, etc. The developers group can administer all aspects of the site. Anyway, as useful as Trac and SVN are, I started to get really sick of handling authentication for them. I used to set up htpasswd files for each repository and wiki and it got to be a real pain, especially when I wanted my clients or developers to also have email, shell access, etc. So I decided to try and get mod_pam_auth working so I could use existing system accounts for Trac and Subversion access (over SSL of course).

mod_auth_pam is an Apache module that implements Basic authentication on top of the Pluggable Authentication Module. Unfortunately, as the project page says, the module is no longer being maintained which is unfortunate, but it works well enough with Apache 2.0.

Installing the module is pretty straightforward if you’re familiar installing Apache modules. I won’t go into too much detail, but as usual you’ll need to load the module in your Apache configuration:

LoadModule auth_pam_module modules/mod_auth_pam.so
LoadModule auth_sys_group_module modules/mod_auth_sys_group.so

Once that’s done you can easily set up basic authentication with PAM. Because Basic authentication involves sending a username + password combination in plain text, this setup should not be used without SSL. Within my VirtualHost configuration, I define separate location configs for each trac site and svn repository. It all looks something like this:

<VirtualHost 123.321.123.321:443>
    ServerName host.domain.tld
    SSLEngine On
    ...
    # Trac config
    <Location /trac>
       SetHandler mod_python
       PythonHandler trac.web.modpython_frontend 
       PythonOption TracEnvParentDir /var/lib/trac
       PythonOption TracUriRoot /trac
    </Location>

    <Location "/trac/tracsiteone/login">
       AuthPAM_Enabled On
       AuthType Basic
       AuthName "trac site # 1"
       Require user paul
    </Location>

    <Location "/trac/tracsitetwo/login">
       AuthPAM_Enabled On
       AuthType Basic
       AuthName "trac site # 2"
       Require group developers
    </Location>

    # Subversion config
    <Location /svn>
       DAV svn
       SVNParentPath /var/svn
       SVNListParentPath On
       SVNAutoVersioning On
    </Location>

    <Location "/svn/repositoryone">
       AuthPAM_Enabled On
       AuthType Basic
       AuthName "Repo # 1"
       Require user paul
    </Location>

    <Location "/svn/repositorytwo">
       AuthPAM_Enabled On
       AuthType Basic
       AuthName "Repo # 2"
       Require group developers
    </Location>
</VirtualHost>

So what we have now is two SVN repositories and two Trac wikis. For the first trac wiki and the first subversion repository, only the user 'paul' is given access. For the second, any valid user in the 'developers' group has access. Unfortunately there’s an issue with shadow passwords and this module and I’m not entirely happy with the work-around so I may have to edit this setup to use mod_authnz_external or maybe I’ll eventually move to LDAP. Regardless, I find this works well enough for now and saves a lot of hassle maintaining separate authentication files.

Tweet