使用する秘密鍵をgitに伝える方法は?


646

ssh-i認証時に使用する秘密鍵ファイルを指示するオプションがあります。

-i identity_file

    RSAまたはDSA認証のID(秘密鍵)が読み取られるファイルを選択します。デフォルトは~/.ssh/identity、プロトコルバージョン1のために、と~/.ssh/id_rsa~/.ssh/id_dsaプロトコルバージョン2.アイデンティティファイルは、コンフィギュレーションファイルによって、ホストごとに指定することができます。複数の-iオプション(および構成ファイルで指定された複数のID)を持つことができます。

ディレクトリにgit複数の秘密鍵があるシステムで使用する秘密鍵ファイルを特定する同様の方法はあります~/.sshか?


3
StackOverflowのこの質問も参照してください。
フリム

回答:


671

では~/.ssh/config、追加します。

host github.com
 HostName github.com
 IdentityFile ~/.ssh/id_rsa_github
 User git

これでできますgit clone git@github.com:username/repo.git

注:IdentityFileのアクセス許可が400であることを確認してください。SSHは、明確に明示されていない方法で、読み取り可能なSSHキーを拒否します。クレデンシャルの拒否のように見えます。この場合の解決策は次のとおりです。

chmod 400 ~/.ssh/id_rsa_github

117
異なるキーで同じホストに接続する必要がある場合はどうなりますか?
バレンティンクリンハンマー

6
@Quelltextfabrik -あなたは別のホストに別のセクションを追加することができます:nerderati.com/2011/03/...
ベンChallenor

1
私のマンページの@Cliff Nop: " HostName:ログインする実際のホスト名を指定します。これは、ホストのニックネームまたは略語を指定するために使用できます。" 私のsshバージョンはopenssh-6.7p1です。
グリッショム

11
構成ファイルが新しい場合は、忘れないでくださいchmod 600 ~/.ssh/config
-elysch

2
@ValentinKlinghammer @Flimmからの回答には、この質問に対する解決策があります。core.sshCommandgit構成を使用することです。superuser.com/a/912281/162466
VasyaNovikov

345

環境変数GIT_SSH_COMMAND

Gitバージョン2.3.0から、次のGIT_SSH_COMMANDような環境変数を使用できます。

GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example" git clone example

-i設定ファイルで上書きされる場合があることに注意してください。この場合、次のように、SSHに空の設定ファイルを指定する必要があります。

GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example -F /dev/null" git clone example

構成core.sshCommand

Gitバージョン2.10.0から、これをリポジトリごとまたはグローバルに構成できるため、環境変数を設定する必要がなくなりました!

git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -F /dev/null"
git pull
git push

1
この作業を行うには、シェル変数を環境変数にエクスポートする必要がありました。つまりexport GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example"git clone example
Abdull

7
@Abdull Bashでは、コマンドと同じ行で割り当てを行うと、そのコマンドだけの環境変数がエクスポートされます。それを試してください:example=hello /usr/bin/env | grep example
フリム

3
物事はさらに良くなりました:Git 2.10の時点で、Git構成にコマンドを保存できます:stackoverflow.com/a/38474220/520162
eckes

2
@Noitidart /dev/nullはUNIXライクなオペレーティングシステムでのみ有効なファイル名であり、Windowsでは機能しません。
Flimm

2
次のコマンドのように、GIT_SSH_COMMAND私が使用するまで動作しませんでした。IdentitiesOnlyGIT_SSH_COMMAND="ssh -i ~/.ssh/mysubdir/id_rsa -o 'IdentitiesOnly yes'" git push
タイラーコリアー

111

リポジトリ認証に依存しているため、使用する秘密鍵を直接伝える方法はありません。ただし、目標を達成する方法はまだいくつかあります。gitssh

オプション1: ssh-agent

を使用ssh-agentして、秘密鍵を一時的に認証できます。

例えば:

$ ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; git fetch user@host'

オプション2: GIT_SSH_COMMAND

GIT_SSH_COMMAND環境変数(Git 2.3.0以降)を使用してssh引数を渡します。

例えば:

$ GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \
  git clone user@host

これをすべて1行で入力できます。無視して$、を省略します\

オプション3: GIT_SSH

GIT_SSH環境変数を使用してssh引数を渡し、代替sshバイナリを指定します。

例えば:

$ echo 'ssh -i ~/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $*' > ssh
$ chmod +x ssh
$ GIT_TRACE=1 GIT_SSH='./ssh' git clone user@host

注:上記の行は、シェル(端末)コマンド行であり、端末に貼り付ける必要があります。という名前のファイルを作成し、ssh実行可能にし、(間接的に)実行します。

注:GIT_SSHv0.99.4(2005)以降で使用可能です

オプション4: ~/.ssh/config

~/.ssh/config他の回答で提案されているようにファイルを使用して、秘密鍵の場所を指定します。たとえば、

Host github.com
  User git
  Hostname github.com
  IdentityFile ~/.ssh/id_rsa

1
//、この質問のように、ssh-agentのIDが転送された場合はどうなりますか?superuser.com/questions/971732/...
ネイサンBasanese

1
この投稿を再フォーマットすることを許可しました:IMOこれは、最も包括的な答えです。元の設計では、クイックスキャンで問題に対する単一の複雑な解決策を説明する投稿が提案されたため、私はそれを逃しました。
アルベルト

3
$ ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; git fetch user@host'他に何もしないときに私のために働いた。称賛。
ダニエルデューハースト

1
私が使用していた~/.ssh/config、方法をENV ...私のために動作しませんでしたvarsの
グレッグDubicki

1
GIT_SSHv0.99.4(2005年8月)以降、基本的にGitが存在するため(2005年4月)から利用可能です。
ドミニク

32

ssh必要な引数を使用して呼び出すスクリプトを作成し、スクリプトのファイル名をに入れます$GIT_SSH。または、単に設定をに入れます~/.ssh/config


2
これを行う方法の別の説明
シスー

1
~/.ssh/configで移動するための方法。
hek2mgl

マシン(A)で作業し、そこからsshキー認証のみを受け入れるサーバー(G)にgit pushします。(A)での〜/ .ssh / configのセットアップはそのマシンで直接作業する場合は完全に正常に機能しますが、他の場所からログインする場合は機能しません(C)。$GIT_SSHスクリプトを使用してこの問題を解決しました。ありがとう!
bsumirak

18

gitを実行するたびに環境変数を指定する必要がない場合、別のラッパースクリプトが必要ない、ssh-agent(1)を実行しない/できない、またはこのためだけに別のパッケージをダウンロードしたくない場合は、gitを使用します-remote-ext(1)外部トランスポート:

$ git clone 'ext::ssh -i $HOME/.ssh/alternate_id git.example.com %S /path/to/repository.git'
Cloning into 'repository'
(...)
$ cd repository
$ git remote -v
origin  ext::ssh -i $HOME/.ssh/alternate_id git.example.com %S /path/to/repository.git (fetch)
origin  ext::ssh -i $HOME/.ssh/alternate_id git.example.com %S /path/to/repository.git (push)

私はこのソリューションが優れていると考えています:

  • リポジトリ/リモート固有です
  • ラッパースクリプトの肥大化を回避
  • SSHエージェントは必要ありません-無人クローン/プッシュ/プル(cronなど)が必要な場合に便利です
  • 間違いなく、外部ツールは必要ありません

2
この答えは、私がChefのgitリソースにリポジトリ固有のデプロイメントキーを使用してGithubプライベートリポジトリからクローン/フェッチするように強制するために必要なものでした。環境/スクリプトベースの方法に対するこの方法の追加の利点は、キーパスがworking-repoの構成でエンコードされるため、最初のクローンと後続のフェッチ/プッシュの両方で同じキーを使用することです。
アダムフランコ

2
うわー!これは素晴らしいことで、これについては知りませんでした。回答をありがとう、人形の環境でも非常に役立ち、管理するのに余分な手間がかかるのを防ぎます.ssh/config。+ 1!
gf_

1
このソリューションは、--recursiveフラグと一緒には機能しません。サブモジュールは指定されたキーを使用してフェッチされないため、認証が必要な場合は失敗します。
ダニエレテスタ

1
各サブモジュールは、独自のリモートセットを備えた完全に異なるリポジトリです。あなたの便宜のためにそれらはGitによって接着されていますが、サブモジュールのリモートが親リポジトリのリモートに結び付けられることはありません。親での再帰が機能するためにextは、サブモジュールでトランスポートを使用してリモートを設定する必要があると思います。
フラビオフ16

2
次のエラーが発生fatal: transport 'ext' not allowedした場合は、を介してextプロトコルをホワイトリストに登録する必要がありexport GIT_ALLOW_PROTOCOL=extます。基本的に、git-remote-extリモートヘルパー( "ext :: ssh example.com%S foo / repo" URLをサポート)は、任意のコマンドの実行を許可します。これは通常、ユーザーがgitに渡すURLを常に表示および信頼するため、心配する必要はありません。ただし、gitサブモジュールでは、.gitmodulesファイルを使用して、攻撃者がクライアントに任意のgit URLをフェッチするよう要求することができます。hackerone.com/reports/104465
Gomino

18

次の~/.ssh/configように、でカスタムホスト構成を使用します。

Host gitlab-as-thuc  
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa.thuc
    IdentitiesOnly yes

次に、次のようなカスタムホスト名を使用します。

git remote add thuc git@gitlab-as-thuc:your-repo.git  

2
これは、自宅と職場に別々のGitHubアカウントを持っているので、私が探していた答えです。単に設定しHost work.github.com HostName github.com IdentityFile ~/.ssh/work、作業リポジトリを複製するたびに「github.com」を「work.github.com」に置き換えるだけでした。まだ「github.com」に接続していますが、デフォルト以外のキーペアを使用しています。
ミッケル

1
詳細のURL( " itblog.study.land / ...")はもう機能しません:(
Carl Smotricz

オリジナルのものはここに移動しました@CarlSmotricz:medium.com/@thucnc/...を
thucnguyen

4
最後に!!!この答えは、実際に~/.ssh/configファイルに入れたものをどのように利用できるかを示しています。他のすべての答えは、オリジンを追加するときにホストを設定する方法を逃します。これにより、gitは自動的に正しいキーファイルを使用できます。ありがとうございました!!
BrianVPS

1
ニース、それは私が探していたものでした:)
ルーカス・ダビラ

15

私との闘争の後、私のために$GIT_SSH働いたものを共有したいと思います。

私の例を通して、私はあなたがあなたの秘密鍵を持っていると仮定します/home/user/.ssh/jenkins

避けるべきエラー:GIT_SSH値にはオプションが含まれます

$ export GIT_SSH="ssh -i /home/user/.ssh/jenkins"

またはgitは値をfileとして実行しようとするため、同様のものは失敗します。そのため、スクリプトを作成する必要があります。

$ GIT_SSHスクリプトの動作例 /home/user/gssh.sh

スクリプトは次のように呼び出されます。

$ $GIT_SSH [username@]host [-p <port>] <command>

サンプルスクリプトの動作は次のようになります。

#!/bin/sh
ssh -i /home/user/.ssh/jenkins $*

$*最後に注意してください、それはそれの重要な部分です。

デフォルトの設定ファイル内のあらゆるものとの競合を防ぐ(さらに使用するポートを明示的に指定する)より安全な代替手段は次のとおりです。

#!/bin/sh
ssh -i /home/user/.ssh/jenkins -F /dev/null -p 22 $*

スクリプトがにあると仮定すると/home/user/gssh.sh、次のようになります。

$ export GIT_SSH=/home/user/gssh.sh

そして、すべてが機能します。


ありがとう。注:パススルー引数には$ *ではなく "$ @"を使用してください。前者は引数に空白が含まれている場合に正しく動作するためです。
ピョートル・フィンデイセン

@PiotrFindeisenご清聴ありがとうございました。しかし、私はそれを完全には理解していません-zshでは、スペースのある文字列を1つのピースに保持できますが、bashではできません。もっと教えてもらえますか?盲目的に変更を加えたくありません。
ヤンヴルチンスキー

答えの前半を削除する必要があります。機能しないソリューションには誰も興味がありません。また、下部の正しい答えを難読化することは無駄に読みますが、これは見事に機能します。
セリン

@Cerin「回避するエラー」を削除するつもりなら、そのままにしておきます。それは避けるべき共通の落とし穴を共有し、非常に短いです。誰かがすべてのものを変数に提供することでソリューションを最適化しようとすると確信しています(これは私に起こりました)ので、成功への道を短くしようとしました。
ヤンヴルチンスキー

5

独自のラッパーを作成する代わりに、ssh-identを使用できます。

詳しくは、https//github.com/ccontavalli/ssh-identをご覧ください。

複数のログインセッション、xterm、またはNFS共有ホームであっても、最初に必要なときにオンデマンドでsshキーを読み込みます。

小さな設定ファイルを使用すると、さまざまなキーを自動的にロードし、必要な内容に応じて(エージェント転送用の)異なるエージェントにそれらを分離した状態に保つことができます。


5

別のgithubアカウントを必要とするクライアントがありました。そのため、この1つのプロジェクトだけに別のキーを使用する必要がありました。

私の解決策は、これを私の.zshrc / .bashrcに追加することでした:

alias infogit="GIT_SSH_COMMAND=\"ssh -i ~/.ssh/id_specialkey\" git $@"

そのプロジェクトにgitを使用したいときはいつでも、「infogit」をgitに置き換えます。

infogit commit -am "Some message" && infogit push

私にとっては、覚えやすいです。


4

そこで、GIT_SSH env変数をに設定し$HOME/bin/git-sshます。

リポジトリ設定で使用するssh IDを指定できるようにするため、私の~/bin/git-sshファイルは次のとおりです。

#!/bin/sh
ssh -i $(git config --get ssh.identity) -F /dev/null -p 22 $*

次に、グローバルなgit config設定があります:

$ git config --global ssh.identity ~/.ssh/default_id_rsa

また、任意のgitリポジトリ内で、ローカルssh.identitygit構成値を設定するだけです。

$ git config --local ssh.identity ~/.ssh/any_other_id_rsa

出来上がり!

各IDに異なる電子メールアドレスを使用できる場合は、電子メールアドレスに基づいてキーに名前を付け、git configのuser.emailで次の~/bin/git-sshようにキーを選択できるため、さらに簡単になります。

#!/bin/sh
ssh -i $HOME/.ssh/$(git config --get user.email) -F /dev/null -p 22 $*

2

私の解決策はこれでした:

スクリプトを作成します。

#!/bin/bash
KEY=dafault_key_to_be_used
PORT=10022 #default port...
for i in $@;do
   case $i in
    --port=*)
        PORT="${i:7}";;
    --key=*)KEY="${i:6}";;
   esac
done
export GIT_SSH_COMMAND="ssh -i $HOME/.ssh/${KEY} -p ${PORT}"
echo Command: $GIT_SSH_COMMAND

その後、var runを変更する必要がある場合:

. ./thescript.sh [--port=] [--key=]

余分なドットを忘れないでください!! これにより、スクリプトは環境変数を設定します!! --keyおよび--portはオプションです。


2

通常、~/.ssh/configこれに使用する必要があります。次のように、サーバーアドレスと使用するキーを単純にペアにします。

Host github.com
  IdentityFile ~/.ssh/id_rsa.github
Host heroku.com
  IdentityFile ~/.ssh/id_rsa.heroku
Host *
  IdentityFile ~/.ssh/id_rsa

Host *は任意のサーバーを示すため、使用~/.ssh/id_rsaするデフォルトのキーとして設定するために使用します。


2

@shellholic とこのSOスレッドにいくつかのチークを追加して作成します。GitHubを例として使用し、プライベートキーを持っている~/.ssh/github(そうでない場合は、このSOスレッドを参照)ことと、パブリックキーをGitHubプロファイルに追加したと仮定します(そうでない場合は、GitHubのヘルプを参照しください)。

必要に応じて、新しいSSH構成ファイルを作成し、~/.ssh/configアクセス許可を400に変更します

touch ~/.ssh/config
chmod 600 ~/.ssh/config

これを~/.ssh/configファイルに追加します。

Host github.com
    IdentityFile ~/.ssh/github
    IdentitiesOnly yes

すでにリモートが設定されている場合、それを削除したい場合があります。そうしないと、ユーザー名とパスワードの入力を求められる場合があります。

git remote rm origin

次に、リモートをgitリポジトリに追加し、ユーザー名の前のコロンに注意してください。

git remote add origin git@github.com:user_name/repo_name.git

そして、gitコマンドは正常に動作します。例:

git push origin master
git pull origin 

このSOスレッドの @HeyWatchThisはIdentitiesOnly yes、各プロトコルのデフォルトのファイル名に一致するIDファイルを送信するSSHのデフォルトの動作を防ぐために追加することを提案しました。詳細および参照については、そのスレッドを参照してください。


これは私の間違いでした:「すでにリモート設定をしている場合...」。どうもありがとう!!!
アランアンドラーデ

よくある間違い---これが答えです
ゴダード

1

ssh-agentssh-addコマンドを使用するだけです。

# create an agent
ssh-agent

# add your default key
ssh-add ~/.ssh/id_rsa

# add your second key
ssh-add ~/.ssh/<your key name>

上記のコマンドを実行した後、両方のキーを同時に使用できます。入力するだけ

git clone git@github.com:<yourname>/<your-repo>.git

リポジトリを複製します。

マシンを再起動した後、上記のコマンドを実行する必要があります。


エージェントを作成する方法を含むプロセスを説明してください
Srikrushna

0

私はgitバージョン2.16を使用していますが、構成や変更されたコマンドでさえ、1つのスクリプトを必要としません。

  • 私の秘密鍵を.ssh / id_rsaにコピーしました
  • 権限を600に設定します

そして、gitは自動的にキーを読み取ります。私は何も尋ねず、エラーもスローしません。正常に動作します。


質問は「~/.sshディレクトリに複数の秘密鍵があるシステム」に関するものであることに気付きましたか?
スコット

0

質問はそれを要求していませんが、特にだけで同じ問題を解決しようとしている他の人のために、この回答を含めています。

gitlabソリューション

アプローチを使用しようとしましたが、gitのドキュメントでさえ~/.ssh/config、単純なケース以外の使用を推奨しています。私の場合、私はサーバーにプッシュしてます-そして、特定のユーザーとしてプッシュしたかったのです-もちろん、ユーザー名ではなく中にによって定義されます。実装したら、次を実行するだけです。git

~/myrepo> git mycommit -m "Important Stuff"
~/myrepo> git mypush
[proceed to enter passphrase for private key...]

セットアップ

私の場合、 場所を思い出してください/myfolder/.ssh/my_gitlab_id_rsa

にエントリを追加し~/.ssh/configます。

Host gitlab-delegate
    HostName gitlab.mydomain.com
    User git
    IdentityFile /myfolder/.ssh/my_gitlab_id_rsa
    IdentitiesOnly yes

を追加し~/.gitconfigます:

mypush = "!f() { \
           path=$(git config --get remote.origin.url | cut -d':' -f2); \
           branch=$(git rev-parse --abbrev-ref HEAD); \
           git remote add gitlab_as_me git@gitlab-delegate:$path && \
           git push gitlab_as_me $branch && \
           git pull origin $branch; \
           git remote remove gitlab_as_me; \
         }; f"

ボーナスとして、この使用て、特定のユーザー同じホストでコミット実行します

mycommit = "!f() { \
             git -c "user.name=myname" -c "user.email=myname@mysite.com" commit \"$@\"; \
           }; f"

説明

上記のすべては、関連するリモートがoriginあり、関連するブランチが現在チェックアウトされていることを前提としています。参考のために、対処する必要があるいくつかの項目に遭遇しました。

  • ソリューションには新しいリモートを作成する必要があり、ログツリーにgitlab_as_me余分なリモートがぶら下がっているのが気に入らなかったので、終了したら削除します
  • リモートを作成するには、その場でリモートのURLを生成する必要があります-gitlabの場合、これは単純なbash 実現
  • プッシュを実行するときは、プッシュするgitlab_as_meブランチを明確にする必要があります
  • プッシュを実行した後、origin一致させるためにローカルポインターを「更新」する必要がありますgitlab_as_megit pull origin $branchこれを行う)

0

複数のgitアカウントがあり、異なるsshキーが必要な場合

sshキーを生成するには同じ手順に従う必要がありますが、

ssh-keygen -t ed25519 -C "your-email-id@gmail.com" 

保存するパスを入力します(例:my-pc / Desktop / .ssh / ed25519)

gitlabに公開キーを追加します(gitlabにsshキーを追加する方法

以下のコマンドを使用して新しいssh IDを作成する必要があります

ssh-add ~/my-pc/Desktop/.ssh/ed25519

(1)誰かまたは何かを引用していますか?その場合は、ソースを特定してください。そうでない場合は、引用形式を使用しないでください。(2)「ed25519」とは何ですか?……………………………コメントで返信しないでください。 回答を編集して、より明確で完全なものにします。
スコット

0
    # start :: how-to use different ssh identity files

    # create the company identity file
    ssh-keygen -t rsa -b 4096 -C "first.last@corp.com"
    # save private key to ~/.ssh/id_rsa.corp, 
    cat ~/.ssh/id_rsa.corp.pub # copy paste this string into your corp web ui security ssh keys

    # create your private identify file
    ssh-keygen -t rsa -b 4096 -C "me@gmail.com"
    # save private key to ~/.ssh/id_rsa.me, note the public key ~/.ssh/id_rsa.me.pub
    cat ~/.ssh/id_rsa.me.pub # copy paste this one into your githubs, private keys

    # clone company internal repo as follows
    GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa.corp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
    git clone git@git.in.corp.com:corp/project.git

    export git_msg="my commit msg with my corporate identity, explicitly provide author"
    git add --all ; git commit -m "$git_msg" --author "MeFirst MeLast <first.last@corp.com>"
    GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa.corp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
    git push 
    # and verify 
    clear ; git log --pretty --format='%h %ae %<(15)%an ::: %s

    # clone public repo as follows
    GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa.corp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
    git clone git@github.com:acoolprojectowner/coolproject.git

    export git_msg="my commit msg with my personal identity, again author "
    git add --all ; git commit -m "$git_msg" --author "MeFirst MeLast <first.last@gmail.com>"
    GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa.me -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
    git push ; 
    # and verify 
    clear ; git log --pretty --format='%h %ae %<(15)%an ::: %s

    # stop :: how-to use different ssh identity files
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.