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'd like to be able to use a ssh key for authentication, but still restrict the commands that can be executed over the ssh tunnel.

With Subversion, I've achieved this by using a .ssh/authorized_keys file like:

command="/usr/local/bin/svnserve -t --tunnel-user matt -r /path/to/repository",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa AAAAB3NzaC1yc2EAAAABIetc...

I've tried this with "/usr/bin/git-shell" in the command, but I just get the funky old fatal: What do you think I am? A shell? error message.

share|improve this question

5 Answers 5

up vote 20 down vote accepted

The following works for me.

In ~/.ssh/authorized_keys:

command="./gitserve",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-dss AAAAB…

In the ~/gitserve script:

#!/bin/sh
exec git-shell -c "$SSH_ORIGINAL_COMMAND"

Note that if you put gitserve somewhere other than the home directory, you will have to adjust the command="./gitserve" parameter in authorized_keys.

share|improve this answer
    
Bingo! This is works just like what I was hoping to achieve! Thanks. –  Matt Connolly Oct 6 '11 at 21:57
    
In this related post on SO stackoverflow.com/questions/5871652/… they point to another solution here: joey.kitenet.net/blog/entry/locking_down_ssh_authorized_keys –  Tim Mar 30 '12 at 14:16
1  
@Tim This is essentially the same solution, but squeezes the content of my ~/gitserve script into authorized keys by using perl. Personally, I prefer keeping it in a separate script. –  Neil Mayhew Apr 4 '12 at 22:32
1  
I understand, I merely added it as reference. –  Tim Apr 9 '12 at 11:42

I could successfully use git-shell directly in the authorizedKeys file without using an additionnal script.

The key is to add \" around the env variable.

Tested in rhel6 openssh-server-5.3p1-70.el6.x86_64:

no-port-forwarding,no-agent-forwarding,command="git-shell -c \"$SSH_ORIGINAL_COMMAND\"" ssh-dss AAAA...
share|improve this answer
    
This rocks, thanks! –  ceejayoz May 1 at 14:00

Grawity's solution can be easily modified to work by replacing the line

        exec $SSH_ORIGINAL_COMMAND

with the line

        git-shell -c "$SSH_ORIGINAL_COMMAND"

The quotes take care of the issues reported above, and replacing exec with git-shell seems a bit more secure.

share|improve this answer

git-shell is designed to be used as a login shell, so that it would receive -c "originalcommand" as arguments. This doesn't happen with "forced commands" in OpenSSH; instead, the forced command is passed to the configured shell.

What you can do is write a script that checks $SSH_ORIGINAL_COMMAND and executes it. Example in bash:

#!/bin/bash

SSH_ORIGINAL_COMMAND=${SSH_ORIGINAL_COMMAND/#git /git-}

case $SSH_ORIGINAL_COMMAND in
    "git-receive-pack"*|"git-upload-pack"*|"git-upload-archive"*)
        eval exec $SSH_ORIGINAL_COMMAND
        ;;
    *)
        echo "Go away." >&2
        exit 1
        ;;
esac
share|improve this answer
    
@Matt: git-shell(1) says the commands are git <cmd>, not git-<cmd>? –  grawity Jun 22 '11 at 9:50
    
Hmm... I made that change according to what I saw when I ran it. With both a bash script and a ruby script, I saw "git-receive-pack" as the command. Quote from my man git-shell (git 1.7.3.4): Currently, only four commands are permitted to be called, git-receive-pack git-upload-pack and git-upload-archive with a single required argument, or cvs server (to invoke git-cvsserver). –  Matt Connolly Jun 23 '11 at 0:16
    
formatting doesn't work in comments :( –  Matt Connolly Jun 23 '11 at 0:16
1  
This doesn't work for me, because my git client (1.7.5.4) sends the repo name in single quotes, presumably because it's expecting to have the entire command line interpreted by a shell. The exec $SSH_ORIGINAL_COMMAND then passes the single quotes on to git-receive-pack etc. which therefore doesn't find the repository. –  Neil Mayhew Oct 6 '11 at 15:50
    
Thanks for the solution, grawity, but it doesn't work for me, for the same reason that was reported by Neil Mayhew... my 1.7.x version of git also sends the repo name in single quotes, ultimately causing the $SSH_ORIGINAL_COMMAND to be invalid, and causing git-shell to bum out :-( –  pvandenberk Oct 13 '11 at 23:45

I couldn't get grawity's solution to work for the same reason that was reported by Neil Mayhew (ie. the single quotes sent by the git client causing an invalid $SSH_ORIGINAL_COMMAND -- I'm using git v1.7.x)

However, the following solution implemented by @moocode just works:

https://moocode.com/posts/6-code-your-own-multi-user-private-git-server-in-5-minutes

Ruby FTW! :-)

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.