Configuring Mercurial and hg-ssh for a centralized repo

I’m thinking of switching over to Mercurial for our source repositories. The benefit of a DVCS in our situation is that we can continue work when we don’t have connections to the server.  This adds another way to survive a server crash, and a means to work without wifi.

However, we need a centralized repository for collaboration purposes.  It should be possible for each developer to push changes to the server without intervention from a project owner.   The repository should also enforce permissions and prevent any user from corrupting or toasting the repo.  The users are sometimes 3rd party contractors, hired by the client, and I don’t mind them changing code as long as there exists a secure log of their changes, and a means to back them out.

I first tried setting up hg-admin-tools.  I had some trouble getting ssh-agent working properly, and the tools didn’t install per the suggestions of several tutorials.  Then, I decided to try hg-ssh.

Hg-ssh is a script that you execute from ~repo_owner/.ssh/authorized_keys.  Each developer places their keys into the file, along with some parameters that run all requests through hg-ssh.  This script simply checks that the parameters are for a valid repo, then allow the incoming command to proceed.  This provides authentication and also protects the repo (and server) from improper commands.

The steps:

1)  Make a user on the server to own the repos, let’s call it hg.  You may want to disable logins.

#make user
sudo "useradd -m hg"

#lock account so no password-based logins are possible
sudo "usermod -L hg"

2)  make a subdirectory to hold the repos (optional), let’s call it repos

3)  create a repo in that directory, such as “hg init testrepo”

4)  Download hg-ssh and place the script in ~hg, and chmod u+x

wget http://www.selenic.com/repo/hg-stable/raw-file/tip/contrib/hg-ssh
chmod u+x ~hg/hg-ssh

5)  Each developer uses ssh-keygen to make a key, if they don’t have one yet

6)  Append all the developer keys to ~hg/.ssh/.authorized_keys

7)  For each key, add the following permissions before the key:

command="~hg/hg-ssh ~hg/repos/testrepo", no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa.....

Note: don’t forget to add the hg user to AlllowUsers in the sshd config, if you are restricting by username.

8)  The developer can then clone the repo using

hg clone ssh://hg@servername.com/repos/testrepo

If you use non-standard ports for ssh, just add the port after the domain name:

hg clone ssh://hg@servername.com:007/repos/testrepo

Leave a Reply