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:
- 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.
- 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
- 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:
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:
anon-access = none
auth-access = write
realm = The Name of Your Repository
[sasl]
use-sasl = true
- 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
- 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
- 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
- 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 ofstatus
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
- 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
- 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://svn
2.
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
, 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.
# chmod 755 /usr/local/bin/svnserve
Related articles
- CentOS – Subversion Configuration (waterbiscuit.wordpress.com)
- Passwords and svn (stackoverflow.com)
- Importing a subversion repository (stackoverflow.com)
- Subversion – Merging Repositories (stackoverflow.com)
svnserve.gz results in a binary file, not a shell script for init.d. Seems like the file is corrupted.
un-gzip it…
Looks like the file has been gzipped twice!
How do I check it with command reprository
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.