I'm trying to set up a secure git repository server using ssh-keys and git-shell. Since our user database is stored in a central LDAP directory, I can't change users' default shell to git-shell, so I've tried prepending the git-shell command to the public key in the authorized_users file like this:

command="git-shell -c $SSH_ORIGINAL_COMMAND" ssh-dss AAAAB3NzaC1kc3...

However, git-shell won't even allow me to clone the repository:

    dhcp202:git-ws frank$ git clone ssh://gitserver/var/repos/git/myrepo/
    Cloning into myrepo...
    fatal: What do you think I am? A shell?
    fatal: The remote end hung up unexpectedly

Any ideas appreciated...

3 Answers 3


You will find a similar mechanism with gitolite, based on ssh and forced command.
(including ldap queries).
It don't allow interactive shell however, which could be your issue there.

The OP Frank Brenner adds:

Ah, I figured it out - the command has to be in single quotes. I suppose $SSH_ORIGINAL_COMMAND was getting expanded before git-shell was started.

That is confirmed in the gitolite forced command script is a Perl one, ending with:

# ----------------------------------------------------------------------------
#       over to git now
# ----------------------------------------------------------------------------

    # the GIT_HTTP_BACKEND env var should be set either by the rc file, or as
    # a SetEnv in the apache config somewhere


$repo = "'$REPO_BASE/$repo.git'";
exec("git", "shell", "-c", "$verb $repo") unless $verb eq 'git-init';

Note the $repo = "'$REPO_BASE/$repo.git'" line: it does contains single quotes.

  • Thanks for the info, but shouldn't git-shell as forced-command allow a "clone" operation? Mar 23, 2011 at 14:15
  • @FRank: yes, but I suppose there is an issue in the way you are calling git-shell (btw, did you try "git shell" instead of "git-shell"?)
    – VonC
    Mar 23, 2011 at 14:19
  • Yes I did try "git shell ...", to no avail, though. Mar 23, 2011 at 15:17
  • Ah, I figured it out - the command has to be in single quotes. I suppose $SSH_ORIGINAL_COMMAND was getting expanded before git-shell was started... Mar 23, 2011 at 15:58
  • @Frank: excellent. I have included your solution in my answer, pointing out the single quotes in the gitolite forced-command script as well.
    – VonC
    Mar 23, 2011 at 16:11

I've made a solution using LDAP, OpenSSH (>4.9) and git-shell.

OpenSSH's ForceCommand is perfect for the job. Consider the following configuration (everyone except admins have to use git-shell):

Match group *,!admin    
    ForceCommand /usr/bin/git-shell -c "$SSH_ORIGINAL_COMMAND"

Access control is defined using ACL-s and reponame access groups.

setfacl -bR -m default:group:$REPONAME:rwX -m group:$REPONAME:rwX $GITROOT/$REPONAME
setfacl -R -m default:group:$REPONAME-ro:r-X -m group:$REPONAME-ro:r-X $GITROOT/$REPONAME

Don't forget to run "nscd -i group", after each change.



This authorized_keys works for me and is properly shell quoted:

restrict,command="/usr/bin/git-shell -c \"$SSH_ORIGINAL_COMMAND\"" ssh-rsa AAAAB3NzaC1yc2EAA...

man sshd describes the authorized_keys file format:

A quote may be included in the command by quoting it with a backslash.

The same man page describes restrict:

Enable all restrictions, i.e. disable port, agent and X11 forwarding, as well as disabling PTY allocation and execution of ~/.ssh/rc. If any future restriction capabilities are added to authorized_keys files they will be included in this set.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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