Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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

share|improve this question
1  
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

1 Answer 1

up vote 0 down vote accepted

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
            echo "[ERROR] ACCESS DENIED" >&2
            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
git-receive-pack '<path>/<to>/<repository>'

I specify repositories in variable ALLOW that are allowed to be accessed through the ssh key that uses the script, and simply compare them to the path specified in the issued git command (variable GITPATH). There is a security risk though, when multiple git commands are issued in one line. If the command contains at least one mention of an allowed repository, it executes the entire command. Any suggestions on improvement?

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.