Allowing Subversion access through Apache2

These are my rough notes on how I got Subversion access through Apache2 working on daystrom, which is running Debian sarge. They're not very clean, but maybe they might help someone out. These notes are old and are probably out-of-date. I no longer use this setup.

The first thing we need to do is to get HTTPS working so we can eventually have Subversion working through Apache2.

First, enable the SSL modules:

   daystrom:/etc/apache2/mods-enabled# ln -s /etc/apache2/mods-available/ssl.load 
   daystrom:/etc/apache2/mods-enabled# ln -s /etc/apache2/mods-available/ssl.conf

Next, create several new virtual hosts. In the default virtual host, make sure you list both of these:

   NameVirtualHost *:80
   NameVirtualHost *:443

Then, change all of the other existing virtual hosts to show port 80, i.e.

   <VirtualHost *:80>

Next, copy the existing port 80 virtual hosts and make them port 443:

   <VirtualHost *:443>

Finally, add SSL engines to each port 443 virtual host:

   SSLEngine On
   SSLCertificateFile /etc/apache2/ssl/apache.pem

You probably want to do the same thing for any other virtual servers, too, otherwise the virtual host configuration might send any port 443 request to the default virtual host (which will be confusing).

Then, create a self-signed certificate:

   daystrom:/root# apache2-ssl-certificate

   creating selfsigned certificate
   replace it with one signed by a certification authority (CA)

   enter your ServerName at the Common Name prompt

   If you want your certificate to expire after x days call this programm
   with -days x
   Generating a 1024 bit RSA private key
   ..++++++
   .....................++++++
   writing new private key to '/etc/apache2/ssl/apache.pem'
   -----
   You are about to be asked to enter information that will be incorporated
   into your certificate request.
   What you are about to enter is what is called a Distinguished Name or a DN.
   There are quite a few fields but you can leave some blank
   For some fields there will be a default value,
   If you enter '.', the field will be left blank.
   -----
   Country Name (2 letter code) [GB]:US
   State or Province Name (full name) [Some-State]:XXXX
   Locality Name (eg, city) []:XXXXX
   Organization Name (eg, company; recommended) []:XXXXX
   Organizational Unit Name (eg, section) []:XXXX
   server name (eg. ssl.domain.tld; required!!!) []:XXXX
   Email Address []:XXXXX

At this point, SSL should work to your various virtual hosts on port 443. Of course, users will get a certificate error from the browser since the certificate can't be verified as from a trusted certificate authority, but that's OK. If you want to use a real SSL certificate (either one from someone like Verisign or one from your own Certificate Authority, see the RealSSL page).

Now, we're going to work on getting Apache2 to serve Subversion requests. The goal is to let anyone do anonymous checkouts of software over http or https, and certain authorized people do checkouts and commits over https and only https. This way, no one accidentally uses their password over a cleartext network connection.

First, install the Subversion Apache modules:

   apt-get install libapache2-svn

Next, create an htpasswd repository:

   htpasswd -cm /etc/subversion/users.software gooduser

Note that the -c creates the repository, so after this you'll just use -m to add new users (stupid syntax, IMNSHO).

Now, if you want to make an entire repository available via Apache, use a section like this in your port 80 VirtualHost directives:

   # Allow anonymous Subversion repository browsing, but never commits
   <Location /svn/software>
      DAV svn
      SVNPath /opt/public/svn/software
      <LimitExcept GET PROPFIND OPTIONS REPORT>
         Order deny,allow
         Deny from all
      </LimitExcept>
   </Location

The LimitExcept clause says to deny any actions besides GET, PROPFIND, etc. under all circumstances. In other words, just allow anonymous browsing.

In your port 443 VirtualHost directives, use something like this:

   # Allow anonymous Subversion repository browsing, and commits for authorized users
   <Location /svn/software>
      DAV svn
      SVNPath /opt/public/svn/software
      AuthType Basic
      AuthName "Cedar Solutions Subversion Repository"
      AuthUserFile /etc/subversion/users.software
      <LimitExcept GET PROPFIND OPTIONS REPORT>
         Require valid-user
      </LimitExcept>
   </Location>

This modified LimitExcept clause requires a valid-user for any actions other than GET, PROPFIND, etc. and causes Apache to use the Basic (htpasswd) authentication that you set up above in /etc/subversion/users.software.

This is great as long as you want to make entire repositories available. I don't want that, though. I want only parts of my software repository available because there are some things (passwords, perhaps) that only "trusted" developers should see. I can also envision in the future giving commit access to someone, but only for the cedar-backup2 tree or something. This is a job for Subversion's authz module.

What you'll do here is specify a slightly different set of configuration options, which will direct Apache to let the authz module decide whether something is allowed, disallowed, or allowed if authenticated, etc.

Again, changes to the port 80 VirtualHost directives are simple:

   # Allow only anonymous access to the repository, which per our authz config disallows commits
   <Location /svn/software>
      DAV svn
      SVNPath /opt/public/svn/software
      AuthzSVNAccessFile /etc/subversion/access.software
   </Location>

This directive forces all access over port 80 to be anonymous. Since no one even has the option to do anything that requires authorization (since only the anonymous rules will apply) there will never be a need for a password over port 80.

Changes to the port 443 VirtualHost directives add a few more options:

   # Allow anonymous Subversion repository browsing, and commits for authorized users
   <Location /svn/software>
      DAV svn
      SVNPath /opt/public/svn/software
      AuthzSVNAccessFile /etc/subversion/access.software
      Satisfy Any
      Require valid-user
      AuthType Basic
      AuthName "Cedar Solutions Subversion Repository"
      AuthUserFile /etc/subversion/users.software
   </Location>

The combination of the Satisfy Any and Require valid-user options basically says, "try as anonymous first, and then ask for authorization when needed". The same Basic (htpasswd) authorization is used here as in the earlier example.

Now, the only thing left is to come up with the authorization configuration used by authz - in /etc/subversion/access.software. This is all I ended up with in the file:

   # Groups of users
   [groups]
   trusted-developers = gooduser

   # Let trusted developers have access to the entire repository
   [/]
   @trusted-developers = rw

   # Let anonymous users have read-only access to certain parts of the repository
   [/banner]
   * = r

   [/cedar-backup]
   * = r

   [/cedar-backup2]
   * = r

   [/secret-santa]
   * = r

   [/utilities/trunk/util]
   * = r

   [/vim-syntax/trunk]
   * = r

   [/wordutils]
   * = r

Essentially, this allows trusted developers to have access to the entire repository, and anonymous users to have limited access to only certain parts of the repository. In particular, anonymous users have access to all of banner, cedar-backup, cedar-backup2, secret-santa and wordutils; the trunk of the vim-syntax project, and a specific part of the trunk in the utilities project. Everything else is blocked.

SubversionApache2 (last edited 2010-05-28 17:14:21 by KennethPronovici)