Setting up Subversion svnserve daemon on CentOS

When you want to host a Subversion repository on your CentOS (or RHEL) server, its quite annoying that the only options available to serve your repository are SSH (using the svn+ssh:// schema in the Subversion URLs – it is basically set up out of the box, not tweaking necessary) and Apache’s mod_dav_svn (using the http:// or https:// schema in the Subversion URLs – this is somewhat complex to setup but good instructions are easy to find on the web).

The main advantage of either of these methods is security: both have easy transport security (SSH by default, Apache if you set it to server over SSL) and are easy to setup authentication for (SSH authenticate against the system’s accounts using PAM and Apache authenticate against basically anything with a simple setup).

The main disadvantage of these methods are that they are slow (SSH is apparently somewhat faster then HTTP) and when supporting multiple large projects of many developers I started running into all kinds of weird connection errors when you try to manipulate many files on many projects at the same time.

Subversion itself offers another alternative using their own network service called svnserve – this is a standard unix daemon that listens on a specific port1 and uses a native protocol to communicate with Subversion clients (using the svn:// schema in Subversion URLs). It offers very good performance, but no transport security (encryption) by default. Another major problem with using svnserve as a network service is that while CentOS ships the binary itself (it is required as part of the way that the svn+ssh:// protocol is implemented) it doesn’t ship any support files to run it as a standalone service nor to help with its configuration. Also by default svnserve can only authenticate users using its own Apache-style password database file – which makes it unsuitable to integrate in large organizations.

In this article I’ll document how I setup snvserve as a network service to support a large development environment. The requirements do not include transport security because the server is on a private network and can only be accessed by trusted computers (either local or through a VPN), but we do need to have Subversion users authenticate against a central authentication server that is used by all local services. In my setup the authentication services is Mirosoft ActiveDirectory, but the local server is setup to authenticate to the ActiveDirectory using PAM, so we will setup svnserve to use PAM and gloss over the ActiveDirectory specifics.

The process is as follows:

  1. Set up your server: Install CentOS 6 and configure PAM to authenticate to your central authentication. Verify that users can SSH into the server using their login credentials.
  2. Set up your Subversion repository: Install subversion and use svnadmin to create your repository. In the below examples I’ve created the repository under /var/svn
  3. Set up svnserve to require authentication and do the authentication using the Cyrus SASL libraries: copy the file svnserve.conf from your repository’s configuration directory (for example /var/svn/svnserve.conf) to /etc/svnserve.conf. Edit it and add in the [general] section the following lines:
    anon-access = none
    auth-access = write
    realm = The Name of Your Repository
    make sure that all other settings in that section are commented out. Now add, at the bottom of the file, a new section like this:
    [sasl]
    use-sasl = true
  4. Setup the Cyrus SASL library to work with the saslauthd authentication service: create the file /etc/sasl2/svn.conf with the following content:
    pwcheck_method: saslauthd
    mech_list: plain login
  5. Start the saslauthd service and make sure it always run when the system start, by executing the following commands:
    # service saslauthd start
    # chkconfig saslauthd on
  6. Set up saslauthd to allow svnserve to authenticate using the main system’s PAM configuration, by executing the following command:
    # cd /etc/pam.d
    # ln -s system-auth svn
  7. Create the SysV initialization script for svnserve – this will allow you to start and stop svnserve using the service command and have it run when the system start. This is the major part that I expected CentOS to ship but is missing. Creating a good SysV script is not trivial – you can do it yourself but I suggest using the script presented here. I’ve used the script from this blog post which is not bad but its implementation of status didn’t report the status of a dead process, so I modified it and you can download my modified version here. The file is compressed because of WordPress, just download it, run it through gunzip and copy the resulting file to /etc/init.d/svnserve and then give it “execute permissions” using:
    # chmod 755 /etc/init.d/svnserve
  8. Create a configuration file for the service by creating and editing the file /etc/sysconfig/subversion.conf with this content:
    OPTIONS="--config-file=/etc/svnserve.conf -r /var/svn"

    We use the -r option to limit svnserve access to only our repository, so have the value there point to your actual repository if its not /var/svn
  9. Set up svnserve to run when the system start, and then start the service itself:
    # chkconfig svnserve on
    # service svnserve start

And that’s it – you should have svnserve listening on port 3690 and ready to serve clients. The URL you use to access the repository should include only the server name as svnserve access is already rooted to only your repository by the configuration file. So for example if my server is called svn then the URL will be svn://svn2.

This setup will still allow you to access the repository using the svn+ssh:// protocol as you would under a normal setup. It can be a bit confusing as access over SSH uses different paths then over the Subversion svnserve network service, because you have to use the full path to the repository on the local file system in the svn+ssh:// URL. To circumvent this, its possible to get the SSH access to also be rooted to your repository’s path and thus be symmetric with the above setup. To do this, create a new file at /usr/local/bin/svnserve and put the following code in it:
#!/bin/bash
exec /usr/bin/svnserve "$@" -r /var/svn

Give the file “execute permissions” by running
# chmod 755 /usr/local/bin/svnserve
, so it can be executed by the Subversion client instead of the system’s svnserve binary. Now both native Subversion and SSH access use basically the same URL, except for the schema part.

Enhanced by Zemanta
  1. port 3690 by default []
  2. very confusing, I know 🙂 []

5 Responses to “Setting up Subversion svnserve daemon on CentOS”

  1. Chris Gebert:

    svnserve.gz results in a binary file, not a shell script for init.d. Seems like the file is corrupted.

  2. Ross Hamilton:

    Looks like the file has been gzipped twice!

  3. modasser:

    How do I check it with command reprository

  4. Ondrej:

    Thanks for the init script, I’m currently trying it and it works cool so far (and no troubles with the gzip).

    I wonder if there may be a mistake in the instructions where you say to create /etc/sysconfig/subversion.conf but the script refers to /etc/sysconfig/subversion . Anyway I preferred to change the reference to /etc/sysconfig/svnserve and create that file and all works fine.

Leave a Reply