Introduction |
Preparing The Machine |
Adding A New Project |
Adding A New Developer |
Introduction
This mini-HOWTO decribes how to set up a jail rooted SVN repository on a POSIX system like GNU/Linux.
Access to the repository is done solely through ssh. The ssh login results in a jail rooted shell per project that allows exactly one command. This provides a high degree of security:
- Project developers need to be able to login using normal ssh authentication [It is possible to provide anonymous access for which no password is required, see below.]
- After logging in through ssh one can only execute a single command, namely
svnserve -t
, which is needed to access the SVN repository. There is absolutely no room to exploit anything (else) here. svnserve
runs in a jail root with only access to the SVN repository, effectively disabling the possibility to exploit a possible bug in svn. Anonymous users do not have significant write access to this file system.
Preparing the machine
This paragraph describes things that need to be done once per machine.
- Install and configure sshd the normal way.
- Set the environment variable SVNBASE. This is the root under which everything will be installed.
For example
SVNBASE="/opt/svn"
. This is not the jail root; the jail roots will reside somewhere inside this directory.$ export SVNBASE="/opt/svn"
- Download svnbase.tar.gz. Check the md5 checksum.
$ md5sum svnbase.tar.gz 200fd135f165c39bf0d6cd996d573ebd svnbase.tar.gz
- Install it by unpacking it in SVNBASE:
$ cd "$SVNBASE" $ sudo tar xzf svnbase.tar.gz
You might want to change the ownership of the unpackedsrc
directory:$ sudo chown -R YOU src
- Add the group
svn-rw
to your system.$ sudo groupadd svn-rw
Adding a new project
We use a new svn repository (and jail root) per project.
To add a new project/repository execute the following commands.
The prompt $
is omitted for your copy&paste pleasure.
Bold commands should be executed as
root.
Make sure that the environment variables are ALSO set
while being root if you use su
instead of sudo
!
- Set the environment variable SVNBASE as above.
SVNBASE=/opt/svn
- Set the environment variable PROJECT to the name of the new project. Only use alphanumeric characters.
PROJECT=projectname
- Create project group, jail root and developers' home directory base.
sudo groupadd svn-$PROJECT sudo install -m 755 -g svn-$PROJECT -d $SVNBASE/$PROJECT/root/home
- If you want to allow anonymous (read) access, add an anonymous user account for this project.
The backslash means this is really just one line.
sudo useradd -p "anonsvn" -d $SVNBASE/$PROJECT/root/home/svn-$PROJECT-anon \ -s $SVNBASE/$PROJECT/bin/chrootsh -c 'Anonymous SVN user' \ -m -k $SVNBASE/skel svn-$PROJECT-anon
You can also use
-p ""
so that no password has to be given at all (otherwise the passwordanonsvn
has to be provided the first time when checking out (svn caches it after that)). For empty passwords to work, change/etc/pam.d/sshd
and replace '@include common-auth
' with 'auth required pam_unix.so nullok
', and change/etc/ssh/sshd_config
and set 'PermitEmptyPasswords yes
'. - Compile and install chrootsh.
cd $SVNBASE/src gcc -O2 -DSVNBASE=\"$SVNBASE\" -DPROJECT=\"$PROJECT\" chrootsh.c -o chrootsh sudo install -m 755 -d $SVNBASE/$PROJECT/bin sudo install -m 4755 chrootsh $SVNBASE/$PROJECT/bin
- Create the chrooted environment.
sudo install -m 755 -d $SVNBASE/$PROJECT/root/lib sudo install -m 755 -d $SVNBASE/$PROJECT/root/bin sudo cp /sbin/ldconfig $SVNBASE/$PROJECT/root/bin sudo cp /bin/sh $SVNBASE/$PROJECT/root/bin sudo cp /usr/bin/svnlook $SVNBASE/$PROJECT/root/bin sudo cp /usr/bin/svnserve $SVNBASE/$PROJECT/root/bin sudo install -m 1777 -d $SVNBASE/$PROJECT/root/tmp sudo install -m 755 -d $SVNBASE/$PROJECT/root/etc sudo touch $SVNBASE/$PROJECT/root/etc/ld.so.conf sudo sh -c "echo 'passwd: files' > $SVNBASE/$PROJECT/root/etc/nsswitch.conf" sudo sh -c "echo 'group: files' >> $SVNBASE/$PROJECT/root/etc/nsswitch.conf" sudo install -m 755 -d $SVNBASE/$PROJECT/root/dev sudo mknod -m 666 $SVNBASE/$PROJECT/root/dev/null c 1 3 sudo sh -c "grep '^svn-$PROJECT[-:]' /etc/group > $SVNBASE/$PROJECT/root/etc/group" sudo sh -c "grep ^svn-$PROJECT- /etc/passwd > $SVNBASE/$PROJECT/root/etc/passwd" cd $SVNBASE/src; sudo ./createlib $SVNBASE $PROJECT
- Create the repository.
sudo svnadmin --fs-type fsfs create $SVNBASE/$PROJECT/root/repos cd $SVNBASE/$PROJECT/root/repos sudo chmod 2770 db sudo chmod 750 hooks sudo chmod 770 locks sudo chgrp -R svn-rw db hooks locks sudo chmod -R g+w db sudo chmod o+rx db db/revs db/revprops locks
- Add yourself as developer, see Adding a new developer below.
- Test the installation a bit by running,
$ ssh $PROJECT test
This should print: This worked. Now try svn.
After adding yourself as developer, you can now go ahead and add the initial directories.
For example,
$ cd $HOME/projects/$PROJECT $ mkdir tmp $ cd tmp $ mkdir branches tags trunk $ svn import -m 'Initial directory structure' "svn+ssh://$PROJECT/repos" $ cd .. $ rm -rf tmp
Or, if you have a dumpfile, for example one that you created from your CVS repository as described here, you could do instead:
$ sudo svnadmin load $SVNBASE/$PROJECT/root/repos < svndump
Finally, check-out your new repository!
$ svn checkout "svn+ssh://$PROJECT/repos/trunk" "$PROJECT" $ cd "$PROJECT"
From there it should all be known, or go read the svn book.
Adding a new developer
The only thing needed for new developers is to add a (project specific) account for them and add them to the right groups to get write access to the repository.
- Set the SVNBASE, PROJECT and SVNUSER environment variables.
SVNBASE=/opt/svn PROJECT=projectname SVNUSER=carlo
Obviously, use values suitable for you. - Also set these helper environment variables (as an example).
REALNAME='John Doe' NICK='nickname'
- Then add the new account. The backslash means that it's really all just one line.
sudo useradd -G svn-$PROJECT-anon,svn-$PROJECT,svn-rw -d $SVNBASE/$PROJECT/root/home/svn-$PROJECT-$SVNUSER \ -s $SVNBASE/$PROJECT/bin/chrootsh -c "SVN $PROJECT developer, $REALNAME ($NICK)" \ -m -k $SVNBASE/skel svn-$PROJECT-$SVNUSER
Leave out thesvn-$PROJECT-anon
group if you didn't create an anonymous user for this project. - Have your developer generate a new key pair by executing the following commands on his own machine:
developer$ cd ~/.ssh developer$ ssh-keygen -t dsa -f projectname_dsa
And let him add the following lines to his~/.ssh/config
file:Host projectname Hostname localhost ForwardX11 no Protocol 2 IdentityFile ~/.ssh/projectname_dsa User svn-projectname-svnuser
Where projectname should be replaced with PROJECT and svnuser should be replaced with the value that you used for SVNUSER above. Also, change localhost into the name or IP of the machine running the repository.
Finally, have him sent you his projectname_dsa.pub file.
- Using the thus retrieved public key file, give the developer access by adding his
key to the
authorized_keys
file:sudo sh -c "cat thekey.pub >> $SVNBASE/$PROJECT/root/home/svn-$PROJECT-$SVNUSER/.ssh/authorized_keys"
This usessh -c
with double quotes because otherwise the environment variables wouldn't be expanded before starting sudo, or we wouldn't have write access to the output file. - Also copy the password and group lines to the chrooted environment.
sudo sh -c "grep ^svn-$PROJECT-$SVNUSER /etc/passwd >> $SVNBASE/$PROJECT/root/etc/passwd" sudo sh -c "grep ^svn-$PROJECT-$SVNUSER /etc/group >> $SVNBASE/$PROJECT/root/etc/group"
That's all!