Just taking in consideration the server configuration one of the nice features it provides is the ability to encapsulate the proprietary svn protocol inside ssh to add security and a lot more.
Such configuration publishes URLs of svn+ssh:// type, is quite simple to set up and allows to:
- use LDAP or RADIUS for user accounts storage through PAM SSH modules
- adopt fine grained access control through file system permissions;
- secure the communication channel;
- quicker and easier set up compared to the widely adopted http/https protocols which require an Apache Web Server integration.
Setting up a decent svn+ssh configuration is a very easy task if you follow a few simple rules that guarantee a flexible and user friendly set up.
Client SSH host keys
The SVN client is unable to cache SSH credentials because it’s actually the SSH client that is in charge of performing authentication, which means that if we want to avoid the constant prompt of credentials we have to generate authorization keys.
Let’s start with opening (or creating, if it doesn’t exists yet) the
svn_user_home/.ssh/authorized_keys file (where
svn_user_home refers to the home folder of the user running the svnserve server) and let’s add one row per each client in the following format:
command="svnserve.sh", TYPE KEY email@example.com
You obviously have to replace xxx with the username you want to grant access while TYPE and KEY refers to the type and has of the generated key associated to that user. Wait a minute: we haven’t generated any key yet! Let’s do it now by following the instructions in this mini guide.
Obviously in the authorized_keys file we’ll have to put the public key only while the private one has to be given to the user that is going to connect to Subversion. To avoid the hassle and to improve security it’s better if those keys are generated by the users and they provide their public ones to the Subversion administrator.
Now you only need to create a svnserve.sh script which will set the most appropriate umask for SVN (I suggest 002).
This will solve most problems related to authentication so we are left with authorizations: I found that Unix groups work quite well and my choice is to use at least a group per each project hosted on my repository so that I can grant permissions to developers on a per project basis by adding users to groups (this is the reason for the umask setting).
If you need a more fine grained control you can imagine to create additional groups, like:
- prj-devels (read/write on trunk and branches)
- prj-testers (read only on everything)
- prj-admins (read/write on everything)