問題描述
ssh
具有-i
選項,用於告知在驗證時使用哪個私鑰文件:
-i identity_file
- Selects a file from which the identity (private key) for RSA or DSA authentication is read. The default is
~/.ssh/identity
for protocol version 1, and~/.ssh/id_rsa
and~/.ssh/id_dsa
for protocol version 2. Identity files may also be specified on a per-host basis in the configuration file. It is possible to have multiple-i
options (and multiple identities specified in configuration files).
有沒有類似的方法告訴git
哪個私鑰文件在~/.ssh
目錄中有多個私鑰的系統上使用?
最佳解決方案
在~/.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
次佳解決方案
環境變量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,您可以配置每個repo或全局,所以您不必再設置環境變量!
-
git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -F /dev/null"
-
git pull
-
git push
第三種解決方案
沒有直接的方法告訴git
哪個私鑰要使用,因為它依賴於ssh
進行存儲庫認證。但是,仍有幾種方法可以實現您的目標:
選項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
您可以在一行中輸入所有內容,省略。
選項3:GIT_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
的文件,使其可執行,並(間接)執行它。
選項4:~/.ssh/config
使用其他答案中建議的~/.ssh/config
文件,以指定您的私鑰的位置。
第四種方案
編寫一個使用所需參數調用ssh
的腳本,並將腳本的文件名放在$GIT_SSH
中。或者將您的配置放在~/.ssh/config
中。
第五種方案
在與$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>
工作示例腳本可能如下所示:
-
-
ssh -i /home/user/.ssh/jenkins $*
注意$*
到底是它的重要組成部分。
甚至更安全的選擇,這將防止任何與您的默認配置文件中的任何可能的沖突(加上明確提及要使用的端口)將是:
-
-
ssh -i /home/user/.ssh/jenkins -F /dev/null -p 22 $*
假設腳本在/home/user/gssh.sh
中,那么你將:
$ export GIT_SSH=/home/user/gssh.sh
所有人都應該工作。
第六種方案
如果您不想在每次運行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)
-
當然,沒有外部工具需要
第七種方案
您可以使用ssh-ident而不是創建自己的包裝器。
您可以閱讀更多:https://github.com/ccontavalli/ssh-ident
它首次需要加載ssh密鑰,一次,即使是多個登錄會話,xterms或NFS共享的家庭。
使用一個微小的配置文件,它可以自動加載不同的密鑰,並根據您需要做的事情將它們分隔在不同的代理(代理轉發)中。
第八種方案
在~/.ssh/config
中使用自定義主機配置,如下所示:
-
Host gitlab- as-thuc
-
HostName git.thuc.com
-
User git
-
IdentityFile ~ /.ssh/id_rsa.thuc
-
IdentitiesOnly yes
然后使用您的自定義主機名:
git remote add thuc git@gitlab-as-thuc:your-repo.git
欲了解更多詳情,請閱讀:http://itblog.study.land/how-to-specify-different-ssh-keys-for-git-push-for-a-given-domain/