Subversion and WebDAV
[ Ref: Subversion 1.7.0rc2, OpenBSD 5.0 beta]
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.
We are installing Subversion 1.7.0rc2 and Apache 2
[ 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.
[ 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
After installing the above packages, we configure our Apache2 server, which begins with the Apache modules that we are going to use.
- Web DAV - httpd-dav.conf
- SSL Encryption - httpd-ssl.conf
- Subversion Provider - httpd-subversion.conf
- Apache Base Configuration - httpd2.conf
Configuration files for Apache 2 modules are stored in /etc/apache2/extras
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:
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.
[ 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.
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.
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.
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.
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 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: *****
In our basic configuration, the designated Subversion Repository is basically a path on your system that we are sharing.
- File System
- Sample Content
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:
- Create Path
- Create SVN Repository
- Set permissions
- Restart Apache
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. As of Subversion 1.2, svnadmin creates new repositories with the fsfs filesystem backend by default.
Where necessary, set the permissions for the repository file storage, and restart apache2
$ sudo chown -R _apache2:_apache2 /var/svn/repo
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.
For first time users, such as myself, it is good to put something on the repository that we can look at:
- Basic Content
- Upload/Commit to Repository
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.