Thursday 22 March 2007

re-root subversion with svn+ssh schema

It is simple to re-root a subversion repository with svn+ssh accessing schema.

The easiest one to re-define the svn command as an alias. For example, if you have repo1, repo2, ... in /var/svn directory. Usually you access them with svn+ssh://myserver/var/svn/repo1/, svn+ssh://myserver/var/svn/repo2/, ...

Now if you want to access them with shortened URLs, like svn+ssh://myserver/repo1/, svn+ssh://myserver/repo2/, ... What can you do?

You can compose a simple script like this:

#!/bin/sh
# /usr/local/bin/svnserve
# This script redefines the svn command so that svn repositories are re-rooted.
# Please make sure this script is before the system command, /usr/bin/svn, in
# the search path. Also please note the proper quotation for commandline options.
#alias svnserve='/usr/bin/svnserve -r /var/svn "$@"'
/usr/bin/svnserve -r /var/svn "$@"

and put it in /usr/local/bin/ and name it as svnserve as well. This is because the OpenSSH server built with default compilation options will put /usr/local/bin before /usr/bin in the searching path for executables.

The above method works when you have a system account on the server.

With new version of OpenSSH, a nice feature called proxy command is added. So you can let multiple users access a subversion repository, using the same system account but with different identities! Say, you decide to use a system account, svn, for this. Then you need to hack ~svn/.ssh/config and ~svn/.ssh/authorised_keys, where ~svn refers to the home directory of the svn account as usual, and in our case, it would be /var/svn.

I’ve got the second method worked but it is slightly complicated. It involves defining proxy commands for different public keys. Check ssh_config and sshd_config manpages for the syntax of ~/.ssh/authorised_keys file.

Oh, did I mention that for this to work you have to use key-based authentication for ssh? You better use key-based authentication for svn+ssh accesses anyway. Otherwise you’ll get bored to type in your password again and again as subversion doesn’t accept pushed client authentication. According to the subversion design document, this is on purpose. It pulls authentication info from a client whenever needed, for a better security.


Additioanlly, on the client side you can define your own schema with this svn+ approach. The following example defines an essh command which is actually a wrapper to the ssh command:

#!/bin/sh
# ~/bin/essh
# a wrap script for svn+ssh scheme to define the svnserve root directory
# the evniroment variable SVN_SSH should be set to this script
/usr/bin/ssh $1 /usr/bin/svnserve -r /var/svn/ -t

With this command defined, you can now access the respository sitting at /var/svn/software/ with the URL below

svn+essh://myserver/software/

Apparently you can insert in more options into the wrapper script. For example, you change the last line to:

/usr/bin/ssh -l svn $1 /usr/bin/svnserve -r /var/svn/software/ -t

or

/usr/bin/ssh $1 /usr/bin/svnserve -r /var/svn/software/ -t --tunnel-user svn

then you access the same repository with svn+essh://myserver/ URL and you always login as user svn.

No comments: