Subversion over WebDAV + LDAP authentication

There weren’t too many resources on setting up this specific configuration on the web (and some were plain incorrect) so I decided to post my own configuration for the glory of mankind.

What I wanted to do, was to have my SVN repository accessible using my freshly setup LDAP directory usernames and passwords. Svn’s-own auth is not a perfect one, it’s impossible for the user to change the password, and it’s yet another separate user db in the end. Also, if sent over https the traffic will be encrypted, so your now-precious – as system-wide – passwords won’t be sent over the line in clear text.

Apart from that, I already set up bugzilla with LDAP auth, and SVN would add to that nicely.

First thing I did was to set up a regular WebDAV resource protected by LDAP login. At the time of writing this article, I’m running Apache 2.2.16 on Debian 6.0.2 (squeeze), and among other modules, I have dav_fs, dav, and dav_svn modules enabled. I also have the subversion package installed.

[adsense]
Inside one of my virtual host directives I put a Location, like so:

<Location /testit>
Order allow,deny
allow from all
Dav on
AuthType Basic
AuthBasicProvider ldap
AuthName "Access allowed only for LDAP-authenticated users of el-kfa.net domain."
AuthLDAPURL "ldap://192.168.0.1/ou=People,ou=auth,dc=el-kfa,dc=net?uid"
Require valid-user
</Location>

I made a few errors on my way there. For example I had AuthType Simple instead of Basic, or just Basic without specifying the AuthBasicProvider, and apache messages are not always very useful in this regard.

As soon as I had the regular WebDAV running fine, I updated it with the SVN setting:

SVNPath /var/svn/testit

And created the svn repo on the server:

# cd /var/svn
# svnadmin create testit
# chown -R www-data testit

I restarted apache, and tried to check-out the repo it sort if worked:

$ svn checkout http://svn.example.com/testit
(password request, password typed in)
svn: The OPTIONS response did not include the requested activity-collection-set; this often means that the URL is not WebDAV-enabled

I tried googling for it, but I mostly got wrong answers. I compared what I had with one more HOWTO, and finally discovered that Dav should be set to “svn”, not “on”. So the final configuration that works for me is:

<VirtualHost *:80>
ServerAdmin webmaster@example.com
ServerName svn.example.com
ErrorLog /var/log/apache2/svn.example.com-error_log
CustomLog /var/log/apache2/svn.example.com-access_log combined

<Location /testit>
Order allow,deny
Allow from all
SVNPath /var/svn/testit
Dav svn
AuthType Basic
AuthBasicProvider ldap
AuthName "Access allowed only for LDAP-authenticated users of example.com domain."
AuthLDAPURL "ldap://192.168.0.1/ou=People,ou=auth,dc=example,dc=com?uid"
Require valid-user
</Location>
</VirtualHost>

´╗┐Now svn checkout asked for the right password and worked beutifully. Next thing to have was a group-level access control, instead of just letting any LDAP user in. Setting LogLevel debug inside the <VirtualHost> helped greatly. Without it we’re pretty much in the dark. For example group specs didn’t work for me, because I enclosed them inside quotation marks whereas they should be just left as they were, without. Another thing to note, is that there should not be a DocumentRoot statement in the VirtualHost directive, or Apache will get confused and you will get:
Error: Repository moved permanently to 'http://svn.example.com/tesit'; please relocate, which again, is not a very usefull error message.
I also wanted to have access to all my repos under one address, so I changed SVNPath /var/svn/testit to SVNParentPath /var/svn.

[adsense]
So my <Location> ended up looking like this:

<Location />
Order allow,deny
Allow from all
SVNParentPath /var/svn
Dav svn
AuthType Basic
AuthBasicProvider ldap
AuthName "Access allowed only for LDAP-authenticated users of example.com domain."
AuthLDAPURL ldap://192.168.0.1/ou=auth,dc=example,dc=com?uid?sub
AuthLDAPGroupAttribute memberUid
AuthLDAPGroupAttributeIsDN off
Require ldap-group cn=svn,ou=Group,ou=auth,dc=example,dc=com
Require ldap-attribute gidNumber=200
</Location>

And now only the members of the group svn (gid=200) are allowed to access the repository. And that concludes the setup.
One particular resource which was very helpful to me was:

http://www.yolinux.com/TUTORIALS/LinuxTutorialApacheAddingLoginSiteProtection.html

I also wanted to have access to all my repos under this address, so I changed SVNPath to SVNParentPath.