# 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


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


### 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:

• Change the Apache directive SVNPath to SVNParentPath
• Specify the repository in the authz file

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

• If you plan on hosting multiple repositories, you need to change SVNPath to “SVNParentPath”.
• Apache will NOT allow you to access the root defined as SVNParentPath! You need to create repositories using svnadmin create and can then access them through http://svn.example.com/{path in SVNParentPath}/{name of repository}. There’s more information in the official handbook about this.

### 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.