Subversion and WebDAV

[ Ref: Subversion 1.7.0rc2, OpenBSD 5.0 beta]

Table of Content

Someone decided that we were going to use Subversion as our Source Code Management Repository. After reviewing our requirements, we decided that we needed Subversion, but we wanted to manage users and share the source code between users and various sites using Apache's mod_dav.

Install

We are installing Subversion 1.7.0rc2 and Apache 2

Subversion

[ Ref: Subversion 1.7.0rc2]

Revision 1.6.x was the stable version at the time, but we wanted to avoid potentially complicated backend upgrades, so went with the 1.7 RC2 that was referenced in the OpenBSD Ports mailing lists.

This required building the source through the ports system, but you should use the binary packages whenever possible, and ver. 1.7 or later is probably the stable package by the time you've read this.

Apache

[ Ref: Apache 2.2.20]

package: apache-httpd-2.2.20, ap2-subversion

Note the warning message from apache-httpd-2.2.20, don't blindly pkg_add stuff and then expect them to work if you don't bother following the instructions from the installation.

Note the Display message from ap2-subversion

Configuration

After installing the above packages, we configure our Apache2 server, which begins with the Apache modules that we are going to use.

  1. Web DAV - httpd-dav.conf
  2. SSL Encryption - httpd-ssl.conf
  3. Subversion Provider - httpd-subversion.conf
  4. Apache Base Configuration - httpd2.conf

Configuration files for Apache 2 modules are stored in /etc/apache2/extras

Web DAV

[Ref: mod_dav]

WebDAV ('Web-based Distributed Authoring and Versioning') functionality for Apache. This extension to the HTTP protocol allows creating, moving, copying, and deleting resources and collections on a remote web server.

Configuration of the Web DAV module (mod_dav) is standardised in the file httpd-dav.conf. The basic configuration settings are:

DavLockDB

Use the DavLockDB directive to specify the full path to the lock database, excluding an extension. If the path is not absolute, it will be taken relative to ServerRoot. The implementation of mod_dav_fs uses a SDBM database to track user locks.

File: /etc/apache2/extra/httpd-dav.conf

DAVLockDB "/var/apache2/var/DavLock"

BrowserMatch

[ Ref: BrowserMatch Directive]

The BrowserMatch is a special cases of the SetEnvIf directive that sets environment variables conditional on the User-Agent HTTP request header. The following two lines have the same effect:

It doesn't seem to hurt to leave the BrowserMatch directives in the configuration file.

Disable or comment out other Alias and Directory settings in this file unless you actually want it.

SSL Encryption

[ mod_dav]

We have a generic layout for certificates on our servers, not all servers host all the different types of services that use certificates, so we'll just keep things standardised to simplify knowledge or expectations of where certificates are placed.

We therefore modify the configuration to point to the path we use for storing SSLCertificates.

File: /etc/apache2/extra/httpd-ssl.conf

SSLCertificateFile    /etc/ssl/server.pem

The certificate file will contain both the server certificate, and the server key in the PEM file format.

Generate the SSL Certificate/Key

From our XMPP Chat notes, we take the Certificate Generation Code and generate SSL Keys. Again, this part is well documented online, these instructions place the SSL certificates in what makes sense for my installs.

Use OpenSSL to generate keys.

# mkdir -p /etc/ssl/certs
# /usr/sbin/openssl req -new -x509 -newkey rsa:4096 -days 3650 \
       -keyout /etc/ssl/private/server.key \
       -out /etc/ssl/certs/server.crt

# cp /etc/ssl/certs/server.crt /etc/ssl/server.pem
# /usr/sbin/openssl rsa -in /etc/ssl/private/server.key -out /etc/ssl/private/server.key.pem
# cat /etc/ssl/private/server.key.pem >> /etc/ssl/server.pem

A few notes about the commands

  • 00 /etc/ssl/certs: We want to keep certificates in a directory, /etc/ssl/certs
  • 01 req -new -x509 -newkey: Generate the Private Key server.key and the self-signed certificate server.crt
  • 05 /etc/ssl/server.pem: Copy the CRT server.crt so we can add information about the key server.key
  • 06 /etc/ssl/private/server.key.pem: Convert the Private Key to RSA output.
  • 07 /etc/ssl/server.pem: Add the RSA Formatted Key information to the server.pem file

Effectively, we now have a single file which contains both the Certificate we serve to clients, and the Private Key.

Subversion

Create the configuration file to enable the SVN service-provider for Web DAV, and specify the path where we intend to configure our subversion folder(s)

New File: /etc/apache2/extra/httpd-subversion.conf

LoadModule dav_svn_module /usr/local/lib/apache2/mod_dav_svn.so
LoadModule authz_svn_module /usr/local/lib/apache2/mod_authz_svn.so

<Location /svn>
    DAV svn

    # Automatically map any "/svn/foo" URL to repository /var/svn/foo
    SVNParentPath /var/svn

    # Authentication
    AuthName "Subversion Repository"
    AuthType Digest
    AuthUserFile /etc/svn-auth.htdigest

    # Authorisation: Authenticated users only
    Require valid-user

    SSLRequireSSL
</Location>

The DAV directive enables the provider-name (svn).

AuthName auth-domain displays the auth-domain to the user with the login prompt.

The auth-domain is also used in the Authentication Type Digest (implemented by modauthdigest)

Apache Base Configuration

Ensure the above "extra" configurations are enabled, and the DAV modules have been read.

File: /etc/apache2/httpd2.conf

LoadModule auth_digest_module /usr/local/lib/apache2/mod_auth_digest.so

LoadModule dav_module /usr/local/lib/apache2/mod_dav.so
LoadModule dav_fs_module /usr/local/lib/apach2/mod_dav_fs.so

Include /etc/apache2/extra/httpd-dav.conf
Include /etc/apache2/extra/httpd-ssl.conf
Include /etc/apache2/extra/httpd-subversion.conf

User Accounts

[Ref: htdigest]

User Accounts are managed for Apache, as such we defer to the configuration setting (httpd-subversion.conf: AuthType) which we've specified as Digest.

htdigest is used to create and update the flat-files used to store usernames, realm and password for digest authentication of HTTP users. Resources available from the Apache HTTP server can be restricted to just the users listed in the files created by htdigest.
htdigest [ -c ] passwdfile realm username
-c    Create the passwordfile. If passwordfile already exists,
      it is deleted first.

For our initial invocation, we use "-c" to make sure we create a new authentication file:

$ sudo htdigest -c /etc/svn-auth.htdigest "Subversion Repository" samt
Adding password for samt in realm Subversion Repository
New password: *****
Re-type new password: *****

Further invocations (running) of htdigest do not require the "-c" option, such as the below:

$ sudo htdigest /etc/svn-auth.htdigest "Subversion Repository" charlie
Adding password for charlie in realm Subversion Repository
New password: *****
Re-type new password: *****

Repository

In our basic configuration, the designated Subversion Repository is basically a path on your system that we are sharing.

  • File System
  • Sample Content

File System

The basic requirements for the file system, is to (obviously) have the path on which to operate our repository, and then to create the subversion specific data for servicing that repository:

  1. Create Path
  2. Create SVN Repository
  3. Set permissions
  4. Restart Apache

Create Path

Create the paths that will contain our repositories

$ sudo mkdir -p /var/svn

Create SVN Repository

Where svnadmin create is the command-line for creating an empty repository.

$ sudo svnadmin create /var/svn/repo

From the manpage svnadmin:

Create a new, empty repository at the path provided. If the provided directory 
does not exist, it will be created for you.[59] As of Subversion 1.2, svnadmin 
creates new repositories with the fsfs filesystem backend by default.

Set Permissions

Where necessary, set the permissions for the repository file storage, and restart apache2

$ sudo chown -R _apache2:_apache2 /var/svn/repo

Restart Apache

After completing the above steps, we can now view the repository by restarting Apache.

$ sudo /usr/local/sbin/apachectl2 stop && sudo /usr/local/sbin/apachectl2 start

Visit our above repository via http://localhost/svn/repo to find an empty repository for repo: set at revision 0 (because we haven't put anything into the repository yet.

Sample Content

For first time users, such as myself, it is good to put something on the repository that we can look at:

  1. Basic Content
  2. Upload/Commit to Repository

Basic Content

Generic content that we can put up on our repository, would/could be any file or directory structure. The below sample commands creates some basic directories that seem to be common for subversion.

$ cd ~
$ mkdir myrepo
$ cd myrepo
$ mkdir -p project1/branches
$ mkdir -p project1/tags
$ mkdir -p project1/trunk
$ mkdir -p utils

Our structure is stored in ~/myrepo and all we need to push this up to our subversion server is svn commit.

Upload/Commit to Repository

$ cd ~
$ svn commit myrepo https://svn-host/svn/repo/

From the manpage svn commit:

Send changes from your working copy to the repository. If you do not supply a log message 
with your commit by using either the --file or --message option, svn will launch your editor 
for you to compose a commit message. See the editor-cmd section in the section called “Config”.

svn commit will send any lock tokens that it finds and will release locks on all PATHS 
committed (recursively), unless --no-unlock is passed.