Our source code repository is currently hosted at the offshore development site and there is no external access to it (neither through the Internet nor a VPN). While this is certainly desirable from a security standpoint, I’d really love to see what the developers are actually working on.
I asked the director there to put me on the mailing list for commits. He replied they didn’t have such a system since all the developers sat in the same room. Plus, the developers weren’t so thrilled about getting a bunch of commit mails in their inbox every day. I immediately thought what about vacation or sick leave? What about a lunch break? Are these guys really together 24/7? And how much work is it to setup a mail filter anyways?
I asked him how long it would take to set up mail notifications and he said he’d look into it. The next day, he told me that it wasn’t so straightforward to implement and what was my real reason for wanting this information anyways? Wait a minute, I thought, I’m flying completely blind here – with no clue what’s being worked on – and they’re not even willing to throw me a bone?
To resolve this I decided to create our own repository and migrate the source code from the offshore site. I’ll have complete control of the code then – able to setup permissions, branches, and email notifications. Plus, the new server will double as a continuous integration server when we’re ready for that step.
My requirements for a Subversion repository are fairly straightforward. It needs to be secure, fast and reliable. Initially, I took a look at some of the commercial providers (beanstalk, unfuddle and SVNRepository.com to name a few). But, as we are developing here in Europe, I was worried about lag times and network overhead going across the Atlantic Ocean. A self-hosting option here in Europe would not only be cheap, but, I’d eventually be able to set up my own continuous integration server.
So, I leased the cheapest possible virtual server from HostEurope for 13 EUR / month (including FTP backup). I get root access on a Debian 4 server, 256MB RAM and a 15GB harddisk partition. There’s no charge for upgrading (or downgrading) the virtual host environment so I’ll be able to upgrade with a button push when I’m ready for more RAM and horsepower. Let me show you how I set it up.
The base install instructions from subversionary.org worked right out of the box. I have a Debian 4.0 host and installed Subversion using apt-get:
sudo apt-get update
sudo apt-get install subversion subversion-tools
The subversion-tools package includes (among other things) some handy perl scripts which we’ll make use of later for our commit hooks.
Repository User Configuration
Now to create the svn user (without a login shell) who will own all the repository files, and the developers will be using the repository. We’ll add the developers directly to the svn group:
sudo useradd svn -s /bin/false
sudo useradd dan -G svn
sudo useradd mark -G svn
sudo useradd susie -G svn
Creating the Repository
I created the repository in /var/svn and assured the correct ownership:
sudo mkdir -p /var/svn
sudo svnadmin create /var/svn/repos
sudo chown -R svn.svn /var/svn
Securing the Server
We want the repository to be available only via ssh. As we’ll eventually disable password based authentication all together, let’s copy the public keys of the all users to their home directories:
scp id_dsa.dan.pub kis1.hosteurope.net:/home/dan/.ssh/authorized_keys
*nix folks won’t have a problem handing over a public key. For Windows users, point them to the standard PuTTy tools from Simon Tatham.
Now, let’s secure the sandbox for these accounts by specifying the ‘command’ option to run svnserve in each users’ authorized_keys file (as one line):
sudo vi /home/dan/.ssh/authorized_keys
command="svnserve -t -r /var/svn/repos --tunnel-user=dan", no-port-forwarding,no-agent-forwarding,no-x11-forwarding,no-pty [dans-ssh-key]
The ‘-r /var/svn/repos’ parameter not only lets us hide the full path from the users, it restricts their access to just this repository – this basically becomes their root directory. The other options ensure there’s no funny business allowed with port forwarding or other types of connection attempts.
From your local machine, you should now be able to verify the availability of your secure subversion repository:
svn co svn+ssh://firstname.lastname@example.org/ local-dev
Repository Root: svn+ssh://email@example.com
svn add local-dev/test.txt
svn ci -m "initial commit"
Transmitting file data .
Committed revision 1.
Congratulations! You’ve verified read and write capabilities to your ssh secured repository. The basic install is done.
Now that you’ve also verified public key authentication works, you can further lock down your server by disabling ssh password authentication.
sudo vi /etc/sshd/ssh.conf
**WARNING** Before you do this, ensure you’ve either created a separate admin account for yourself (including appropriate permissions in /etc/sudoers) or have placed your public key in the authorized_keys file of the root user (and that the root user is allowed to login as some systems have this disabled by default). Failing to do this will basically lock you out of your server if you’ve added the ‘command=”svnserve…’ option to your user account’s authorized_keys file!
Just restart your sshd daemon
sudo /etc/init.d/ssh restart
and you’ve made your server even more secure.
Next week, I’ll show you how to setup fine grained read-write permissions and generate email notifications per commit using built-in subversion hook scripts. Subscribe here so you won’t miss it!