題 如何告訴git使用哪個私鑰?


ssh 有 -i 用於在進行身份驗證時告知使用哪個私鑰文件的選項:

-i identity_file

    選擇一個文件   讀取RSA或DSA身份驗證的標識(私鑰)。   默認是 ~/.ssh/identity 對於協議版本1,   和 ~/.ssh/id_rsa 和 ~/.ssh/id_dsa 對於協議版本2。   還可以基於每個主機指定身份文件   在配置文件中。有可能有多個 -i 選項    (以及配置文件中指定的多個標識)。

是否有類似的方式告訴 git 在具有多個私鑰的系統上使用哪個私鑰文件 ~/.ssh 目錄?


497
2018-01-12 18:20


起源


看到 StackOverflow中的這個問題 同樣。 - Flimm
也有關係 serverfault.com/questions/194567/... - Machavity


答案:


~/.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

543
2018-01-12 19:36



如果您需要使用不同的密鑰連接到同一主機,該怎麼辦? - Valentin Klinghammer
@Quelltextfabrik - 您可以使用其他主機添加另一個部分: nerderati.com/2011/03/... - Ben Challenor
@Cliff Nop,在我的聯機幫助頁中:“HostName:指定要登錄的真實主機名。這可以用來指定主機的暱稱或縮寫。“我的ssh版本是openssh-6.7p1。 - Grissiom
@Grissiom這就是它所說的。但你似乎理解倒退的意思。主機(或匹配)是必需的。要創建主機暱稱,請將暱稱放在主機行中,將真實主機名放在HostName行中。例子: saltycrane.com/blog/2008/11/... - Cliff
如果配置文件是新的,請不要忘記 chmod 600 ~/.ssh/config - elysch


環境變量 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

238
2018-05-08 09:43



我不得不出口 貝殼 變量到環境變量,使這項工作,即 export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example", 然後 git clone example - Abdull
@Abdull在Bash中,在與命令相同的行上進行賦值,只為該命令導出環境變量。試試吧: example=hello /usr/bin/env | grep example。 - Flimm
事情變得更好:從Git 2.10開始,您可以將命令存儲在Git配置中: stackoverflow.com/a/38474220/520162 - eckes
@Noitidart /dev/null 在類UNIX操作系統中只是一個有效的文件名,它在Windows上不起作用。 - Flimm
如果需要多個鍵,可以重複-i參數,ssh將依次嘗試每個鍵。 git config core.sshcommand "ssh -i /path/to/keyA -i /path/to/keyB"。這允許git使用不同的密鑰與不同的遠程主機。 - Mark


沒有 直接 辦法 告訴 git 要使用哪個私鑰,因為它依賴於 ssh 用於存儲庫驗證。但是,仍有幾種方法可以實現您的目標:

選項1: ssh-agent

您可以使用 ssh-agent 暫時授權您的私鑰。

例如:

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

選項2: GIT_SSH_COMMAND

使用。傳遞ssh參數 GIT_SSH_COMMAND 環境變量 (Git 2.3.0+)。

例如:

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

您可以在一行中輸入所有內容 - 忽略 $ 並且遺漏了 \

選項3: GIT_SSH

使用。傳遞ssh參數 GIT_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

注意:上面的行是shell(終端)命令行,您應該將它們粘貼到終端中。他們將創建一個名為的文件 ssh,使其可執行,並(間接)執行它。

注意: GIT_SSH 自v0.99.4起可用 (2005年)。

選項4: ~/.ssh/config

使用 ~/.ssh/config 根據其他答案中的建議提交文件,以指定私鑰的位置,例如

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

70
2018-01-23 22:08



//,如果轉發了ssh-agent中的身份,如此問題,該怎麼辦? superuser.com/questions/971732/... - Nathan Basanese
我允許我重新格式化這篇文章:IMO這是迄今為止最全面的答案。在其原始設計中,快速掃描建議帖子描述問題的單一複雜解決方案,所以我錯過了它。 - Alberto
$ ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; git fetch user@host' 什麼都沒有,為我工作。榮譽。 - Daniel Dewhurst
我不得不使用 ~/.ssh/config 方法,env vars對我不起作用...... - Greg Dubicki
GIT_SSH 從那時起可用 v0。99。4(2005年8月),基本上自Git存在以來(2005年4月)。 - Dominik


寫一個調用的腳本 ssh 使用您想要的參數,並將腳本的文件名放入 $GIT_SSH。或者只是將您的配置放入 ~/.ssh/config


32
2018-01-12 18:25



另一種解釋 怎麼做 - Sithsu
~/.ssh/config 是 該 要走的路。 - hek2mgl
我在一台機器(A)上工作,我將git推送到只接受ssh密鑰認證的服務器(B)。雖然我直接工作時(A)上的〜/ .ssh / config設置完全正常 上 那台機器,當我從其他位置(C)登錄時,它不會。運用 $GIT_SSH 並且腳本解決了這個問題。謝謝! - bsumirak


如果你不想每次運行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中),則非常有用
  • 當然,不需要外部工具

15
2017-07-21 19:44



//,優秀的解決方案。不過,我想知道是否允許指定通過代理轉發傳遞的身份。我的大多數密鑰都不是我使用它們的服務器的本地密鑰。我在這裡問過這件事: superuser.com/questions/971732/... - Nathan Basanese
答案僅涉及指定用作git存儲庫的任意命令行的方法。恕我直言,你應該首先嘗試單獨使用ssh來解決你的問題(例如“ssh” 主辦“應該使用正確的密鑰連接。”但我會嘗試提供有關您的其他問題的更多信息。 - flaviovs
這個答案正是我需要強迫廚師的 git 資源,使用特定於存儲庫的部署密鑰從私有Github存儲庫進行克隆/獲取。此方法相對於基於環境/腳本的方法的另一個優點是,由於密鑰路徑在working-repo的配置中進行編碼,因此它將在初始克隆和後續提取/推送時使用相同的密鑰。 - Adam Franco
哇!這很棒,不知道這個。感謝答案,在木偶環境中也很有幫助,以防止額外的麻煩管理 .ssh/config 等+1! - gf_
如果遇到以下錯誤 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


經過與我的鬥爭 $GIT_SSH 我想分享一下對我有用的東西。

通過我的示例,我將假設您的私鑰位於/home/user/.ssh/jenkins

要避免錯誤:GIT_SSH值包括選項

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

或類似的任何失敗,如 git會嘗試將值作為文件執行。因此,您必須創建一個腳本。

$ 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

所有人都應該工作。


13
2018-05-28 17:09



謝謝。請注意:對於pass-thru參數,使用“$ @”而不是$ *,因為前者在參數包含空格時表現正確。 - Piotr Findeisen
@PiotrFindeisen感謝您的留言。但是,我完全不理解它 - 在zsh中它幫助我保持一塊空間的字符串,但不是bash。你能告訴我更多還是指出一些解釋?我不想盲目地添加一些修改。 - Jan Vlcinsky
你應該刪除答案的前半部分。沒有人對一個不起作用的解決方案感興趣,並且浪費了閱讀,在底部混淆了正確的答案,這非常有效。 - Cerin
@Cerin如果你的意思是刪除“要避免的錯誤”我將保留它。它有共同的缺陷要避免,而且很短。我相信,有人會嘗試通過將所有的東西都變成變量(這發生在我身上)來優化解決方案,所以我試圖縮短成功之路。 - Jan Vlcinsky


使用自定義主機配置 ~/.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  

7
2018-05-17 15:03



這是我正在尋找的答案,因為我有單獨的GitHub帳戶用於家庭和工作。我只需要設置 Host work.github.com  HostName github.com  IdentityFile ~/.ssh/work,每當我克隆工作存儲庫時,用“work.github.com”替換“github.com”。它仍然連接到“github.com”,但使用非默認密鑰對。 - Mikkel
詳情的網址(“itblog.study.land / ......“)不再工作:( - Carl Smotricz


您可以使用ssh-ident而不是創建自己的包裝器。

您可以在以下網址閱讀更多    https://github.com/ccontavalli/ssh-ident

它在第一次需要時按需加載ssh密鑰,一次,即使有多個登錄會話,xterms或NFS共享住宅。

使用微小的配置文件,它可以自動加載不同的密鑰,並根據您需要執行的操作將它們分隔在不同的代理中(用於代理轉發)。


5
2018-03-23 01:35





我有一個客戶端需要一個單獨的github帳戶。所以我需要為這個項目使用一個單獨的密鑰。

我的解決方案是將其添加到我的.zshrc / .bashrc中:

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

每當我想為該項目使用git時,我用git替換“infogit”:

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

對我來說,它更容易記住。


4
2018-03-26 19:26





我的解決方案是:

創建一個腳本:

#!/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
2017-12-05 12:22