Secure SVN repository using svn+ssh

Posted by theBlatherskite Wed, 25 Oct 2006 00:33:00 GMT

My pet project has recently grown to the point where I needed to shift over to a modern revision-control tool like Subversion (also known as svn – more info here).

I need to be able to access by repository from multiple computers, but access needs to be restricted and the authorization encrypted. Though the solution is simple (svn+ssh), its implementation required me to become much more familiar with various aspects of the console I hadn’t really explored.

This article assumes you have shell access on a remote server, where you intend to host your repository, and svn successfully installed. If you’ve got that, let’s right jump in!

Creating the Repository

On the server, > svnadmin create repositoryName

Create your repository’s structure

> mkdir projectName
> cd projectName
> mkdir ./trunk
> mkdir ./tags
> mkdir ./branches

Import that structure into the repository itself > svn import . file://pathToRepository/repositoryName/projectName -m ‘Initial import’

Note: On Site5, the path to my home directory is /home/USERNAME, so this becomes svn import . file:///home/USERNAME/repos/project -m ‘Initial import’, but this will vary across environments. Note: You should end up with THREE slashes after the file:, because file:// is just a url prefix like http:// – the third slash begins the path. Note: If you receive “svn unable to open an ra_local session to URL” errors, make sure the destination path you’re using is fully qualified (starts from the root /).

Remove the temp files > cd ..
> rm -rf projectName

Using the Repository

Check out a working copy of your (empty) project > svn co file:///pathToRepository/repositoryName/trunk nameForWorkingCopy

Note: svn co is short for svn checkout

Change to the new directory and get to work > cd nameForWorkingCopy

If you’re just starting a new project, go ahead and begin coding within this directory (For rails, rails MyProject, then copy files in…). If you have already begun coding elsewhere, however, you need to somehow get that code onto the server and copied into the nameForWorkingCopy directory, and then run > svn add path for each file or directory you need to add.

Note: If you’re switching old code to a new svn repository, you’ll need to remove all the .svn directories. On *nix, this can be accomplished with > find . -name .svn -print0 | xargs -0 rm -rf Otherwise, use Ruby: require ‘find’ require ‘fileutils’ Find.find(‘./’) do |path| if File.basename(path) == ‘.svn’ FileUtils.remove_dir(path, true) Find.prune end end

Thanks to HelgeG and nickstenning on TextSnippets.

Once the directory’s been updated, we’re ready to check our work back into the server. > svn ci -m ‘Adding first revisions’
# Translates to: svn commit –message “Adding first revisions”

Finishing touches – it’s a good idea to tell svn which files you don’t need it to keep versioned for you, as well. This listing is copied from winton at TextSnippets.

> svn remove log/*
> svn commit -m “Removed log files”
> svn propset svn:ignore “*.log” log/
> svn update log/
> svn commit -m “Ignoring log files”
> svn remove tmp/*
> svn propset svn:ignore “*” tmp/
> svn update tmp/
> svn commit -m “Ignoring temp folder”

Remote access

Okay, so now we’ve got our svn server all set, but that doesn’t do us much good if we can’t connect to it. Presumably, however, we want to have some sort of access control, and if we’re authenticating in any way then we’d want that traffic to be encrypted.

Generating the keys

First we need to generate a public key to use public key cryptography. I’ll demonstrate with ssh-keygen, and point our windows readers to PuTTY and the PuTTY Docs.

nix-bsd-user > ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/nix-bsd-user/.ssh/id_rsa): [Return]
Enter passphrase (empty for no passphrase): some sort of spl3nd1d pa$$phrase
Enter same passphrase again: some sort of spl3nd1d pa$$phrase
Your identification has been saved in /Users/nix-bsd-user/.ssh/id_rsa.
Your public key has been saved in /Users/nix-bsd-user/.ssh/id_rsa.pub.
The key fingerprint is:
0e:e2:7a:5d:51:79:33:aa:2f:3b:24:60:7e:cf:33:d3 nix-bsd-user@sleek

Note: for security, your passphrase will not be echoed to the screen as you type it – and for goodness sake DON’T leave it blank.

Authorizing the keys

Your public and private keys don’t do much good sitting together on a computer you’re already staring at – let’s put them to work for us. We want to copy the contents of the newly created id_rsa.pub into the authorized_keys file on the server. You could just FTP the file up, but assuming the authorized_keys file doesn’t yet exist, we can do this with scp (Windows users try WinSCP) > scp -p ~/.ssh/id_rsa.pub remoteUsername@remoteHost:.ssh/authorized_keys

Note: make sure you copy over the *.pub file, and not the private key!

At this point, we should be able to log into remoteHost using our passphrase from above.

If you’re running *nix, we can have ssh-agent remember our authentication information for us so we don’t have to enter it each time we try to connect to remoteHost. We just have to load the passphrase into memory once with ssh-add. > ssh-agent $SHELL
> ssh-add
Enter passphrase for /Users/nix-bsd-user/.ssh/id_rsa: some sort of spl3nd1d pa$$phrase
Identity added: /Users/nix-bsd-user/.ssh/id_rsa (/Users/nix-bsd-user/.ssh/id_rsa)

Note: ssh-agent will continue to store your keys until whatever command is passed into it ($SHELL, most commonly) finished executing, so we only have to log in once as long as we keep that window open. If you didn’t enter a passphrase when using ssh-keygen, you wouldn’t never have to type in a password, but then anyone who gained access to your console could log in to your server. On the whole, the ssh-agent method (PuTTY has an equivalent feature) seems a good compromise between security and ease of use. On a Mac, you can even use SSHKeyChain to manage the ssh-agent for you.

Using svn+ssh

Whew! It’s about time – we’re finally ready to connect remotely to our svn repository. Now don’t blink, ‘cause you might miss it. > svn co svn+ssh://remoteUsername@remoteHost/pathToRepository/repositoryName/projectName/trunk
# svn checkout svn+ssh://username@domain.com/home/username/repos/project/trunk

That’s it! All your svn <whatever> commands should work just fine against your ssh-protected remote svn server. Que bueno!

    Resources:
  • svnX – Open source Mac GUI
  • TortoiseSVN – A free Windows GUI implemented as shell extension

Posted in , ,  | Tags , , , ,  | 7 comments | no trackbacks

Comments

  1. Anand said 12 months later:

    OK now a small funny question. Suppose that the svn is in the same server.

    Explanation:

    I have logged into the server whose name is : xyz@abcdef.com

    and the SVN is also in the same server but with svn+ssh

    svn+ssh://abcdef.com/var/opt/SVN/project_name/trunk.

    I have already done the ssh authentication for this server from my windows machine. ( server : Unix : xyz@abcdef.com client : Windows )

    So the private key is in my windows and the public key is in the authorized_keys file.

    Loggin into the server with putty from windows is happening as expected (not asking for password) and now the problem is when I am doing a svn co the password is being asked.

    how can the automatic password authentication be done? Is it with the ssh authentication??

    I see the .subversion folder under my username. I know that some thing has to be done with the auth, but I dont know what has to be done ??

    Please help me ..

    THanks in advance

  2. kyzyl said 12 months later:

    Under “Using the Repository” the command to check out the trunk from your newly create repo is:

    svn co file:///pathToRepository/repositoryName/trunk nameForWorkingCopy

    Should that not be:

    svn co file:///pathToRepository/repositoryName/projectName/trunk nameForWorkingCopy

    …?

  3. TheBlatherskite said 12 months later:

    Hi Anand,

    I may be wrong, but it sounds like you’re trying to checkout from an svn repository on a machine you’re already logged into. If this is the case, you can use the file:// protocol, rather than svn+ssh:

    svn co file:///path/to/respository

    (Note that the url is [protocol] [path], so you’ll end up with three slashes in row (two for file:// and one to start the path /path/to/repos).

    Hope that helps!

  4. prabhu said about 1 year later:

    how can i use export command in linux with ssh

  5. TheBlatherskite said about 1 year later:

    @Prabhu, I’m not sure exactly what you’re referring to… can you give me a little more information?

  6. tunesmith said about 1 year later:

    What I want to figure out is how to use local editor (on my macbook) to interact with files that are remote, while also being able to run the various subversion commands. I don’t think it’s possible.

    1) From shell server, create repository 2) From shell server, create checkout 3) From macbook, edit files in checkout in Hypothetical Editor 4) Run “SVN Diff” from Hypothetical Editor - it sends command over network, runs it, and sucks output back into Hypothetical Editor that can do cool visual diff stuff, etc.

    Necessary because I might have to have that checkout on the server so the webserver can see it along with the development database…

    Otherwise I’m looking at having the same php/mysql/apache/whatever setup duplicated on my macbook, which isn’t always practical.

  7. D said about 1 year later:

    Hi,

    I am trying to set svn+ssh on Mac OS X. I followed directions from a different site when I set it up a few weeks ago, but I believe they produced the same end result. The problem I’m running into is that the ssh account is automatically used as the svn account. To avoid making separate user accounts on the computer, what I need is to have a single ssh account with different svn accounts (probably based on the different keys). Could you suggest a way to do this?

Trackbacks

Use the following link to trackback from your own site:
http://www.theblatherskite.com/trackbacks?article_id=secure-svn-repository-using-svn-ssh&day=24&month=10&year=2006

(leave url/email »)

   Comment Markup Help Preview comment