SSHとHTTPSでアクセスできるGitサーバの設計と構築
(追記) この記事は公開から時間が経っており、内容が古くなっています。
本稿では、すでにプライベートなWebサーバを運用している人向けにGitサーバの構築方法を説明します。ひと手間をかけるだけでGitサーバを構成できます。Webサーバがない人はGitHubでプライベートリポジトリを作った方が早くて安くて旨いかもしれません。
要件
以下の要件を考えてみます。
具体的には、
git clone git@git.example.com:/something.git
とか、
git clone https://myname@git.example.com/something.git
とかしたいです。
設計
世の中で広く使われている標準的な構成を採用します。
セキュリティ設計
リポジトリには機密情報が含まれる可能性があるため、リポジトリにアクセスできる手段を可能な限り絞り込みます。具体的には、以下のように設計します。
Gitolite
Gitoliteは、Gitリポジトリを管理するためのツールです。リポジトリからSSH設定までまるっと管理してくれます。詳しい仕組みは ユカイ、ツーカイ、カイハツ環境!(26):Git管理の神ツール「Gitolite」なら、ここまでできる! (1/2) - @IT が参考になります。本稿では以下の設計とします。
GitWeb
GitWebは、Webベースのリポジトリビューアです。GitHubに比べたらお世辞にも高機能とは言えませんが、CGIファイルを置くだけで使えるので簡単です。詳しくは Git - GitWeb が参考になります。本稿では以下の設計とします。
git-http-backend
git-http-backendは、HTTP経由のリポジトリアクセスを実現するためのバックエンドです。詳細な仕組みは Smart HTTP Transport が参考になります。本稿では以下の設計とします。
- suexecを利用してgitユーザでバックエンドを実行します。
- suexecを利用するため、バックエンドを呼び出すラッパースクリプトを /var/www/git に配置します。
Apache httpd
以下の設計とします。
- 他のWebサイトとGitサーバを分離したいので、新しくバーチャルホストを作成します。ここでは https://git.example.com とします。
- パスワードを保護するため、SSLを使います。
- ワイルドカード証明書(例:*.example.com)にしておくと、SSLでもバーチャルホストを増やせるので便利です。
- 自己署名CAの場合は、WebブラウザにCA証明書をインポートしておきしましょう。
- suexecを有効化します。
構築
Gitolite
詳しい方法は ユカイ、ツーカイ、カイハツ環境!(26):Git管理の神ツール「Gitolite」なら、ここまでできる! (1/2) - @IT を参照してください。
結果的に、以下のディレクトリ構造があればOKです。
- /home/git (git:git 700)
- repositories/
- gitolite-admin.git/
- 他のリポジトリ...
- repositories/
Apache httpd
下記のようにhttpd.confを設定します。これはApache httpd 2.4の例です。2.2では手直しが必要です。あと、バーチャルホスト以外の設定は省略しています。
# Basic SSL setup SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5 SSLPassPhraseDialog builtin SSLSessionCache shmcb:/var/cache/mod_ssl/scache(512000) SSLSessionCacheTimeout 300 SSLCertificateFile /etc/pki/https-wildcard.crt # 環境に応じて変更してください SSLCertificateKeyFile /etc/pki/https-wildcard.key SSLCACertificateFile /etc/pki/https-ca.crt Listen 443 <VirtualHost *:443> SSLEngine on ServerName git.example.com SuexecUserGroup git git DocumentRoot /var/www/git <Location /> AuthMerging And Authname "git" Include "/etc/httpd/conf.d/auth-ldap" # 認証方式に応じて変更してください Require user someone </Location> <Directory /var/www/git> Require all granted Options ExecCGI AddHandler cgi-script .cgi DirectoryIndex gitweb.cgi </Directory> ScriptAliasMatch ^/.*\.git/.*$ /var/www/git/git-http-backend-wrapper.cgi$0 </VirtualHost>
ポイントは、
- 認証を有効にします。
- / にアクセスすると GitWeb が実行されるようにします。
- .git/ が含まれるパスにアクセスするとバックエンドラッパーが実行されるようにします。
git-http-backend
下記の内容で /var/www/git/git-http-backend-wrapper.cgi を配置します。chmod +xしておきます。
#!/bin/sh export GIT_PROJECT_ROOT=/home/git/repositories export GIT_HTTP_EXPORT_ALL=1 export GIT_HTTP_BACKEND=/usr/libexec/git-core/git-http-backend export GITOLITE_HTTP_HOME=/home/git exec gl-auth-command
ポイントは、
- このスクリプトはGitoliteを経由してgit-http-backendを実行するラッパーの役割を果たします。
- Gitoliteとgit-http-backendに必要な環境変数を設定します。
GitWeb
設定ファイル(/etc/gitweb.conf)にリポジトリパスを指定します。
テスト
まず https://git.example.com/ にアクセスしてみましょう。GitWebのリポジトリ一覧が表示されるはずです。
今度はHTTPS経由でgit cloneしてみましょう。
git clone https://myname@git.example.com/something.git
別のリポジトリを使って、HTTPS経由のgit pushも試してみましょう。
git remote add private https://myname@git.example.com/hoge.git git push private master
うまくいきましたか?アクセスに失敗した場合はApache httpdのエラーログやsuexecログを参照します。特にsuexecの実行条件はかなり複雑なので、一つずつ問題を解決していきましょう。