web-dev-qa-db-ja.com

gitをssh経由でトンネリング(ファイアウォールを通過するため):ポート仕様は相対パスとして解釈されますか?

Ssh経由でサーバーAにアクセスでき、サーバーAからサーバーBにアクセスできます。サーバーBには、gitlabsを実行し、アクセスする必要のあるリポジトリが含まれています。サーバーAにSSH接続すると、git clone http://serverB/path/to/repo.gitを正常に実行できます。 ssh://の代わりにgit://またはhttp://を使用しても機能しません。 (エラーはそれぞれ「gitリポジトリではないようです」と「serverBに接続できません」です。)

このようなトンネルを設定した場合:

ssh username@serverA -L 3333:serverB:80 -N

Gitクローンでの次の2つの試行は失敗します。

git clone http://localhost:3333/path/to/repo.git

失敗:「致命的:リポジトリが見つかりません」

git clone localhost:3333/path/to/repo.git

ServerBのパスワードの入力を求められた後、「致命的:3333/path/to/repo.gitはgitリポジトリではないようです」と失敗します。もちろんそうではありません!ローカルホスト、ポート3333を指定しようとした私の試みは、明らかにserverBの相対パスとして解釈されています。

これを修正する方法はありますか?このアプローチには根本的に何か問題がありますか?

6
Kristin

なぜ動かないのか

http://localhost:3333/path/to/repo.git

これは、URLのホスト名が異なるため(localhostserver2)、サーバーが異なる構成を使用するために失敗します。

すべてのHTTPクライアントは要求されたホスト名をサーバーに送信し、サーバーはその名前に基づいていくつかの構成(仮想ホスト)から選択できます。これは、ホスティングプロバイダーで同じIPアドレスを共有できるWebサイトの数(多くの場合、数百)です。

localhost:3333/path/to/repo.git

これは、HTTP URLではないではないため、実際にはすべてのURLであるため、失敗します。 (GitはWebブラウザーではなく、デフォルトでhttp://を想定していません。)

代わりに、[user@]Host:pathの形式のrcpスタイルのSSHアドレスです。以前は[email protected]:foo/bar.gitとして見たことがあるかもしれませんが、ssh@プレフィックスは実際には単なるSSHユーザー名です。

Gitは、rcpスタイルのアドレスにポートフィールドがまったくないことを除いて、それをssh://[user@]Host[:port]/pathURLと同等に扱います。

何をすべきか

gitが使用するHTTPクライアントであるcurlは、ssh -D動的トンネルによって提供されるSOCKSプロキシをサポートします。

  1. 次のコマンドで動的(SOCKS)トンネルを設定します。

    ssh username@serverA -D 1080 -N
    
  2. プロキシとして使用するようにGitを構成します。

    グローバルに(またはリポジトリごとに):

    git config [--global] http.proxy socks5://localhost:1080
    

    単一のコマンドの場合:

    git -c http.proxy=socks5://localhost:1080 clone http://serverB/repo.git
    

socks5およびsocks4プロトコルはクライアント側でDNS解決を実行し、socks5hおよびsocks4aはすべてのホスト名をSOCKSを介してSSHサーバーに渡します。

7
user1686