Subversion Installation and Configuration

[TOC]

Host is svn.example.com. There are basically two ways of serving up
a subversion repository. One uses svnserve, a lightweight server
(default port 3690). The other is leveraging Apache (httpd) via the
WebDAV protocol.

The latter is more complex. But it is extremely flexible in terms of
administration and is the basis for this setup guide. I will be setting
up a single repository at https://svn.example.com/repository with SSL,
LDAP-based authentication, and project-specific access control.

Installation

Getting the RPM

I’m putting the SVN root in /home/svn as well. This can be anywhere.

yum install subversion mod_dav_svn

This will install Apache and other dependencies as well.

service httpd start  
chkconfig --level 345 httpd on

Make sure it’s working, and that iptables is not causing any issues.
You can use nmap for this purpose or just go to
http://svn.example.com.

Preparing subversion.conf

Installing the packages will create a new apache configuration directive
in /etc/httpd/conf.d called subversion.conf. You need to edit this
file to set up the location of the repository.

First uncomment these files if they’ve not been uncommented:

LoadModule dav_svn_module     modules/mod_dav_svn.so  
LoadModule authz_svn_module   modules/mod_authz_svn.so

Define the SVN root:

<Location /repository>  
        DAV svn  
        SVNPath /home/svn/repository  
</Location>

Now you can add simple authentication or use LDAP.

Configuration

Simple Authentication

This uses basic htpasswd based authentication. Passwords may be sent
in the clear if you don’t enable SSL. You can also use digest-based
authentication which is slightly more secure.

For this scheme, our /etc/httpd/conf.d/subversion.conf file will have
the following directive:

<Location /repository>  
        DAV svn  
        SVNPath /home/svn/repository  
          
        # Simple authentication  
        AuthType Basic  
        AuthName "SVN Server"  
        AuthUserFile /home/svn/basic-authentication  
        Require valid-user  
</Location>

Here, we use /home/svn/authorized-users to authenticate. Create this
file and add a user with:

[root@svn ~]# htpasswd -cm /home/svn/authorized-users testuser  
New password:   
Re-type new password:   
Adding password for user testuser

Setting up the repository

svnadmin create /home/svn/repository

Make absolutely sure that Apache owns this directory and its
descendants!

chown -R apache:apache /home/svn/repository

Testing the Configuration

At this point, you should have a repo accessible via Apache, with
password sent in clear text (we’ll change that). I went to
http://svn.example.com and saw the image to the right after entering
my credentials for testuser.

Excellent! Test it now! I tested this config with Eclipse (with the
Subclipse plugin.)

Securing with SSL

To secure stuff with SSL, generate or use a certificate and enable
Apache with mod_ssl. Change subversion.conf so that all traffic on
port 80 is redirected to port 443 (which uses the certs we’ve created.)

 <VirtualHost *:80>  
         ServerName svn.example.com  
         RewriteEngine On  
         RewriteRule .* https://svn.example.com%{REQUEST_URI} [L,R=301]  
 </VirtualHost>

Restart httpd and you’re good to go!

LDAP integration

In this example, I will be using directory.example.com as the (Open
Directory-based) LDAP provider. Change the basic authentication scheme
to match this:

 # # If using some CA file  
 # LDAPTrustedMode NONE    
 # LDAPTrustedGlobalCert CA_DER /etc/pki/tls/certs/root_ca.crt  
 # LDAPVerifyServerCert off

 # Define the repository location  
 <Location /repository>  
         DAV svn  
         SVNPath /home/svn/repository  
   
         # Integrate with LDAP server  
         AuthType Basic  
         AuthBasicProvider ldap  
         AuthName "SVN Server"  
         AuthzLDAPAuthoritative off  
         AuthLDAPURL "(ldap://directory.example.com/cn=users,dc=directory,dc=example,dc=com?uid?sub)?(objectClass=*)"  
         Require valid-user  
         AuthzSVNAccessFile /home/svn/repository/conf/authz  
 </Location>

It is important that you set AuthBasicProvider ldap. If not,
Apache will look for a password file and not even bother to authenticate
against your LDAP server. You’ll also see something like this when
restarting the httpd daemon:

Invalid command 'AuthLDAPAuthoritative', perhaps misspelled or defined by a module not included in the server configuration

I had terrible luck with setting AuthzLDAPAuthoritative to “on”. You
can read the Apache mod_authnz_ldap page for more information on these
directives. They’re quite flexible when configuring multiple
repositories, with respect to user and group access.

Now that you have a single repository, you can fine tune access with the
AuthzSVNAccessFile directive. By default, and when you use
svnadmin create, you get an authz file in your repository’s conf
folder. In the Apache configuration above, it’s the file I’ve used to
tweak folder access.

Project Management within a Repository

Creating a project

This is very simple. It’s vitally important that your project folder
contains three sub-folders: trunk, branches and tags. All
the code you want to check into the repository must be in trunk.

Step 1: Create the required directory structure

mkdir -p /tmp/newproject/{trunk,branches,tags}

Step 2: Copy/move project files into trunk

cp -R /path/to/project/files/* /tmp/newproject/trunk/

Step 3: Perform the first commit

cd /tmp
svn import newproject https://svn.example.com/repository/myproject --message "Initial import" --username myuser

Observe that my project is called newproject on my local machine but
is myproject on the SVN server. You may or may not choose to do this,
but the option is available.

You may get a dialog about the certificate used to secure the
transaction. Accept the key permanently. You will then be required to
supply a password.

Step 4: Working with your project

Most typical CVS actions should apply (prefixed with an svn of
course.) For example, to check out the project created above.

svn checkout https://username@svn.example.com/repository/myproject

The Google teems with SVN cheatsheets.

Modifying Access Control

Important: Only root can do this. Talk to your friendly sysadmin for
project-specific access control. By default, your newly created project
will be world accessible (i.e. to all authenticated users.)

Here’s an example where I created a folder for a rather sinister project
called thiswillendpoorly and have given write access only to user
nanand and read access to machrist. The leading slash is
important!

# Deny world access to repository root (noone needs to get a project listing)  
[/]  
* =  
  
# Allow only Nikhil and Mark to access this terrible project (Mark can only read)  
[/thiswillendpoorly]  
nanand = rw  
machrist = r  
* =

If you had multiple repositories, you would need to:

Here’s an example:

[repository1:/path]  
user1 = rw  
user2 = r  
  
[repository2:/path]  
* = rw

If you specified a path without specifying the repository, the filter is
applied across all repositories! This is explained
here
.

Miscellaneous

Special note about LDAP groups

You cannot do LDAP group-based authentication in SVN with the authz
file. However, I’ve seen a python
script
which can import LDAP
groups.

Few pointers on multiple repository configuration

Configuring for use with Self-Signed Certificates

Assuming that your Root CA is called root_ca.crt. Create and edit
/etc/sysconfig/servers to add the following:

[global]  
ssl-authority-files = /etc/pki/tls/certs/root_ca.crt

The other option is to use the system-wide keystore at
/etc/pki/tls/certs/ca-bundle.crt by appending the ASCII version to the
end of this file.

Resources

Active Directory Integration