By user1813844

2012-11-10 02:39:57 8 Comments

I am curious as to how programs such as gitolite work -- specifically how do they interact with the SSH protocol to provide a tailored experience. Can somebody provide an example of how I might accomplish something like the following and where I might learn more about this topic?

→ ssh [email protected]
PTY allocation request failed on channel 0
Hi <username>! You've successfully authenticated, but GitHub does not provide shell access.
Connection to closed.

A side question: my primary language is JavaScript. Is it possible to accomplish what I want with NodeJS?


@VonC 2012-11-10 07:41:51

gitolite in itself is an authorization layer which doesn't need ssh.
It only needs to know who is calling it, in order to authorize or not that person to do git commands.

SSH is used for authentication (but you can use an Http Apache for authentication as well, for instance)

The way gitolite is called by ssh is explained in "Gitolite and ssh", and uses the ssh mechanism forced command:

The ~/.ssh/authorized_keys (on the gitolite ssh server) looks like:

command="[path]/gitolite-shell sitaram",[more options] ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA18S2t...
command="[path]/gitolite-shell usertwo",[more options] ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArXtCT...

First, it finds out which of the public keys in this file match the incoming login. Once the match has been found, it will run the command given on that line; e.g., if I logged in, it would run [path]/gitolite-shell sitaram.
So the first thing to note is that such users do not get "shell access", which is good!

(forced command = no interactive shell session: it will only provide a restricted shell, executing only one script, always the same)

Before running the command, however, sshd sets up an environment variable called SSH_ORIGINAL_COMMAND which contains the actual git command that your workstation sent out.
This is the command that would have run if you did not have the command= part in the authorized keys file.

When gitolite-shell gets control, it looks at the first argument ("sitaram", "usertwo", etc) to determine who you are. It then looks at the SSH_ORIGINAL_COMMAND variable to find out which repository you want to access, and whether you're reading or writing.

Now that it has a user, repository, and access requested (read/write), gitolite looks at its config file, and either allows or rejects the request.

The fact that the authorized_keys calls a perl script (gitolite-shell) is because Gitolite is written in perl.
It could very well call a javascript program.

If your ssh on GitHub without any command, you get a greeting message, like your mention in your question.
Gitolite displays a similar message, as detailed in the print_version() function of the info command script:

sub print_version {
    chomp( my $hn = `hostname -s 2>/dev/null || hostname` );
    my $gv = substr( `git --version`, 12 );
    $ENV{GL_USER} or _die "GL_USER not set";
    print "hello $ENV{GL_USER}, this is " . ($ENV{USER} || "httpd") . "\@$hn running gitolite3 " . version() . " on git $gv\n";

The message looks like:

hello admin, this is [email protected] running gitolite3 v3.0-12-ge0ed141 on git

The late 2013 Gitolite documentation now includes that diagram which summarizes all the pieces:

ssh and Gitolite

@user1813844 2012-11-12 03:16:22

So just out of curiosity, how can a site like GitHub utilize these techniques? It seems impractical to maintain an authorized_keys file for the git user containing everyone's public keys as well as handling changes to that file (deleting keys and whatnot)?

@VonC 2012-11-12 07:10:18

@user1813844 GitHub? But GitHub most certainly don't use gitolite. it has its own ssh key management. Which is no more or less practical than the ssh key management used by Gitolite, I suppose.

@user1813844 2012-11-13 14:13:38

So do they have their own version of SSHD? I'm trying to figure out how they could have built their system with standard existing technologies.

@VonC 2012-11-13 14:33:03

@user1813844 standard? not sure if their authorization mechanism is standard. They just built what they needed. Recently, they are based the authentication part on OAuth (, but for the authorization... it can be any in-house internal development they want.

@VonC 2012-11-13 14:34:34

@user1813844 GitLab, on the other hand, (a free GitHub look-alike) is using gitolite for the authorization. They are more recent, and gitolite was more mature at the time of their development.

@linquize 2013-01-30 10:19:59

only commands like git-upload-pack and git-receive-pack are allowed, other unix commands like ls, rm, are blocked.

@VonC 2013-01-30 10:35:34

@linquize correct, I mentioned as much in With V3, you also have a small list of gitolite commands which can be run:

@gabeio 2014-12-01 17:01:07

Sidenote: github like bitbucket most likely uses a slightly modified version of sshd which allows lookups in a large db. which they talk about here: ; just like bitbucket github most likely uses haproxy to allow loadbalancing of the ssh.

@VonC 2014-12-01 19:00:17

@gabeio I agree, but GitHub or BitBucket don't use gitolite at all, do they?

@gabeio 2014-12-01 20:58:38

github uses a custom build ruby gem is what I got from reading the creator's blog, and bitbucket is built on java so they most likely have a custom app also I doubt either of them use gitolite, but I don't work for either company so I am just guessing.

@Sitaram 2012-12-23 14:56:53

Note that sshd does a linear scan of the ~/.ssh/authorized_keys file. Once you get about 3000 keys in there, people whose keys appear later in the file start to notice the lag -- it begins to be more than network lag :-)

That is one reason why github has their own patched version of sshd. They have far too many users to be able to manage with normal sshd!

@tpg2114 2012-11-10 02:58:23

The basic steps are:

  1. Check the public key of the person trying to log in
  2. Map the public key to an access control list

In other words, for these things to work, you have to get public keys from the users and then generate a list (file, database, whatever) that pairs a key to a user and permissions.

@user1813844 2012-11-10 04:35:04

I am more interested in the mechanics of using the SSH protocol.

@tpg2114 2012-11-10 04:39:21… Then make your questions clearer. I looked at the comment at the top of the gitolite source and it said "script invoked from ~/.ssh/authorized_keys" so I searched for how to invoke a script from the authorized_keys file and found that question.

@tpg2114 2012-11-10 04:40:44

I'm not trying to troll here. But I'm not inclined to go into a ton of detail to answer the question when it doesn't look like much effort went into figuring it out independently.

Related Questions

Sponsored Content

29 Answered Questions

[SOLVED] How to specify the private SSH-key to use when executing shell command on Git?

  • 2010-12-30 19:42:01
  • Christoffer
  • 1161734 View
  • 1211 Score
  • 29 Answer
  • Tags:   git bash shell ssh

17 Answered Questions

[SOLVED] How to use SSH to run a local shell script on a remote machine?

1 Answered Questions

[SOLVED] Connecting to github repository via ssh

  • 2020-07-09 14:28:33
  • Gelo
  • 31 View
  • 1 Score
  • 1 Answer
  • Tags:   github ssh

6 Answered Questions

16 Answered Questions

[SOLVED] github: No supported authentication methods available

12 Answered Questions

[SOLVED] Git's famous "ERROR: Permission to .git denied to user"

  • 2011-03-17 05:22:50
  • meder omuraliev
  • 116164 View
  • 122 Score
  • 12 Answer
  • Tags:   git ssh github

1 Answered Questions

[SOLVED] How to get current user's ssh public key from the Linux ssh server?

  • 2014-04-26 03:09:54
  • Cheng
  • 1327 View
  • 0 Score
  • 1 Answer
  • Tags:   security ssh pki

3 Answered Questions

2 Answered Questions

2 Answered Questions

[SOLVED] osx - gitolite: login with git user from terminal

  • 2012-02-16 12:47:16
  • paolaccio
  • 1889 View
  • 1 Score
  • 2 Answer
  • Tags:   git ssh gitolite

Sponsored Content