チャプター ▾ 第2版

4.1 サーバー上のGit - プロトコル

この時点で、Gitを使うほとんどの日常的な作業ができるようになっているはずです。しかし、Gitで共同作業を行うには、リモートのGitリポジトリが必要になります。技術的には個々のリポジトリにプッシュしたりプルしたりできますが、注意しないと彼らが作業している内容をかなり簡単に混乱させてしまう可能性があるため、これは推奨されません。さらに、コラボレーターはあなたのコンピューターがオフラインであってもリポジトリにアクセスできる必要があります。より信頼性の高い共通のリポジトリがある方が便利です。したがって、誰かと共同作業を行うための推奨される方法は、両方がアクセスできる中間リポジトリを設定し、そこからプッシュしたりプルしたりすることです。

Gitサーバーの実行はかなり簡単です。まず、サーバーがサポートするプロトコルを選択します。この章の最初のセクションでは、利用可能なプロトコルとそれぞれの長所と短所について説明します。次のセクションでは、これらのプロトコルを使用した一般的なセットアップと、それらを使ってサーバーを実行する方法について説明します。最後に、誰かのサーバーにコードをホストすることに抵抗がなく、独自のサーバーを設定して維持する手間をかけたくない場合の、いくつかのホスト型オプションについて説明します。

独自のサーバーを実行するのに興味がない場合は、章の最後のセクションにスキップしてホスト型アカウントを設定するためのいくつかのオプションを確認し、次の章に進んで、分散型ソース管理環境での作業のさまざまな詳細について説明します。

リモートリポジトリは通常、_ベアリポジトリ_です。つまり、作業ディレクトリを持たないGitリポジトリです。リポジトリは共同作業のポイントとしてのみ使用されるため、ディスク上にスナップショットをチェックアウトしておく必要はありません。Gitデータだけです。最も単純な言葉で言えば、ベアリポジトリとは、プロジェクトの.gitディレクトリの中身だけであり、それ以外の何ものでもありません。

プロトコル

Gitはデータを転送するために、ローカル、HTTP、Secure Shell (SSH)、Gitの4つの異なるプロトコルを使用できます。ここでは、それらが何であるか、そしてどのような基本的な状況でそれらを使用したい(または使用したくない)かについて説明します。

ローカルプロトコル

最も基本的なのは_ローカルプロトコル_です。このプロトコルでは、リモートリポジトリが同じホスト上の別のディレクトリに存在します。これは、チームの全員がNFSマウントなどの共有ファイルシステムにアクセスできる場合、または全員が同じコンピューターにログインするという可能性の低いケースでよく使用されます。後者は理想的ではありません。なぜなら、すべてのコードリポジトリインスタンスが同じコンピューターに存在し、壊滅的な損失がはるかに起こりやすくなるからです。

共有マウントファイルシステムがある場合、ローカルのファイルベースのリポジトリからクローンを作成したり、プッシュしたり、プルしたりできます。このようなリポジトリをクローンする場合、または既存のプロジェクトにリモートとして追加する場合、リポジトリへのパスをURLとして使用します。たとえば、ローカルリポジトリをクローンするには、次のように実行できます。

$ git clone /srv/git/project.git

または、次のようにすることもできます。

$ git clone file:///srv/git/project.git

URLの先頭に明示的にfile://を指定すると、Gitはわずかに異なる動作をします。パスだけを指定すると、Gitはハードリンクを使用するか、必要なファイルを直接コピーしようとします。file://を指定すると、Gitは通常ネットワーク経由でデータを転送するために使用するプロセスを起動しますが、これは通常はるかに効率が悪くなります。file://プレフィックスを指定する主な理由は、余分な参照やオブジェクトを除外したリポジトリのクリーンなコピーが必要な場合です。これは通常、別のVCSからのインポートなど(メンテナンス作業についてはGitの内部を参照)の後に行われます。ここでは、ほとんどの場合それが速いため、通常のパスを使用します。

既存のGitプロジェクトにローカルリポジトリを追加するには、次のように実行できます。

$ git remote add local_proj /srv/git/project.git

その後、新しいリモート名local_projを介して、ネットワーク経由で行うかのように、そのリモートにプッシュしたりプルしたりできます。

メリット

ファイルベースのリポジトリの利点は、シンプルで、既存のファイル権限とネットワークアクセスを使用することです。チーム全体がアクセスできる共有ファイルシステムがすでにある場合、リポジトリのセットアップは非常に簡単です。ベアリポジトリのコピーを全員が共有アクセスできる場所に置き、他の共有ディレクトリと同様に読み取り/書き込み権限を設定します。この目的のためのベアリポジトリのコピーのエクスポート方法については、サーバーにGitをセットアップするで説明します。

これは、他の人の作業リポジトリから作業を素早く取得するのにも良い選択肢です。あなたと同僚が同じプロジェクトで作業しており、彼らが何かをチェックしてほしい場合、git pull /home/john/projectのようなコマンドを実行する方が、彼らがリモートサーバーにプッシュしてあなたがそこからフェッチするよりも簡単なことがよくあります。

デメリット

この方法のデメリットは、共有アクセスは、基本的なネットワークアクセスよりも、一般的に複数の場所からの設定や到達が難しいということです。自宅にいるときにラップトップからプッシュしたい場合、リモートディスクをマウントする必要があり、これはネットワークベースのアクセスに比べて困難で遅い場合があります。

何らかの共有マウントを使用している場合、これは必ずしも最速のオプションではないことに注意することが重要です。ローカルリポジトリが高速であるのは、データへの高速アクセスがある場合のみです。NFS上のリポジトリは、同じサーバー上のSSH経由のリポジトリよりも遅いことが多く、Gitは各システムのローカルディスクから実行されます。

最後に、このプロトコルは偶発的な損傷からリポジトリを保護しません。すべてのユーザーは「リモート」ディレクトリへの完全なシェルアクセス権を持ち、内部のGitファイルを変更したり削除したりしてリポジトリを破損させることを防ぐものは何もありません。

HTTPプロトコル

Gitは、2つの異なるモードを使用してHTTP経由で通信できます。Git 1.6.6以前は、非常にシンプルで一般的に読み取り専用の1つの方法しかありませんでした。バージョン1.6.6で、SSH経由で行うのと同様の方法でGitがデータをインテリジェントにネゴシエートできる、新しい、よりスマートなプロトコルが導入されました。この数年間で、この新しいHTTPプロトコルは、ユーザーにとってよりシンプルで、通信方法がよりスマートであるため、非常に人気が高まっています。新しいバージョンはしばしば_Smart_ HTTPプロトコルと呼ばれ、古い方法は_Dumb_ HTTPと呼ばれます。最初に新しいSmart HTTPプロトコルについて説明します。

スマートHTTP

Smart HTTPはSSHまたはGitプロトコルと非常によく似た動作をしますが、標準のHTTPSポート上で実行され、様々なHTTP認証メカニズムを使用できます。つまり、SSHキーを設定する必要があるSSHのようなものよりも、ユーザー名/パスワード認証などを使用できるため、ユーザーにとってより簡単であることがよくあります。

現在では、git://プロトコルのように匿名でサービスを提供することもでき、SSHプロトコルのように認証と暗号化を伴うプッシュも可能になったため、Gitを使用する最も人気のある方法になっているかもしれません。これらのために異なるURLを設定する必要がなくなり、両方に1つのURLを使用できるようになりました。プッシュしようとしてリポジトリが認証を要求する場合(通常はそうであるべきです)、サーバーはユーザー名とパスワードを要求できます。読み取りアクセスも同様です。

実際、GitHubのようなサービスでは、オンラインでリポジトリを表示するために使用するURL(例:https://github.com/schacon/simplegit)は、クローンを作成し、アクセス権があればプッシュするためにも使用できる同じURLです。

ダンプHTTP

サーバーがGit HTTPスマートサービスで応答しない場合、Gitクライアントはよりシンプルな_Dumb_ HTTPプロトコルにフォールバックしようとします。Dumbプロトコルは、ベアGitリポジトリがWebサーバーから通常のファイルとして提供されることを期待します。Dumb HTTPの利点は、セットアップのシンプルさにあります。基本的に、必要なのは、ベアGitリポジトリをHTTPドキュメントルートの下に置き、特定のpost-updateフックを設定するだけです(Gitフックを参照)。その時点で、リポジトリを置いたWebサーバーにアクセスできる人なら誰でも、リポジトリをクローンできます。HTTP経由でリポジトリへの読み取りアクセスを許可するには、次のようにします。

$ cd /var/www/htdocs/
$ git clone --bare /path/to/git_project gitproject.git
$ cd gitproject.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update

以上です。Gitにデフォルトで付属しているpost-updateフックは、HTTPでのフェッチとクローンが適切に機能するために適切なコマンド(git update-server-info)を実行します。このコマンドは、このリポジトリにプッシュする(おそらくSSH経由で)ときに実行されます。その後、他の人は次のようにクローンできます。

$ git clone https://example.com/gitproject.git

この特定のケースでは、Apacheのセットアップで一般的な/var/www/htdocsパスを使用していますが、任意の静的Webサーバーを使用できます。ベアリポジトリをそのパスに置くだけです。Gitデータは基本的な静的ファイルとして提供されます(どのように提供されるかの詳細はGitの内部の章を参照してください)。

通常、読み書き可能なSmart HTTPサーバーを実行するか、ファイルをDumbな方法で読み取り専用としてアクセス可能にするかのどちらかを選択します。両方のサービスを混在させることは稀です。

メリット

HTTPプロトコルのスマートバージョンの利点に焦点を当てて説明します。

すべての種類のアクセスに対して単一のURLを持ち、認証が必要な場合にのみサーバーがプロンプトを表示するというシンプルさは、エンドユーザーにとって非常に簡単です。ユーザー名とパスワードで認証できることもSSHに対する大きな利点です。ユーザーはSSHキーをローカルで生成し、サーバーに公開鍵をアップロードしてからやり取りする必要がないからです。あまり洗練されていないユーザーや、SSHが一般的でないシステムを使用しているユーザーにとっては、これは使いやすさの大きな利点です。また、SSHと同様に、非常に高速で効率的なプロトコルです。

HTTPS経由でリポジトリを読み取り専用で提供することもできます。これにより、コンテンツ転送を暗号化したり、クライアントに特定の署名付きSSL証明書を使用させたりすることも可能です。

もう一つの良い点は、HTTPとHTTPSが非常に一般的に使用されるプロトコルであるため、企業のファイアウォールがそれらのポートを通過するトラフィックを許可するように設定されていることが多いことです。

デメリット

HTTPS経由のGitは、一部のサーバーではSSHに比べて設定が少し複雑になる場合があります。それ以外は、Gitコンテンツを提供するために他のプロトコルがSmart HTTPよりも優れている点はほとんどありません。

認証付きプッシュにHTTPを使用する場合、資格情報の提供はSSH経由でキーを使用するよりも複雑になることがあります。ただし、macOSのキーチェーンアクセスやWindowsのCredential Managerなど、いくつかの資格情報キャッシュツールを使用することで、これをかなり簡単に行うことができます。システム上で安全なHTTPパスワードキャッシュを設定する方法については、資格情報ストレージを参照してください。

SSHプロトコル

Gitをセルフホスティングする場合の一般的な転送プロトコルはSSHです。これは、ほとんどの場所でSSHサーバーへのアクセスがすでに設定されており、設定されていない場合でも簡単に行えるためです。SSHは認証されたネットワークプロトコルでもあり、ユビキタスであるため、一般的にセットアップと使用が簡単です。

SSH経由でGitリポジトリをクローンするには、次のようにssh:// URLを指定できます。

$ git clone ssh://[user@]server/project.git

または、SSHプロトコルのより短いscpのような構文を使用することもできます。

$ git clone [user@]server:project.git

上記のどちらの場合も、オプションのユーザー名を指定しない場合、Gitは現在ログインしているユーザーを仮定します。

メリット

SSHを使用する利点は多数あります。まず、SSHは比較的簡単にセットアップできます。SSHデーモンは一般的であり、多くのネットワーク管理者はそれらの経験があり、多くのOSディストリビューションはそれらが設定されているか、それらを管理するためのツールを持っています。次に、SSH経由のアクセスは安全です。すべてのデータ転送は暗号化され、認証されます。最後に、HTTPS、Git、およびローカルプロトコルと同様に、SSHは効率的であり、データを転送する前に可能な限りコンパクトにします。

デメリット

SSHのデメリットは、Gitリポジトリへの匿名アクセスをサポートしていないことです。SSHを使用している場合、人々は読み取り専用の場合でもあなたのマシンへのSSHアクセスを_持っている必要があり_、これは、人々が単にリポジトリをクローンして調べたいだけのオープンソースプロジェクトにはSSHが適していません。企業ネットワーク内でのみ使用している場合、SSHが扱う必要のある唯一のプロトコルかもしれません。プロジェクトへの匿名読み取り専用アクセスを許可し、SSHも使用したい場合は、プッシュ用にはSSHを設定する必要がありますが、他の人がフェッチできるようにするには別のものを設定する必要があります。

Gitプロトコル

最後に、Gitプロトコルがあります。これはGitに同梱されている特別なデーモンで、専用ポート(9418)でリッスンし、SSHプロトコルに似たサービスを提供しますが、認証や暗号化は一切ありません。Gitプロトコル経由でリポジトリを提供するには、git-daemon-export-okファイルを作成する必要があります(このファイルがないとデーモンはリポジトリを提供しません)が、それ以外にセキュリティはありません。Gitリポジトリは誰でもクローンできるか、そうでないかのどちらかです。これは通常、このプロトコル経由でのプッシュはできないことを意味します。プッシュアクセスを有効にすることはできますが、認証がないため、インターネット上でプロジェクトのURLを見つけた人なら誰でもそのプロジェクトにプッシュできてしまいます。言うまでもなく、これは稀なことです。

メリット

Gitプロトコルは、利用可能なネットワーク転送プロトコルの中で最も高速であることがよくあります。公開プロジェクトのために大量のトラフィックを処理する場合、または読み取りアクセスにユーザー認証を必要としない非常に大規模なプロジェクトを処理する場合、Gitデーモンを設定してプロジェクトを提供したいと思うでしょう。これはSSHプロトコルと同じデータ転送メカニズムを使用しますが、暗号化と認証のオーバーヘッドがありません。

デメリット

TLSやその他の暗号化がないため、git://経由のクローンは任意のコード実行の脆弱性につながる可能性があり、何をしているかを理解している場合を除き避けるべきです。

  • git clone git://example.com/project.gitを実行すると、例えばルーターを制御する攻撃者がクローンしたリポジトリを改ざんし、悪意のあるコードを挿入する可能性があります。その後、クローンしたコードをコンパイル/実行すると、悪意のあるコードが実行されます。同じ理由でgit clone http://example.com/project.gitも避けるべきです。

  • git clone https://example.com/project.gitを実行しても、同じ問題は発生しません(攻撃者がexample.comのTLS証明書を提供できない限り)。git clone git@example.com:project.gitを実行しても、間違ったSSHキーのフィンガープリントを受け入れない限り、この問題は発生しません。

また、認証もありません。つまり、誰でもリポジトリをクローンできます(これはまさに望ましいことである場合が多いですが)。また、おそらく最も設定が難しいプロトコルでもあります。独自のデーモンを実行する必要があり、xinetdsystemdの設定などが必要になりますが、これは常に簡単なことではありません。また、企業のファイアウォールが常に許可する標準ポートではないポート9418へのファイアウォールアクセスも必要です。大規模な企業ファイアウォールの背後では、この不明なポートは一般的にブロックされています。

scroll-to-top