gitoliteはどうやってユーザを判別しているか


ちょっとしたコネタの紹介

gitoliteをhostgitというユーザ名でインストールするとssh://git@host:reponame.gitreponameというリポジトリに対するアクセス制御をすることができる。
当然ながらssh://git@host:reponame.githostgitというユーザ名でSSH接続することを意味する。

で、不思議なのはgitoliteは一体どうやってユーザの判別をしているのか、ということだ。

なにせgitoliteはサーバ上にインストールされているのだから、gitoliteから見たらどのアクセスもgitというユーザなのだ。どうやってgitoliteは「このアクセスはyuku_tからだ」「こっちのはyaottiからだ」という風に判断しているのだろう。(むしろこれができなければアクセス制御なんてできっこない)

答えはgitユーザのauthorized_keysファイルにある。

authorized_keysが単なる公開鍵置き場だと思ったら大間違い。実はもっといろいろな設定ができるのだ。
以下にauthorized_keysの例を引用する。

# gitolite start
command="/home/git/gitolite/src/gitolite-shell taka84u9",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3NzaC1y...== taka84u9
# gitolite end

ssh-rsa以降が普段我々が公開鍵を設定している箇所だ。
そしてその前半部分にcommandno-port-forwardingなど見覚えのない部分がある。
実はsshdは公開鍵でユーザの認証を取ったあとの制御をこの部分で記述することができるのだ。
そして、commandというのがユーザがログイン後に実行するコマンドになる。よくよく見てみると

command="/home/git/gitolite/src/gitolite-shell taka84u9"

gitolite-shellというコマンドに対して引数でユーザ名が渡されている。
先ほどの疑問の答えがこれで、このスクリプトの中でアクセス制御が行われる。
またこのユーザ名は$GL_USERという環境変数に格納されるためgitoliteで管理されているgitリポジトリのhookの中でユーザの判別もできる、という訳。

なかなか面白い実装だと思う。