# Setting up a shared remote git repository without root privileges (solved) using ssh keys to manage per user access?

I'll first explain my setup. I'm working on a non-self managed system on which I have an account without root/elevated privileges. On this system I want to share multiple git repositories to different groups of people. The actions taken to realise a shared git repository follow below. I've divided them in commands executed in a bash terminal on the REMOTE and LOCAL system. ps: replace any variables surrounded by delimiters < and > with appropriate values.

----------- REMOTE (my system): -----------

bash-4.2> mkdir -p <path>/<to>/project.git
bash-4.2> cd <path>/<to>/project.git
bash-4.2> git init --bare
bash-4.2> ssh-keygen -t rsa -f ~/.ssh/gitkey_rsa -N <password>
bash-4.2> echo "command=\"git-shell -c \\\"\$SSH_ORIGINAL_COMMAND\\\"\", no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty \$(cat ~/.ssh/gitkey_rsa.pub)" >> ~/.ssh/authorized_keys


These command do the following:

1. create a git repository
2. generate a ssh key
3. add the key to authorized_keys with prepended restrictions

----------- LOCAL (other users) -----------

bash-4.2> mv <path>/<to>/gitkey_rsa ~/.ssh
bash-4.2> echo -e "Host gitserver\n\
\tHostName <remote server>\n\
\tUser <remote user>\n\
\tIdentityFile ~/.ssh/gitkey_rsa" >> ~/.ssh/config
bash-4.2> git clone gitserver:/home/<remote user>/<path>/<to>/project.git


These commands do the following:

1. place rsa key in directory ~/.ssh
2. add a rule to ~/.ssh/config specifying hostname 'gitserver' with key
3. retrieve repository contents

The commands used are based on restrict access to only git. By using the restricted key, a user is only allowed to execute git commands. The problem is that the user is also allowed to access every git repository on the remote system. I'd like to restrict access to only one repository per ssh key. In other words, I'd like to restrict access to one folder, containing the git repository, through ssh key restrictions.

The solutions I have found thus far are: access only certain directories through ssh and Restrict SSH user to one folder. They either want you to install a (S)FTP server, WebDAV or create a new user with restricted privileges. This is not what I'm looking for, as it requires root privileges. Due to the fact that commands can be restricted with ssh key restrictions, isn't there a way to restrict access privileges as well?

Regards

• Welcome to Stack Exchange. It's good that you found out how to solve your problem. Take the solution you found and move it to an answer, and then remove the answer section from your question. (You can click that little "edit" button under the tags.) This makes both of them easier to read. – Jonathan Garber Oct 25 '13 at 13:44
• Have you considered using a system like Gitolite. It makes managing users and repos pretty simple. There is even an install guide which says root is not required. – heavyd Oct 25 '13 at 13:53
• @heavyd: I have tried Gitolite, just now. It's a viable option, though you have to keep in mind things like: "Removing a repo is not so straightforward..gitolite will not automatically delete the repo..". I will give it a serious try, if no other options present themselves :) – gospes Oct 25 '13 at 14:33

Possible solution:

As I was typing the question I came up with a solution. But it seems to me there must be a simpler and more secure solution to this problem. What I did was change the value of 'command' in the authorized_keys file to:

command="~/somescript.sh"


And 'somescript.sh' contains:

#!/bin/bash
ALLOW=(
'/home/<user>/repository1.git'
'/home/<user>/repository2.git'
)

case $SSH_ORIGINAL_COMMAND in "git-receive-pack"*|"git-upload-pack"*|"git-upload-archive"*) GITPATH=$(echo $SSH_ORIGINAL_COMMAND | sed -r "s:.*'([^']*)'.*:\1:g") ALLOWED="false" for ((i=0; i <${#ALLOW[@]}; i++)); do
if [ "${ALLOW[$i]}" == "$GITPATH" ]; then ALLOWED="true"; break; fi done if [ "$ALLOWED" == "true" ]; then
eval "git-shell -c \"\$SSH_ORIGINAL_COMMAND\""
else
exit 1
fi
;;
*)
echo "[ERROR] Only git commands are allowed!" >&2
exit 1
;;
esac


In the script I'm taking advantage of the fact that the commands git clone, git push and git pull produce on the REMOTE side:

git-upload-pack '<path>/<to>/<repository>', or