[英]How to specify the private SSH-key to use when executing shell command on Git?
也許是一種相當不尋常的情況,但我想指定一個私有 SSH 密鑰,以便在從本地計算機執行 shell ( git
) 命令時使用。
基本上是這樣的:
git clone git@github.com:TheUser/TheProject.git -key "/home/christoffer/ssh_keys/theuser"
或者更好(在 Ruby 中):
with_key("/home/christoffer/ssh_keys/theuser") do
sh("git clone git@github.com:TheUser/TheProject.git")
end
我已經看到使用指定私鑰的Net::SSH
連接到遠程服務器的示例,但這是一個本地命令。 是否可以?
這些解決方案都不適合我。
相反,我詳細說明了@Martin v. Löwis 提到為 SSH 設置config
文件。
SSH 將查找用戶的~/.ssh/config
文件。 我的設置為:
Host gitserv
Hostname remote.server.com
IdentityFile ~/.ssh/id_rsa.github
IdentitiesOnly yes # see NOTES below
我添加了一個遠程 git 存儲庫:
git remote add origin git@gitserv:myrepo.git
然后 git 命令對我來說正常工作。
git push -v origin master
筆記
IdentitiesOnly yes
以防止 SSH 默認行為發送與每個協議的默認文件名匹配的身份文件。 如果您有一個名為~/.ssh/id_rsa
的文件,它將在您的~/.ssh/id_rsa.github
之前嘗試,而無需此選項。參考
像這樣的東西應該可以工作(由 orip 建議):
ssh-agent bash -c 'ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git'
如果您更喜歡 subshell,您可以嘗試以下方法(盡管它更脆弱):
ssh-agent $(ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git)
Git 將調用 SSH,它會通過環境變量找到它的代理; 反過來,這將加載密鑰。
或者,設置HOME
也可以解決問題,前提是您願意將僅包含.ssh
目錄的目錄設置為HOME
; 這可能包含一個identity.pub,或一個配置文件設置IdentityFile。
從 Git 2.3.0 開始,我們還有一個簡單的命令(不需要配置文件):
GIT_SSH_COMMAND='ssh -i private_key_file -o IdentitiesOnly=yes' git clone user@host:repo.git
請注意,需要-o IdentitiesOnly=yes
以防止 SSH 默認行為發送與每個協議的默認文件名匹配的身份文件,如上面的答案中所述。
其他人對~/.ssh/config
的建議更加復雜。 它可以很簡單:
Host github.com
IdentityFile ~/.ssh/github_rsa
使用 git 2.10+(2016 年第三季度:2016 年 9 月 2 日發布),您可以為GIT_SSH_COMMAND
設置配置(而不僅僅是Rober Jack Will的回答中描述的環境變量)
請參閱Nguyễn Thái Ngọc Duy ( pclouds
)的提交 3c8ede3 (2016 年 6 月 26 日)。
(由Junio C Hamano -- gitster
--在提交 dc21164中合並,2016 年 7 月 19 日)
添加了一個新的配置變量
core.sshCommand
來指定GIT_SSH_COMMAND
使用的每個存儲庫的值。
core.sshCommand:
如果設置了這個變量,當
git fetch
和git push
需要連接到遠程系統時,它們將使用指定的命令而不是ssh
。
該命令與GIT_SSH_COMMAND
環境變量的形式相同,並在設置環境變量時被覆蓋。
這意味着git pull
可以是:
cd /path/to/my/repo/already/cloned
git config core.sshCommand 'ssh -i private_key_file'
# later on
git pull
你甚至可以只為一個命令設置它,比如git clone
:
git -c core.sshCommand="ssh -i private_key_file" clone host:repo.git
這比設置GIT_SSH_COMMAND
環境變量更容易,如Mátyás Kuti-Kreszács所述,在 Windows 上,它將是
set "GIT_SSH_COMMAND=ssh -i private_key_file"
my_git_ssh_wrapper 的內容:
#!/bin/bash
ssh -i /path/to/ssh/secret/key $1 $2
然后,您可以通過執行以下操作來使用密鑰:
GIT_SSH=my_git_ssh_wrapper git clone git@github.com:TheUser/TheProject.git
總結一下答案和評論,設置git使用不同密鑰文件然后忘記它的最佳方法,它還支持同一主機的不同用戶(例如個人GitHub帳戶和工作帳戶),適用於Windows同樣,是編輯~/.ssh/config
(或c:\Users\<your user>\.ssh\config
)並指定多個身份:
Host github.com
HostName github.com
IdentityFile /path/to/your/personal/github/private/key
User dandv
Host github-work
HostName github.com
IdentityFile /path/to/your/work/github/private/key
User workuser
然后,要以個人用戶身份克隆項目,只需運行常規git clone
命令。
要將workuser
克隆為工作用戶,請運行git clone git@github-work:company/project.git
。
如此處所述: https ://superuser.com/a/912281/607049
您可以為每個 repo 配置它:
git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -F /dev/null"
git pull
git push
問題是當您在同一主機(例如 github.com)上有不同的遠程存儲庫,並且您想使用不同的 ssh 密鑰(即不同的 GitHub 帳戶)與它們交互時。
為了做到這一點:
首先,您應該在~/.ssh/config
文件中聲明不同的密鑰。
# Key for usual repositories on github.com Host github.com HostName github.com User git IdentityFile ~/.ssh/id_rsa # Key for a particular repository on github.com Host XXX HostName github.com User git IdentityFile ~/.ssh/id_other_rsa
通過這樣做,您將第二個鍵與 github.com 的新友好名稱“XXX”相關聯。
然后,您必須更改特定存儲庫的遠程來源,以便它使用您剛剛定義的友好名稱。
在命令提示符下轉到本地存儲庫文件夾,並顯示當前遠程源:
>git remote -v origin git@github.com:myuser/myrepo.git (fetch) origin git@github.com:myuser/myrepo.git (push)
然后改變原點:
>git remote set-url origin git@XXX:myuser/myrepo.git >git remote -v origin git@XXX:myuser/myrepo.git (fetch) origin git@XXX:myuser/myrepo.git (push)
現在您可以使用右鍵自動推送、獲取...。
最快和最簡單的方法是:
使用 ssh 克隆你的倉庫:
git -c core.sshCommand="ssh -i ~/.ssh/<your_key>" clone git@github.com:<user>/<repo>.git
然后cd
進入你克隆的 repo 並:
git config core.sshCommand 'ssh -i ~/.ssh/<your_key>'
要測試它是否正常工作:
git --git-dir=/path/to/repo/.git pull
所以你可能想知道:為什么我創建的 ssh 密鑰在我在 github 中種植 .pub 並且私有在默認目錄中之后不起作用?
該文檔為我們提供了一個澄清問題的命令: ssh -vT git@github.com
輸出顯示 git 查找的 ssh 密鑰名稱列表。 因此,您可能希望使用其中一個名稱創建您的密鑰,或者使用上述過程來包含您需要的名稱。
GIT_SSH_COMMAND="ssh -i /path/to/git-private-access-key" git clone $git_repo
或者
export GIT_SSH_COMMAND="ssh -i /path/to/git-private-access-key"
git clone REPO
git push
像這樣將該主機或 ip 添加到.ssh/config
文件的方法更好:
Host (a space separated list of made up aliases you want to use for the host)
User git
Hostname (ip or hostname of git server)
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_(the key you want for this repo)
從 Git 版本 2.10.0 開始,您可以按 repo 或全局配置它
git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -o 'IdentitiesOnly yes'"
這將為當前 repo 指定將使用的 ssh 密鑰。 我假設如果你想指定這個全局只需要設置--global
選項。
我使用了 GIT_SSH 環境變量。 這是我的包裝器,類似於上面 Joe Block 的包裝器,但可以處理任意數量的參數。
文件 ~/gitwrap.sh
#!/bin/bash
ssh -i ~/.ssh/gitkey_rsa "$@"
然后,在我的 .bashrc 中,添加以下內容:
export GIT_SSH=~/gitwrap.sh
假設您在 aws 上有一個 ubuntu 服務器,您通常像這樣連接到它:
% ssh -i blah/yourkeypair.pem ubuntu@test.fattie.com
在終端只是
% export GIT_SSH_COMMAND="ssh -i /Users/fattie/Desktop/blah/yourkeypair.pem"
在你這樣做之后。 然后就可以自由...
% git clone ubuntu@test.fattie.com:/home/ubuntu/teste.git
這會將您服務器上的存儲庫克隆到您的本地文件夾“teste”,
然后,您可以在 teste/ 中自由執行常用命令,例如...
% git push origin master
等等。
--
另請注意: https ://stackoverflow.com/a/67287133/294884
至於在服務器上,看來你基本上
] git clone --bare the-actual-folder teste.git
然后在 teste.git
] git init --bare --shared
如果這里的其他解決方案都不適合您,並且您創建了多個 ssh 密鑰,但仍然無法執行簡單的操作,例如
git pull
然后假設您有兩個 ssh 密鑰文件,例如
id_rsa
id_rsa_other_key
然后在 git repo 中,嘗試:
# Run these commands INSIDE your git directory
eval `ssh-agent -s`
ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/id_rsa_other_key
並通過以下方式確保您的 github 默認用戶名和用戶 ID 正確:
# Run these commands INSIDE your git directory
git config user.name "Mona Lisa"
git config user.email "mona.lisa@email.com"
有關更多信息,請參閱https://gist.github.com/jexchan/2351996 。
當您需要通過正常請求( git pull origin master
)連接到 github 時,在~/.ssh/config
中將主機設置為*
對我有用,任何其他主機(例如“github”或“gb”)都不是工作。
Host *
User git
Hostname github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_xxx
其中許多解決方案看起來很誘人。 但是,我發現以下鏈接中的通用 git-wrapping-script 方法最有用:
關鍵是沒有git
命令,如下所示:
git -i ~/.ssh/thatuserkey.pem clone thatuser@myserver.com:/git/repo.git
Alvin 的解決方案是使用一個定義明確的 bash-wrapper 腳本來填補這個空白:
git.sh -i ~/.ssh/thatuserkey.pem clone thatuser@myserver.com:/git/repo.git
git.sh
在哪里:
#!/bin/bash
# The MIT License (MIT)
# Copyright (c) 2013 Alvin Abad
# https://alvinabad.wordpress.com/2013/03/23/how-to-specify-an-ssh-key-file-with-the-git-command
if [ $# -eq 0 ]; then
echo "Git wrapper script that can specify an ssh-key file
Usage:
git.sh -i ssh-key-file git-command
"
exit 1
fi
# remove temporary file on exit
trap 'rm -f /tmp/.git_ssh.$$' 0
if [ "$1" = "-i" ]; then
SSH_KEY=$2; shift; shift
echo "ssh -i $SSH_KEY \$@" > /tmp/.git_ssh.$$
chmod +x /tmp/.git_ssh.$$
export GIT_SSH=/tmp/.git_ssh.$$
fi
# in case the git command is repeated
[ "$1" = "git" ] && shift
# Run the git command
git "$@"
我可以驗證這解決了我在使用git remote update
、 git pull
和git clone
進行遠程 bitbucket 存儲庫的用戶/密鑰識別時遇到的問題; 所有這些現在都可以在cron
作業腳本中正常工作,否則在有限 shell 中導航時會遇到問題。 我還能夠從 R 中調用此腳本,並且仍然解決完全相同的cron
執行問題(例如system("bash git.sh -i ~/.ssh/thatuserkey.pem pull")
)。
並不是說 R 與 Ruby 相同,但如果 R 可以做到... O:-)
很多很好的答案,但其中一些假設事先有管理知識。
我認為重要的是要明確強調,如果您通過克隆 Web URL 開始您的項目- https://github.com/<user-name>/<project-name>.git
那么您需要確保.git/config
中[remote "origin"]
下的url
值已更改為 SSH URL (請參見下面的代碼塊)。
除此之外,請確保添加sshCommmand
,如下所述:
user@workstation:~/workspace/project-name/.git$ cat config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
sshCommand = ssh -i ~/location-of/.ssh/private_key -F /dev/null <--Check that this command exist
[remote "origin"]
url = git@github.com:<user-name>/<project-name>.git <-- Make sure its the SSH URL and not the WEB URL
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
在此處閱讀更多相關信息。
我只需要添加密鑰然后再次運行 git clone。
ssh-add ~/.ssh/id_rsa_mynewkey
git clone git@bitbucket.org:mycompany/myrepo.git
如果您的路徑上有目錄要使用給定的標識文件進行簽名,您可以通過 .ssh/config 文件通過設置ControlPath
來指定使用特定的標識文件,例如:
host github.com
ControlPath ~/Projects/work/**
HostName github.com
IdentityFile ~/.ssh/id_work
User git
然后ssh
在給定的工作路徑下執行 git 命令時會使用指定的身份文件。
在帶有 Git Bash 的 Windows 中,您可以使用以下命令添加存儲庫
ssh-agent bash -c 'ssh-add "key-address"; git remote add origin "rep-address"'
例如:
ssh-agent bash -c 'ssh-add /d/test/PrivateKey.ppk; git remote add origin git@git.test.com:test/test.git'
哪個私鑰在驅動器D,計算機的文件夾測試中。 此外,如果要克隆存儲庫,可以使用git clone
更改git remote add origin
。
將其輸入到 Git Bash 后,它會要求您輸入密碼!
請注意,openssh 私鑰和 putty 私鑰是不同的!
如果您使用 puttygen 創建了密鑰,則必須將您的私鑰轉換為 openssh!
這種方法的問題是,至少在 Windows 上通過 bash.exe 運行時,它每次都會創建一個新進程,該進程將保持休眠狀態。
ssh-agent bash -c 'ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git'
如果您想按計划將其用於syncig repo,那么您需要在最后添加“&& ssh-agent -k”。
就像是:
ssh-agent bash -c 'ssh-add C:/Users/user/.ssh/your_key; git -C "C:\Path\to\your\repo" pull && ssh-agent -k'
ssh-agent -k 將在完成后終止該進程。
這里給出的大多數答案都沒有解釋最基本的用法的細節。
在雲中設置服務器(在本例中為linux
服務器)后,您可以從終端使用 ssh 連接到它。
在您的計算機上,將您的雲服務提供商(如 Azure、AWS 等)提供給您的私鑰dyson-ubuntu-vm.pem
添加到本地計算機上的 .ssh 配置中,如下所示:
將.pem
文件復制到/home/ssenyonjo/.ssh
文件夾,然后打開/home/ssenyonjo/.ssh/config
文件並添加以下條目:
Host 20.85.213.44
HostName 20.85.213.44
User Dyson
IdentityFile /home/ssenyonjo/.ssh/dyson-ubuntu-vm.pem
IdentitiesOnly yes
現在從您的終端訪問雲 linux 服務器,如下所示:
ssh Dyson@20.85.213.44
當它工作時,在雲服務器上創建一個 git 項目,如下所示:
Dyson@dyson-ubuntu-vm:~/projects$ git init --bare s2
現在回到您的本地機器並像這樣克隆那個空存儲庫:
ssenyonjo@ssenyonjo-pc:~/Projects/mastering-git$ git clone ssh://Dyson@20.85.213.44/home/Dyson/projects/s2
如果您看到類似於以下內容的錯誤: fatal: Could not read from remote repository
,這意味着您訪問了錯誤的文件夾。 確保您已經概述了從根目錄到創建的存儲庫的正確路徑。
如果您不想設置配置文件但想訪問需要密鑰的 ssh 服務器,可以使用以下命令:
GIT_SSH_COMMAND='ssh -i ~/Projects/aws/keys/aws_ubuntu.pem' git clone ssh://ubuntu@15.207.99.158/home/ubuntu/projects/mastering-git/rand
您可以導出命令以繼續將其用於其他任務,例如git push
和git pull
export GIT_SSH_COMMAND='ssh -i ~/Projects/aws/keys/aws_ubuntu.pem'
請參閱: https ://stackoverflow.com/a/29754018/10030693
讓 GIT_SSH_COMMAND 環境變量在 Windows(CMD) 下工作,而不是:
set GIT_SSH_COMMAND="ssh -i private_key_file"
利用:
set "GIT_SSH_COMMAND=ssh -i private_key_file"
報價必須像
set "variable=value"
一些背景: https ://stackoverflow.com/a/34402887/10671021
您需要創建一個 ~/.ssh/config 如下
Host <Your bitbucket server>
User <userid>
Hostname <Your bitbucket server as above>
IdentitiesOnly yes
IdentityFile ~/.ssh/id_rsa<file> This is your private key file
權限如下
-rw------- $HOME/.ssh/config
將您的公鑰添加到您的 git 中(cat ~/.ssh/id_rsa_pub [或類似名稱])
然后 git clone 如下
git clone ssh://blahblah@blah.com/userid/test.git
用例是我需要使用 SSH 來使用個人和工作 GitHub 帳戶。 我想默認使用工作 SSH 密鑰,因為我的項目內部將有其他工作存儲庫作為依賴項。 所以克隆它們應該可以無縫地工作。
我遵循的步驟是:
生成默認 SSH 密鑰並將其添加到工作 git 帳戶。
在單獨的文件中生成個人 SSH 密鑰並將其添加到個人 git 帳戶。
在.bashrc
或.zshrc
文件中添加以下函數代碼並獲取它。
gclone() { # Clone the repo-url using personal ssh-key git -c core.sshCommand="ssh -i path_to_personal_key" clone "$1" && # Extract repo name from URL using "awk" and switch to that folder using "cd" cd $(awk '{ sub(/.*\//, ""); sub(/\.git.*/, ""); print }' <<< "$1") && # Set personal ssh-key as default for this repo git config core.sshCommand "ssh -i path_to_personal_key"; }
使用gclone
命令使用個人 SSH 密鑰克隆存儲庫,並將存儲庫設置為默認使用該密鑰。
使用普通的git clone
命令克隆帶有默認(工作)SSH 密鑰的存儲庫。
我使用zsh
並且不同的密鑰會自動加載到我的 zsh shell 的ssh-agent
中,以用於我筆記本電腦上的其他目的(即訪問遠程服務器)。 我修改了@Nick 的答案,並將它用於我需要經常刷新的回購協議之一。 (在這種情況下,這是我的點文件,無論我在dotfiles
工作,我都希望在我的所有機器上使用相同的最新版本。)
bash -c 'eval `ssh-agent`; ssh-add /home/myname/.dotfiles/gitread; ssh-add -L; cd /home/myname/.dotfiles && git pull; kill $SSH_AGENT_PID'
cd
到 repo dir 成功,從遠程 repo 拉取對於gitlab RSAAuthentication yes
Host gitlab.com
RSAAuthentication yes
IdentityFile ~/.ssh/your_private_key_name
IdentitiesOnly yes
在一個命令中克隆
git -c core.sshCommand='ssh -i /path/to/key/' clone git@github.com:your_repository.git /path/target/clone --branch git_branch_name
您可以使用 GIT_SSH 環境變量。 但是您需要將 ssh 和選項包裝到一個 shell 腳本中。
請參閱 git 手冊:命令 shell 中的man git
。
如果 SSH 端口號不是 22(默認),則在~/.ssh/config
中添加Port xx
就我而言(Synology),
Host my_synology
Hostname xxxx.synology.me
IdentityFile ~/.ssh/id_rsa_xxxx
User myname
Port xx
然后使用配置中的主機標題進行克隆。 (“my_synology”。避免@chopstik 的“*”)
git clone my_synology:path/to/repo.git
2022 WINDOWS+POWERSHELL :
當您使用當前流行的Windows Terminal 時,您可以為新終端指定一個命令行。 這是用於啟動PowerShell的簡短配置(在我看來,如果經過修改,外觀會更好,並且更現代):
{
"commandline": "powershell -NoExit -Command \"$env:GIT_SSH_COMMAND='ssh -i C:\\\\mypathtoidenitty\\\\id_rsa_x'",
"guid": "{4b8d0cfe-e8be-4ae6-a4ad-88efd65b0983}",
"hidden": false,
"icon": "🗽",
"name": "bitbucket",
"startingDirectory": "C:\\myrepos\\"
},
哎呀! 請注意身份路徑中的四個反斜杠。
通過這種方式,您可以全面了解您的路徑並設置身份,並且如果您有許多給定服務器,則不必為給定服務器的每個 repo 設置git config core.sshCommand
。
獎勵:通過問題使用ssh -Tv -i ...
查看實際使用了哪些身份。
此命令克隆存儲庫並將 SSH 密鑰配置為永久使用:
git clone -c "core.sshCommand=ssh -i ~/.ssh/<key>" git@github.com:<user>/<repo>.git
現在,如果您運行git fetch
、 git pull
或git push
,它將使用在core.sshCommand
中配置的 SSH 密鑰(保存在.git/config
中)。
為什么不將身份密鑰的位置添加到 git 配置文件中,以獲取特定的回購協議,如下所示:
cd .git
vi config
[core]
sshcommand = ssh -i <IDENTITY_KEY_LOCATION>
這就是你所需要的。
另外,作為一個簡單的“解決方法”,如果您真的不需要那么頻繁:
刪除所有 ssh 身份
ssh-add -D
重新添加您需要使用的那個
ssh-add ~/.ssh/MyProperProfile
做 gits
可選 - 通過添加其他身份(或所有身份)來恢復。
如果你和我一樣,你可以:
讓您的 ssh 密鑰井井有條
保持你的 git clone 命令簡單
為任意數量的存儲庫處理任意數量的密鑰。
減少您的 ssh 密鑰維護。
我將密鑰保存在~/.ssh/keys
目錄中。
我更喜歡約定而不是配置。
我認為代碼就是法律; 越簡單越好。
第 1 步 - 創建別名
將此別名添加到您的 shell: alias git-clone='GIT_SSH=ssh_wrapper git clone'
第 2 步 - 創建腳本
將此ssh_wrapper腳本添加到您的 PATH:
#!/bin/bash
# Filename: ssh_wrapper
if [ -z ${SSH_KEY} ]; then
SSH_KEY='github.com/l3x' # <= Default key
fi
SSH_KEY="~/.ssh/keys/${SSH_KEY}/id_rsa"
ssh -i "${SSH_KEY}" "$@"
例子
使用 github.com/l3x 密鑰:
KEY=github.com/l3x git-clone https://github.com/l3x/learn-fp-go
以下示例還使用github.com/l3x鍵(默認情況下):
git-clone https://github.com/l3x/learn-fp-go
使用 bitbucket.org/lsheehan 密鑰:
KEY=bitbucket.org/lsheehan git-clone git@bitbucket.org:dave_andersen/exchange.git
筆記
將 ssh_wrapper 腳本中的默認 SSH_KEY 更改為您最常使用的內容。 這樣,您大部分時間都不需要使用 KEY 變量。
你可能會想,“嘿!這與別名、腳本和一些鍵目錄有關,”但對我來說,這是約定俗成的。 幾乎我所有的工作站(以及與此相關的服務器)都進行了類似的配置。
我的目標是簡化我定期執行的命令。
我的約定,例如 Bash 腳本、別名等,創建了一個一致的環境並幫助我保持簡單。
吻和名字很重要。
有關更多設計技巧,請查看我的書中的第 4 章 Go 中的 SOLID 設計: https ://www.amazon.com/Learning-Functional-Programming-Lex-Sheehan-ebook/dp/B0725B8MYW
希望有幫助。 - 萊克斯
這是我在尋找解決這個問題的方法時發現的 ssh key hack:
例如,您有 2 組不同的鍵:
key1, key1.pub, key2, key2.pub
將這些密鑰保存在您的.ssh
目錄中
現在在您的.bashrc
或.bash_profile
別名文件中,添加這些命令
alias key1='cp ~/.ssh/key1 id_rsa && cp ~/.ssh/key1.pub id_rsa.pub'
alias key2='cp ~/.ssh/key2 id_rsa && cp ~/.ssh/key2.pub id_rsa.pub'
瞧! 您可以隨時切換鍵的快捷方式!
希望這對你有用。
您可以嘗試使用 sshmulti npm 包來維護多個 ssh 密鑰。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.