24 March 2015

How to make an SVN repo accessible by Web and SSH

Would you like to publish an SVN repo over the web (read-only of course) so people can see your dotfiles, etc.?  If so, it takes some effort to make it work.

The examples below apply to Debian, but with minor tweaks (e.g. which config files you edit) it should work anywhere.

Apache setup

This assumes that you want your repo available at http://my.site/svn/xyz .  (The docs will tell you how to host all repos in a given directory, rather than one specific one.)  It also assumes that your repo is in /srv/svn/xyz on your web server.

First, Apache will have to be augmented with stuff to let it use the SVN libraries to interact with the repo.   This lets Apache present it as a sort of filesystem over the web, which supports both browser access as well as access by SVN clients.
sudo aptitude install libapache2-svn
## sudo service apache2 restart   # done by the above
 Then add the following to your vhost file:
# -- SVN --
<Location /svn/xyz>
  DAV svn
  SVNPath /srv/svn/xyz
  <LimitExcept GET PROPFIND OPTIONS REPORT>
    Deny from all
  </LimitExcept>

  # Uncomment and tweak this to enable write access for certain people.
  ## AuthzSVNAccessFile /etc/httpd/security/svn.access
  ## Require valid-user
  ## AuthType Basic
  ## Authname "Subversion Test repository"
  ## AuthUserFile /etc/httpd/security/svn.auth
  ## <LimitExcept GET PROPFIND OPTIONS REPORT>
  ##   Require valid-user
  ## </LimitExcept>
</Location>
I don't accept any liability for the above, and it is your responsibility to test that it is secure, e.g. by trying things that should be blocked and checking your Apache logs to ensure that they are.

Also, be sure that there's been nothing sensitive committed to the repo, even in past revisions.  Don't commit your whole home directory, because you don't want to reveal things like your API tokens (e.g. in .gitconfig) etc.

Special considerations 

Web access will happen via the www-data user, which on Debian is the user that Apache runs as.  This still needs to write to files in order for locking to work.

In the past, I got it working the past by tweaking group permissions and probably the umask (possibly using wrapper scripts).

But this is the 21st century, and everything should support POSIX ACLs, which are a kind of extended permission system.  This example assumes the existence of an svnusers group of which the required people, who will access the repo over ssh, are members.
cd /path/to/repo

# set the ACL mask to stop files being made executable
find . -type f | sudo xargs setfacl -m m:rw

# set blanket permissions, but don't recalculate the ACL mask
sudo setfacl -R -n -m g:svnusers:rwx,u:www-data:rwx

# set default perms on directories (no effect on files) so new files get correct perms
sudo setfacl -R -d -m g:svnusers:rwx,u:www-data:rwx .
Note that this won't have to be done again in future, because any new files (and directories for that matter) will automatically be given the correct permissions thanks to the last line.  "-d" automatically transforms regular ACL entries into default ACL entries, e.g. u:www-data:rwx -> default:u:www-data:rwx .

Labels: ,