[ Home on 246net ] [ Git index ]
Gitのリポジトリを、HTTP経由で読み書きするサーバーを構築します。
本記事では、CentOS 6の上でHTTPサーバーとGitに含まれるCGIコマンド git-http-backend を用いたGit HTTPサーバー環境の構築例を紹介します。
なお、WebDAVを使ってHTTP越しにリポジトリを変更する方法もありますが、ユーザー認証/性能の点で使用を見合わせました。
CentOS 6のgitについては、OS標準搭載の1.7.1の問題と回避策、新しいバージョンのgitを入れる方法の1つを紹介しています。
Gitリポジトリの認証については、HTTPの認証を利用する方法に加えて、チケット管理ツールRedmineのユーザー認証と統合する設定(必要なモジュール追加)を紹介します。
CentOS標準のgitをインストールします。なお、開発ツール一式と一緒に入れておきます。
# yum groupinstall "Development Tools"
CentOS 6(RHEL 6)標準搭載gitのバージョンは、1.7.1と古いものです。Gitは同じ1.7.xでも末尾の数字で大きな変更がある他、HTTPアクセスでBasic認証に問題があるため(本記事で後述)、できれば新しいバージョンのGitに差し替えたいところです。
Repoforge(旧RPMforge)で提供される新しいバージョンのgitをインストールします。
ただし、Repoforgeには極力依存したくないので、yumのリポジトリには追加せず、必要なrpmを個別にダウンロードして適用します。
Repoforgeが提供するRPMパッケージをインストールする場合、通常Repoforgeのyum設定ファイルをCentOS上に配置し、オンラインでインストールする手順が紹介されます。しかし、著者のCentOS設定ポリシーは、極力外部のyumリポジトリには依存しないこととし、CentOS自体とepelだけ有効にしています(ローカルにそれぞれのyumリポジトリのミラーを置いてます)。それ以外のパッケージを入れる場合は、面倒ですが手動でrpmパッケージをダウンロードしてからインストールしています。これは、インターネットと切り離された環境でのCentOSセットアップを可能にする意図をもっているからです。
# yum erase perl-Git Loaded plugins: fastestmirror Setting up Remove Process Resolving Dependencies --> Running transaction check ---> Package perl-Git.noarch 0:1.7.1-2.el6_0.1 will be erased --> Processing Dependency: perl(Git) for package: git-1.7.1-2.el6_0.1.x86_64 --> Processing Dependency: perl-Git = 1.7.1-2.el6_0.1 for package: git-1.7.1-2.el6_0.1.x86_64 --> Running transaction check ---> Package git.x86_64 0:1.7.1-2.el6_0.1 will be erased --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Removing: perl-Git noarch 1.7.1-2.el6_0.1 @base 35 k Removing for dependencies: git x86_64 1.7.1-2.el6_0.1 @base 15 M Transaction Summary ================================================================================ Remove 2 Package(s) Installed size: 15 M Is this ok [y/N]: y Downloading Packages: Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Erasing : git-1.7.1-2.el6_0.1.x86_64 1/2 Erasing : perl-Git-1.7.1-2.el6_0.1.noarch 2/2 Verifying : perl-Git-1.7.1-2.el6_0.1.noarch 1/2 Verifying : git-1.7.1-2.el6_0.1.x86_64 2/2 Removed: perl-Git.noarch 0:1.7.1-2.el6_0.1 Dependency Removed: git.x86_64 0:1.7.1-2.el6_0.1 Complete!
# yum localinstall git-1.7.11.3-1.el6.rfx.x86_64.rpm perl-Git-1.7.11.3-1.el6.rfx.x86_64.rpm Loaded plugins: fastestmirror Setting up Local Package Process Examining git-1.7.11.3-1.el6.rfx.x86_64.rpm: git-1.7.11.3-1.el6.rfx.x86_64 Marking git-1.7.11.3-1.el6.rfx.x86_64.rpm to be installed Loading mirror speeds from cached hostfile * base: ftp.riken.jp * epel: ftp.kddilabs.jp * extras: ftp.riken.jp * updates: ftp.riken.jp Examining perl-Git-1.7.11.3-1.el6.rfx.x86_64.rpm: perl-Git-1.7.11.3-1.el6.rfx.x86_64 Marking perl-Git-1.7.11.3-1.el6.rfx.x86_64.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package git.x86_64 0:1.7.11.3-1.el6.rfx will be installed --> Processing Dependency: perl(DBI) for package: git-1.7.11.3-1.el6.rfx.x86_64 ---> Package perl-Git.x86_64 0:1.7.11.3-1.el6.rfx will be installed --> Processing Dependency: perl(SVN::Client) for package: perl-Git-1.7.11.3-1.el6.rfx.x86_64 --> Processing Dependency: perl(SVN::Core) for package: perl-Git-1.7.11.3-1.el6.rfx.x86_64 --> Processing Dependency: perl(SVN::Delta) for package: perl-Git-1.7.11.3-1.el6.rfx.x86_64 --> Processing Dependency: perl(SVN::Ra) for package: perl-Git-1.7.11.3-1.el6.rfx.x86_64 --> Running transaction check ---> Package perl-DBI.x86_64 0:1.609-4.el6 will be installed ---> Package subversion-perl.x86_64 0:1.6.11-7.el6 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: git x86_64 1.7.11.3-1.el6.rfx /git-1.7.11.3-1.el6.rfx.x86_64 17 M perl-Git x86_64 1.7.11.3-1.el6.rfx /perl-Git-1.7.11.3-1.el6.rfx.x86_64 116 k Installing for dependencies: perl-DBI x86_64 1.609-4.el6 base 705 k subversion-perl x86_64 1.6.11-7.el6 base 796 k Transaction Summary ================================================================================ Install 4 Package(s) Total size: 19 M Total download size: 1.5 M Installed size: 22 M Is this ok [y/N]: y Downloading Packages: (1/2): perl-DBI-1.609-4.el6.x86_64.rpm | 705 kB 00:00 (2/2): subversion-perl-1.6.11-7.el6.x86_64.rpm | 796 kB 00:00 -------------------------------------------------------------------------------- Total 1.2 MB/s | 1.5 MB 00:01 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Installing : perl-DBI-1.609-4.el6.x86_64 1/4 Installing : subversion-perl-1.6.11-7.el6.x86_64 2/4 Installing : perl-Git-1.7.11.3-1.el6.rfx.x86_64 3/4 Installing : git-1.7.11.3-1.el6.rfx.x86_64 4/4 Verifying : git-1.7.11.3-1.el6.rfx.x86_64 1/4 Verifying : perl-Git-1.7.11.3-1.el6.rfx.x86_64 2/4 Verifying : subversion-perl-1.6.11-7.el6.x86_64 3/4 Verifying : perl-DBI-1.609-4.el6.x86_64 4/4 Installed: git.x86_64 0:1.7.11.3-1.el6.rfx perl-Git.x86_64 0:1.7.11.3-1.el6.rfx Dependency Installed: perl-DBI.x86_64 0:1.609-4.el6 subversion-perl.x86_64 0:1.6.11-7.el6 Complete!
CentOS標準のhttpd(Apache 2)と、httpdからPerlを実行するmod_perl、そしてダイジェスト認証時に使用するハッシュ perl-Digest-SHAをインストールしておきます。
# yum install httpd httpd-develop mod_perl perl_Digest_SHA
Redmine側でLDAP認証しているユーザーをGitでは使用しない場合は、追加モジュールは不要です。
Redmineをインストールした中に含まれるextra/svn/Redmine.pmを、Perlの検索パスのどこかに配置します。ここでは、/etc/httpd/の下に次のディレクトリ構造でシンボリックリンクを貼っておきます。
# mkdir -p /etc/httpd/Apache/Authn # ln -s /var/lib/redmine-2.2.2/extra/svn/Redmine.pm /etc/httpd/Apache/Authn/Redmine.pm
※ /var/lib/redmine のシンボリックリンクを作っておくのがバージョンアップ時に作業漏れがなくてよいかも。
まず上述のRedmine認証(LDAP認証を使わない)の手順にあるシンボリックリンクを作成します。
Redmine側でLDAP認証しているユーザーをGitで使用する場合、Perlの追加モジュールが必要になります。CentOS標準およびEPELから極力インストールしますが、どうしても不足するモジュールが2つ残ります(Auth::Simple、Authen::Simple::LDAP)。
この2つのモジュールについては、それぞれ次のいずれかの方法でインストールします。
CPANサイトからインストールすると、後々アンインストールが大変なので、OSの管理上できればRPM化したいところです。
CPANからインストールするとき、依存するモジュールも一緒にインストールしますが、極力RPMパッケージを使用したいので、あらかじめCentOS 6用にパッケージ化されているperlモジュールはCPANサイトからのインストールに先立ってインストールしておきます。
# yum install perl-LDAP perl-Params-Validate perl-Module-Runtime \ perl-Module-Implementation perl-Class-Accessor perl-Class-Data-Inheritable \ perl-Crypt-PasswordMD5 perl-Test-Simple
次に、CPANからインストールするためのパッケージをインストールします。
# yum install perl-CPAN perl-YAML
CPANからインストールを行います。cpan[n]> というプロンプトが表示されるので下線部のコマンドを入力し実行します。
# perl -MCPAN -e shell ... cpan[1]> o conf prerequisites_policy follow cpan[2]> o conf commit cpan[3]> install Authen::Simple::LDAP ...
途中、何回も次のような確認を求めてきます。実行時には不要なモジュールなので、いずれも no と入力します。
J/JP/JPEACOCK/version-0.9901.tar.gz is just needed temporarily during building or testing. Do you want to install it permanently? [yes] no
無事ビルド(makeとinstall)が完了すると、デフォルトのインストール先である/usr/local下にモジュールが展開されます。
$ find /usr/local -type f /usr/local/lib64/perl5/auto/Authen/Simple/LDAP/.packlist /usr/local/lib64/perl5/auto/Authen/Simple/.packlist /usr/local/share/perl5/Authen/Simple/Adapter.pm /usr/local/share/perl5/Authen/Simple/Password.pm /usr/local/share/perl5/Authen/Simple/ActiveDirectory.pm /usr/local/share/perl5/Authen/Simple/Apache.pm /usr/local/share/perl5/Authen/Simple/Log.pm /usr/local/share/perl5/Authen/Simple/LDAP.pm /usr/local/share/perl5/Authen/Simple.pm /usr/local/share/man/man3/Authen::Simple::Password.3pm /usr/local/share/man/man3/Authen::Simple.3pm /usr/local/share/man/man3/Authen::Simple::Apache.3pm /usr/local/share/man/man3/Authen::Simple::LDAP.3pm /usr/local/share/man/man3/Authen::Simple::ActiveDirectory.3pm /usr/local/share/man/man3/Authen::Simple::Adapter.3pm /usr/local/share/man/man3/Authen::Simple::Log.3pm $
Authen::Simpleモジュールについては、EPEL testingリポジトリにperl-Authen-Simpleパッケージが提供されています。これをダウンロードしてインストールします。
# yum localinstall perl-Authen-Simple-0.4-5.el6.noarch.rpm ...
Authen::Simple::LDAPのRPMパッケージを、rpmbuildコマンドでビルドして作成することとします。
RPM作成時に必要なSPECファイルの記述は、ゼロから書くのは大変なので、類似したRPMパッケージのものを流用します。
最初、上述のEPEL testingにあるperl-Auth-Simple-0.4-5.el6用のSPECファイルを流用しようとしたところ、perl-Authen-Simple.specではBuild.PLファイルを使ってビルドする記述になってましたが、perl-Authen-Simple-LDAPではMakefile.PLを使います。そこで、より新しいfedora 18のperl-Authen-Simple-0.5-3.fc18のspecファイルを参照したところ、こちらはMakefile.PLを使うようになっていました。そこで、fedora 18のものを参考にして今回perl-Authen-Simple-LDAP.specを作成しました。
CPANサイトから、Authen::Simple::LDAPのソースアーカイブをダウンロードします。CPANサイトを開き、"Authen::Simple::LDAP"を検索、Authen-Simple-LDAP-0.3ページから[Download]でモジュールアーカイブファイルをダウンロードします。
rpmbuildを初回に実施するユーザーであればrpmbuild初期設定を行います。
~$ mkdir -p rpm/{BUILD,RPMS,SOURCES,SPECS,SRPMS} ~$ vi .rpmmacros ~$ cat .rpmmacros %_topdir /home/torutk/rpm %packager Toru Takahashi <torutk@example.org> %dist .el6 ~$
ダウンロードしたperl-Authen-Simple-0.5-3.fc18.src.rpmからspecファイルを取り出します。
work$ rpm2cpio ~/perl-Authen-Simple-0.5-3.fc18.src.rpm | cpio -i work$ ls Authen-Simple-0.5.tar.gz perl-Authen-Simple.spec work$
このspecファイルを参考に、~/rpm/SPECS/perl-Authen-Simple-LDAP.spec を作成します。
Name: perl-Authen-Simple-LDAP Version: 0.3 Release: 1%{?dist} Summary: Simple LDAP authentication License: GPL+ or Artistic Group: Development/Libraries URL: http://search.cpan.org/dist/Authen-Simple-LDAP/ Source0: http://www.cpan.org/authors/id/C/CH/CHANSEN/Authen-Simple-LDAP-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: noarch BuildRequires: perl(Authen::Simple) BuildRequires: perl(Class::Accessor::Fast) BuildRequires: perl(Class::Data::Inheritable) BuildRequires: perl(Crypt::PasswdMD5) BuildRequires: perl(Module::Implementation) BuildRequires: perl(Params::Validate) BuildRequires: perl(Test::Fatal) BuildRequires: perl(Test::Requires) BuildRequires: perl(Try::Tiny) Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) %description Authenticate against a LDAP service. %prep %setup -q -n Authen-Simple-LDAP-%{version} %build %{__perl} Makefile.PL installdirs=vendor make %{?_smp_mflags} %install make pure_install PERL_INSTALL_ROOT=$RPM_BUILD_ROOT find $RPM_BUILD_ROOT -type f -name .packlist -exec rm -f {} \; find $RPM_BUILD_ROOT -depth -type d -exec rmdir {} 2>/dev/null \; %{_fixperms} $RPM_BUILD_ROOT/* %check make test %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) %doc Changes README %{perl_vendorlib}/* %{_mandir}/man3/* %changelog * Mon Jan 28 2013 Toru Takahashi <torutk@example.org> - 0.3-1 - Specfile created based on perl-Authen-Simple-0.4-5, and modified.
※ このspecファイルは、こちらのgithubに挙げています。
RPMパッケージを作成します。
~$ cp Authen-Simple-LDAP-0.3.tar.gz ~/rpm/SOURCES ~$ rpmbuild -ba rpm/SPECS/perl-Authen-Simple-LDAP.spec ... ~$ ls rpm/RPMS/noarch perl-Authen-Simple-LDAP-0.3-1.el6.noarch.rpm ~$
インストールします。
~$ yum groupinstall rpm/RPMS/noarch/perl-Authen-Simple-LDAP-0.3-1.el6.noarch.rpm ... ~$
認証不要でリポジトリを読み書きします。
共有のgit リポジトリを作成します。
# mkdir /var/lib/git # git init --bare --shared /var/lib/git/anonymous.git # cd /var/lib/git/anonymous.git # git update-server-info # mv hooks/post-update.sample hooks/post-update
http.receivepackをtrueにします。
# git config http.receivepack true
HTTPサーバーの設定で/gitへのアクセスをCGI呼び出しに置き換えます。
/etc/httpd/conf.d/git.conf
SetEnv GIT_PROJECT_ROOT /var/lib/git SetEnv GIT_HTTP_EXPORT_ALL ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
$ mkdir work $ cd work $ git clone http://cisterna/git/anonymous.git Initialized empty Git repository in /home/hogehoge/work/anonymous/.git/ warning: You appear to have cloned an empty repository. $ ls anonymous
$ cd anonymous $ vi README.txt $ git add README.txt $ git commit ... $ git push origin master Counting objects: 3, done. Writing objects: 100% (3/3), 262 bytes, done. Total 3 (delta 0), reused 0 (delta 0) To http://cisterna/git/anonymous.git * [new branch] master -> master $
Basic認証で認証されたユーザーのみアクセス可能な設定を行います。
/etc/httpd/conf.d/git.conf にBasic認証設定を以下のように記載
SetEnv GIT_PROJECT_ROOT /var/lib/git SetEnv GIT_HTTP_EXPORT_ALL ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/ <LocationMatch "^/git/basicauthen.git/.*"> AuthType Basic AuthName "Git Repository" AuthUserFile /etc/httpd/conf.d/git_auth.basic Require valid-user </LocationMatch>
リモートからクローンを試みるとエラーとなった
$ git clone http://foo.example.com/git/basicauthen.git Initialized empty Git repository in /home/torutk/work/basicauthen/.git/ error: The requested URL returned error: 401 while accessing http://foo.example.com/git/basicauthen.git/info/refs
HTTPサーバーのログは
192.168.123.146 - - [27/Jan/2013:10:09:00 +0900] "GET /git/basicauthen.git/info/refs?service=git-upload-pack HTTP/1.1" 401 475 "-" "git/1.7.1" 192.168.123.146 - - [27/Jan/2013:10:09:00 +0900] "GET /git/basicauthen.git/info/refs HTTP/1.1" 401 475 "-" "git/1.7.1"
git.confを以下のように修正した。
- <LocationMatch "^/git/basicauthen.git/.*"> + <LocationMatch "^/git/.*">
エラーは変わらなかった。
Windows上でCygwinのgit(バージョン1.7.9)では問題なくアクセスできることが分かった。原因は、CentOS 6.3 の git 1.7.1がBasic認証を要求するHTTPに対してアクセスするとき、ユーザーにユーザー/パスワードを入力するよう要求せず結果401エラーとなっています。Fedora 17のgit 1.7.11ではユーザー/パスワード入力を促してきます。
CentOS 6.xのgit 1.7.1のこの問題を回避する手段が2つあります。
Gitのリポジトリアクセス認証を、Redmineユーザー認証と統合する方法があります。ソフトウェア開発基盤にRedmineを使用している場合、認証はRedmineに統合するのが便利です。アクセス制御も、プロジェクトに対するRedmineのユーザーのアクセス権をGitリポジトリに引き継ぐので、ユーザー認証とアクセス権の管理を一元化することができます。また、RedmineユーザーをLDAP(Active Directory)で認証していた場合も対応できています。
httpd用の設定ファイルを作成します。ここでは、/etc/httpd/conf.d/redmine_git.conf としますが、設定ファイル名は拡張子.confであれば任意でOKです。
PerlLoadModule Apache::Authn::Redmine PerlLoadModule Authen::Simple::LDAP SetEnv GIT_PROJECT_ROOT /var/lib/git SetEnv GIT_HTTP_EXPORT_ALL SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/ <LocationMatch /git/> PerlAccessHandler Apache::Authn::Redmine::access_handler PerlAuthenHandler Apache::Authn::Redmine::authen_handler AuthType Basic AuthName Git # for Redmine Authentication RedmineDSN "DBI:mysql:database=redminedb;host=localhost" RedmineDbUser "redmine" RedmineDbPass "foobar" RedmineGitSmartHttp yes Require valid-user </LocationMatch>
クライアント側の設定(アカウントの指定方法)は、Basic認証と同じです。
Gitリポジトリにアクセスするユーザーは、Redmineの該当プロジェクトにメンバーとして登録し適切なアクセス権が設定されている必要があります。
$ git clone http://cisterna/git/mabinogion.pwyll Cloning into 'mabinogion.pwyll'... warning: You appear to have cloned an empty repository. $ ls mabinogion.pwyll
$ git push origin master Username for 'http://cisterna': hogehoge Password for 'http://hogehoge@cisterna': fugafuga Counting objects: 3, done. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 326 bytes, done. Total 3 (delta 0), reused 0 (delta 0) To http://cisterna/git/mabinogion.pwyll * [new branch] master -> master $
Redmine認証の場合、リポジトリの閲覧権は匿名でもあるため、git cloneはユーザー名/パスワードを入力することなく成功することが多いです。一方、git pushについては、perlモジュールの不足、設定ファイルの記述ミス、ディレクトリのアクセス権などの様々な要因でエラーになることがあります。