gitolite で Git リポジトリへの SSH アクセスを制御する
先日、安価な VPS サービスである ServersMan@VPS を契約しまして、以前から欲しいと思っていた Git リポジトリのホスティング環境を構築してみました。複数の Git リポジトリを作成して、リポジトリごとにアクセスできるユーザーを制限するものです。 Github を使えという話もありますが、単にリポジトリが欲しいだけなら VPS のほうが安いので… ^^;
これを実現する最も素直なやり方は、ユーザーごとにサーバーのローカルユーザーを作成し、 OS のファイルパーミッションでアクセス制限することです。しかし、すべてのユーザーに個別にローカルユーザーを発行するのはさすがに面倒。もっといい方法はないかと探したところ、 gitosis と gitolite という 2 つのプログラムが見つかりました。どちらも私の望みの機能は持っているようですが、より高機能でドキュメントも比較的整っている gitolite のほうを使うことにしました。
ということで、本日は gitolite を使って Git リポジトリのアクセス権限の制御を行う方法をご紹介します。以下の内容は ServersMan@VPS の debian で確認しましたが、 git のインストール以外は大抵の Linux ディストリビューションに適用できると思います。
ユーザーの仮想マシンを勝手に操作するなんてことを平気でしてくれるので、 ServersMan@VPS は解約しました。正直、信用できるサービスではないと思います。
準備
gitolite をインストールする前に、必要な環境を整えましょう。 gitolite のドキュメントによると、必要なものは以下のとおりです。
- git バージョン 1.6.2 以上
- perl
- OpenSSH
ServersMan@VPS (debian) では perl と OpenSSH は標準でインストールされているので、以下では git のインストールを行います。さらに、 Git リポジトリへアクセスするために使用するユーザーも作成します。当然ですが、以下の作業は root で行ってください。
git のインストール
git のインストールは apt-get コマンド一発…といきたいところですが、残念ながら現在の debian (lenny) でインストールされる git はバージョン 1.5 系とかなり古いもので、 gitolite は動作しません。そこで、パッケージの取得元に lenny-backports を加えて、新しい git がインストールできるようにします。具体的には、以下のコマンドを実行します(読みやすさから行を分けていますが、一行で入力してください)。
echo "deb http://backports.debian.org/debian-backports lenny-backports main" > /etc/apt/sources.list.d/lenny-backports.list
そして、パッケージリストをアップデートし、 git をインストールします。
apt-get update apt-get -t lenny-backports install git
これで gitolite が動作する git (たぶん git 1.7 系)がインストールされるはずです。以下のコマンドでバージョンが 1.6.2 以上であることを確認してください。
git --version
リポジトリアクセス用のユーザーを作成する
次に、 Git リポジトリへのアクセスのために共通で利用するローカルユーザーを作成しておきます。名前は「git」だと標準のなにかにバッティングしそうなので、私は「gituser」にしておきました。基本的に以下のコマンドを実行すれば良いはずです。
useradd -m -U gituser passwd gituser # gituserのパスワードを2回入力
gitolite のスクリプトは $HOME/bin にインストールされるので、それを実行パスに追加する必要があります。私は遭遇しませんでしたが、 gitolite を使って SSH アクセスした際に実行パスが設定されないことがあるようなので、念のため .bashrc の先頭に以下の行を挿入しておくのが無難かと思います。
export PATH="/home/gituser/bin:/home/gituser/bin:/usr/local/bin:/usr/bin"
以上で gitolite に必要な環境が整いました。
gitolite のインストール
それでは gitolite をインストールしましょう。実は debian の lenny-backports には gitolite のパッケージがあり、それを利用してインストールすることも可能です。しかし、 gitolite のインストールはとても簡単なので、ここでは多くの環境で利用できる、通常ユーザー権限でのインストール方法を使います。この方法なら debian 以外のディストリビューションはもちろん、 root 権限のない共有サーバーでも対応できるはずです。
root 権限不要のインストール方法なので、以下の作業は gituser で行ってください。
管理ユーザー用の認証鍵の作成
gitolite では、各ユーザーは認証鍵(公開鍵・秘密鍵のペア)により識別されます。インストール時には管理者用公開鍵を指定する必要があるので、自分の公開鍵を gituser が読み込める場所にコピーしておいてください。ここでは以下のパス($HOME は gituser のホームディレクトリ)にコピーしたと仮定します。
$HOME/admin.pub
※ root 権限を持っていない場合は、ここで使用する公開鍵は普段のログイン用とは別のものにしてください。詳細は後述。
gitolite のインストール
公開鍵の準備ができたら、いよいよ gitolite のインストールです。基本的には、以下のコマンドを順番に実行するだけです。
mkdir -p $HOME/bin $HOME/gitolite/conf $HOME/gitolite/hooks git clone git://github.com/sitaramc/gitolite gitolite-source cd gitolite-source src/gl-system-install $HOME/bin $HOME/gitolite/conf $HOME/gitolite/hooks gl-setup $HOME/admin.pub
gl-setup の実行後、エディタが開いて設定ファイルを編集できます。もっとも、多くの場合はデフォルトで大丈夫だと思います。設定は ~/.gitolite.rc を編集することでいつでも変えられます。
以上でインストールは終了です。
管理用 Git リポジトリを取得する
gitolite では、ユーザーやリポジトリの追加などの管理作業は、すべて gitolite-admin という Git リポジトリのファイルを変更して push することにより行います。そこで、まずは自分のクライアントマシンにこのリポジトリを clone します。 Git リポジトリのあるサーバーのホスト名を仮に「gitserver.com」とすると、以下のコマンドで取得できます。
git clone gituser@gitserver.com:gitolite-admin
これで、カレントディレクトリ内に gitolite-admin ディレクトリが作成され、管理用のファイルがその中に作成されるはずです。
ユーザーやリポジトリの追加
前述のとおり、 gitolite での管理作業はすべて、 gitolite-admin リポジトリに変更を push することで行います。ここでは、ユーザーの追加とリポジトリの追加の方法をご紹介します。以下の作業は自分のクライアントマシン(上で gitolite-admin リポジトリを clone したマシン)上で実行してください。
ユーザーの追加
gitolite は認証鍵(公開鍵・秘密鍵ペア)によってユーザーを識別します。したがって、ユーザーを追加するには、まずそのユーザーの認証鍵を作成しなければなりません。認証鍵は以下のコマンドで作成できます。
ssh-keygen -t rsa
実行すると認証鍵のファイル名を尋ねてくるので、適当に入力してください(くれぐれも自分の認証鍵を上書きしないように!)。ここでは ~/foo と入力したと仮定します。続けてパスフレーズを尋ねてきますが、これはお好みで。
作成した秘密鍵はそれを使用するユーザーに渡し、公開鍵は gitolite-admin/keydir にコピーします。
cp ~/foo.pub /path/to/gitolite-admin/keydir
そして、この変更をコミットしておきます。
cd /path/to/gitolite-admin git commit -a
これでユーザーの追加は完了です。実際にサーバーに反映するためには push しなければなりませんが、その前にユーザーがアクセスするリポジトリを作成(もしくは既存のリポジトリへのアクセスを許可)しなければ意味がないので、その作業に移ります。
リポジトリの追加
リポジトリと各ユーザーのアクセス権限は gitolite-admin/conf/gitolite.conf で管理されています。インストール直後にこのファイルを開くと、以下の内容になっているはずです。
repo gitolite-admin RW+ = admin repo testing RW+ = admin
これは、 gitolite-admin, testing という 2 つのリポジトリがあり、いずれも admin ユーザーのみがアクセスできることを表しています。 gitolite.conf の基本的な文法は以下のとおりです。
repo [リポジトリ名] [アクセス権限] = ユーザー名 [ユーザー名...] ...
上記のうち、 [リポジトリ名] はそれ以降でアクセス権限を指定するリポジトリ名、 [ユーザー名] はアクセス権限を設定するユーザーの名前(公開鍵のファイル名部分)です。 [アクセス権限] には以下の 3 つを指定できます。
指定 | 権限 |
---|---|
R | 読み込みのみ |
RW | 読み込み / 書き込み |
RW+ | 読み込み / 書き込み / rewind |
したがって、新しいリポジトリ「newrepo」を作成し、 admin ユーザーにフルアクセスを、 foo ユーザーに読み込みのみを許可するなら、 gitolite.conf に以下の内容を追加します。
repo newrepo RW+ = admin R = foo
そして、変更をコミットします。
cd /path/to/gitolite-admin git commit -a
これで新しいリポジトリの作成の指定ができました。
変更の適用
これまでの変更はローカルのリポジトリ上でのものなので、実際にサーバーに適用するには push する必要があります。方法はもちろんご存知かと思いますが、以下のコマンドを実行するだけです。
cd /path/to/gitolite-admin git push
これで gitolite-admin リポジトリの変更がローカルからサーバーに転送されると同時に、その内容にしたがって ~/.ssh/authorized_keys への公開鍵の追加やリポジトリの作成など、必要な作業がすべて実行されます。
試しに newrepo リポジトリを clone してみてください。
git clone gituser@gitserver.com:newrepo
空のリポジトリが clone されるはずです。
その他の Tips
以下、上記の作業中に気づいたことなど。
SSH のポート番号を変更している場合
gitolite 経由でリポジトリにアクセスする場合、必ず「ユーザー@サーバー:リポジトリ」形式でリポジトリ指定をしなければならず、「ssh://〜」のような URL 形式は使えません。したがって、ポート番号が変更されている場合は ~/.ssh/config で指定しておく必要があります。また、リポジトリアクセスに専用の認証鍵を使用する場合もこの方法が使えます。
Host [ホスト名] Port [ポート番号] IdentityFile /path/to/secret_key_rsa
こんな感じで ~/.ssh/config に書いておけばよいかと思います。
共有サーバーに gitolite をインストールする際の注意点
共有サーバーの場合など、自分が普段ログインユーザーとして使っているユーザーと同じユーザーで gitolite をインストールする際は、インストール時に指定する管理者用公開鍵を普段のログイン用公開鍵とは別にしてください。ここで同じものを使用してしまうと、その鍵でのログインが Git リポジトリへのアクセスのみに制限されてしまいます。とくにパスワードログインが禁止されている場合はログイン不可能になってしまうので、注意してください。
また、共有サーバーなどで標準とは違うパスに git がインストールされている場合は、 .gitolite.rc で $GIT_PATH にそのパスを設定する必要があります。
さらに詳細な指定
私はリポジトリ単位でアクセス制限ができれば十分だったので詳しく調べていませんが、設定次第で特定のタグ・ブランチに対するアクセス制限やユーザーのグループ化などの機能が利用できるようです。詳細はインストール時にサーバーに clone した gitolite-source リポジトリにある conf/example.conf に書いてあるので、必要な方はそちらを参照してください。
以上、本日は gitolite を使用して Git リポジトリへの SSH アクセスを制御する方法をご紹介しました。この方法を使えば、自分のサーバーに作成した Git リポジトリを簡単に他人に公開し、共同作業が行えます。 Git の利用の幅が一気に広がりますので、ぜひお試しください!
補足情報
- gitolite と同様な機能を持つ gitosis の解説が GREE Engineers' blog で公開されています。 Hook スクリプトを使ったメール通知なども解説されているので、 gitolite を使っていても参考になります。
詳しくはこちらの記事をどうぞ!
この記事にコメントする