日本語資料がまったくなかったので怒りのQiita初投稿
目標/仕様
- gitoliteを用いてGitレポジトリの権限管理を行う。
- Gitに対する接続はSSH,HTTPSともに確保する。
- サーバー上に存在するGitレポジトリをgitwebで表示する。
ただし、閲覧できるレポジトリはgitoliteにより指定されるものとする。 - nginxはGit以外の公開ページにも用いるため、gitolite,gitwebはサブディレクトリに配置する。サブドメインにしなかったのはCertbotでワイルドカード証明書が取れないため。
サブドメインごとに取るのめんどい
構成
- git 2.10.0.rc1
- gitolite v3.6.6-3-g72c0238
- nginx 1.10.2
ちなみにCentOS7 on さくらのVPSです
前提
- gitがインストールされていること(gitwebが同梱されているため)
- nginxがインストールされており、接続できること
なにはともあれまずはgitolite
git:gitとしてgitoliteを立ち上げるとする。
gitoliteを公式ドキュメント( http://gitolite.com/gitolite/install.html )に従ってインストールすると/home/git/にもろもろのファイルが配置される。これではパーミッションの関係で、gitへのSSHアクセスかnginxのnginxユーザでの立ち上げのどちらかを諦めなければならない。
そこで、gitoliteのインストールフォルダを変更する(ここでは/path/to/gitolite/とする)
$ su - git
$ cd /path/to/gitolite
$ mkdir bin
$ git clone git://github.com/sitaramc/gitolite
$ gitolite/install -ln bin
$ gitolite setup -pk admin.pub
#ユーザ識別用の鍵を指定。公開鍵は事前にSCPかなにかで送っておく
注意としてはユーザ識別用の鍵としてSSHログイン用の鍵を用いないこと。SSHログインなのかgitolite向けのログインなのか分からねーよと怒られてしまう。
これだけではダメで、SSHとHTTPS両方でアクセス可能にするためには、上で書いたようにgitoliteのフォルダが/home/git以下にあってはならない。そこで/path/to/gitoliteに全部引っ越して、/home/gitからはシンボリックリンクを貼ることで対処する。
$ mv ~/.gitolite* /path/to/gitolite/
$ mv ~/repositories /path/to/gitolite/
$ ln -s /path/to/gitolite/.gitolite ~/.gitolite
$ ln -s /path/to/gitolite/.gitolite.rc ~/.gitolite.rc
$ ln -s /path/to/gitolite/repositories ~/repositories
また、お引っ越しをしたことにより設定をいじってやる必要がある。具体的には
- nginxが読み書きできるように、パーミッションの変更
- レポジトリの保存フォルダの変更
- gitoliteのバイナリにパスを通す
の3点である。
+ $ENV{PATH} .= ":/path/to/gitolite/bin";
...
%RC = (
...
- UMASK => 0007
+ UMASK => 0007
...
+ GL_REPO_BASE => "/path/to/gitolite/repositories",
)
ここまででとりあえずgitoliteがSSHで通るようになった。
git clone git@hogehoge:testing が通ることを確かめておくと良い。ただしSSH鍵はgitユーザのものではなくインストールの際に指定したadminの鍵である。
spawn-fcgiのインストール
gitoliteとnginxを連携させるにはCGIが動かなければならない。そのための下準備としてspawn-fcgiをインストールしておく。
$ sudo yum install fcgi-devel automake autoconf spawn-fcgi
$ git clone https://github.com/gnosek/fcgiwrap
$ cd fcgiwrap
$ autoreconf -i
$ ./configure
$ make
$ sudo make install
spawn-fcgiのコンフィグをnginx向けに修正。このとき、CGIを呼び出す際にgitグループとして実行しているため、nginxユーザをgitグループに追加する必要がある。
$ usermod -a -G git nginx
...
+ OPTIONS="-u nginx -g git -s /var/run/fcgiwrap.sock -S -M 0660 -F 4 -P /var/run/spawn-fcgi.pid -- /usr/local/sbin/fcgiwrap"
gitolite over HTTPS with nginx
https://hogehoge/git/ にアクセスした際にnginxがspawn-fcgiを呼び出すように設定を行う。この際、Basic認証によってユーザを識別するので、予めhtpasswdファイルを作成しておく。
$ sudo yum install httpd-tools
$ sudo htpasswd -cs /var/www/git/.htpasswd USERNAME
location /git/ {
auth_basic "Restricted";
auth_basic_user_file /var/www/git/.htpasswd;
access_log /var/log/nginx/git_access.log main;
error_log /var/log/nginx/git_error.log;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
fastcgi_split_path_info ^(/git)(/[^/]+\.git/.*);
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /path/to/gitolite/gitolite/src/gitolite-shell;
fastcgi_param GITOLITE_HTTP_HOME /path/to/gitolite;
fastcgi_param GIT_PROJECT_ROOT /path/to/gitolite/repositories;
fastcgi_param GIT_HTTP_EXPORT_ALL 1;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param REMOTE_USER $remote_user;
fastcgi_pass unix:/var/run/fcgiwrap.sock;
}
また、Basic認証はそのままだとパスワードが平文で流れるので、HTTPSで通信するよう強制する。サーバー証明書はCertbot/Let's Encryptを用いるとよい。nginxでのHTTPS通信およびCertbot/Let's Encryptについては日本語資料もそこそこあるため適宜参照のこと。
...
- user nginx nginx;
+ user nginx git;
...
http{
...
server{
listen 80 default_server;
listen [::]:80 default_server;
server_name hogehoge;
+ return 301 https://$host$request_uri;
...
ここまででSSH/HTTPSそれぞれでgitoliteにアクセスできるようになったはずである。
git clone https://hogehoge/git/testing.git して試してみると良い。
gitweb-gitolite連携
コードの基礎は http://gitolite.com/gitolite/gitweb.conf.html にあるとおりである。つまりnginxから受け取ったユーザ名をgitoliteに引き渡してやれば良い。ただしnginxでは少し工夫が必要となる。
まずはnginxの設定である。
location /gitweb/ {
auth_basic "Restricted";
auth_basic_user_file /var/www/git/.htpasswd;
root /usr/local/share/;
access_log /var/log/nginx/gitweb_access.log main;
error_log /var/log/nginx/gitweb_error.log;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
# fastcgi_split_path_info ^(/git)(/[^/]+\.git/.*);
index /gitweb/index.cgi;
gzip off;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /usr/local/share/gitweb/gitweb.cgi;
fastcgi_param GITWEB_CONFIG /usr/local/share/gitweb/gitweb.conf.pl;
fastcgi_param REMOTE_USER $remote_user;
if ($uri ~ "/gitweb/index.cgi"){
fastcgi_pass unix:/var/run/fcgiwrap.sock;
}
}
gitwebで用いられている/etc/gitweb.confの代わりに/usr/local/share/gitweb/gitweb.conf.plを用いるよう指定する点、および$ENV{REMOTE_USER}に$remote_userを渡してやる点がミソである。そして、そのgitweb.conf.plの内容は以下である。ほとんどさっき出したサイトのコピー
BEGIN {
$ENV{HOME} = "/path/to/gitolite/";
$ENV{GL_BINDIR} = "/path/to/gitolite/gitolite/src";
$ENV{GL_LIBDIR} = "/path/to/gitolite/gitolite/src/lib";
}
use lib $ENV{GL_LIBDIR};
use Gitolite::Easy;
$projectroot = $ENV{GL_REPO_BASE};
# Changed from original gitweb.conf.pl
# for nginx
$ENV{GL_USER} = $ENV{REMOTE_USER} || "Anonymous";
$export_auth_hook = sub {
my $repo = shift;
return unless $repo =~ s/^\Q$projectroot\E\/?(.+)\.git$/$1/;
return can_read($repo);
};
これでようやく完成。https://hogehoge/gitweb/ にアクセスするとユーザ名とパスワードが要求され、ログインするとそのユーザがRead権限を持っているレポジトリが閲覧できる。はず。
参考Web
- http://qiita.com/egnr-in-6matroom/items/2a052339ee0515b31fdf (git+nginxの設定の基礎)
- http://gitolite.com/gitolite/ssh-and-http.html (gitolite+smart httpの設定:公式ドキュメント)
- http://gitolite.com/gitolite/gitweb.conf.html (gitolite+gitweb+Apacheの設定)