git - 是否必須每次新增ssh-add
ringa_lee
ringa_lee 2017-04-28 09:04:12
0
3
2627

我的repo 分別推送到github,gitcafe。 正確加入了兩個公鑰私鑰之後,並命名為id_github和id_gitcafe,發現每次push 程式碼 都必須重新ssh-add 上私鑰。將id_github 位元改回預設的id_rsa,就可以直接push了。但是gitcafe 被拒絕。有沒有辦法可以一次都設定上,不需要每次 ssh-add 私鑰的。

ringa_lee
ringa_lee

ringa_lee

全部回覆(3)
淡淡烟草味

首先我得說和 ssh 相關的一切機制的確比較複雜,很容易讓人暈頭轉向,如果你想徹底掌握這個知識體係就必須系統的學習一下相關的知識。所以 first thing first,我推薦一本書給你,不妨抽空把它一勞永逸了:

SSH, The Secure Shell,這本書的第一版有中文的。

接著說你的這個特定的問題。

你首先得了解一件事:ssh-add 這個指令不是用來永久性的記住你所使用的私鑰的。實際上,它的功能只是把你指定的私鑰加到 ssh-agent 所管理的一個 session 當中。而 ssh-agent 是一個用於儲存私鑰的臨時性的 session 服務,也就是說當你重啟之後,ssh-agent 服務也就重置了。

如果是為了永久記住對應的私鑰是哪一個,我們不能依賴 ssh-agent 服務。能依賴什麼則取決於下列哪些方案適合你的使用場景。

使用某種安全的秘鑰管理機制

你沒有在問題裡描述你所使用的作業系統,所以我以我日常使用的 Mac OS X 為例。 Mac 系統內建了一個 Keychain 的服務及其管理程序,可以方便的幫你管理各種秘鑰,其中包括 ssh 秘鑰。 ssh-add 預設將制定的秘鑰添加在目前運行的ssh-agent 服務中,但是你可以改變這個預設行為讓它加入到keychain 服務中,讓Mac 來幫你記住、管理並保障這些秘鑰的安全性。

你要做的就是執行下面的指令:

$ ssh-add -K [path/to/your/ssh-key]

之後,其他的程式請求 ssh 秘鑰的時候,會透過 Keychain 服務來請求。下面的截圖裡你可以看到我目前的機器上Keychain 為我管理的有關ssh 的秘鑰,這其中包括我自己生成的四個,以及Github Client App 自己使用的一個——前者幾個都是供ssh 相關的命令所使用,而後者則指明了僅供Github.app 這個應用程式使用。 另外,它們都是 login keychains 也就是只有當前使用者登入之後才會生效的,換了使用者或是未登入狀態是不能使用的,這就是 Keychain 服務所幫你做的事情。

如何使用多個 ssh 秘鑰並對應不同的應用程式?

這個問題也是我沒有完全吃透的,按照某些資料描述,做了以上的工作之後,應用程式應該能夠自動匹配適用的 ssh 秘鑰了。但在我學習的過程中也遇到過非得手動指定的情況(那時候我還不了解Keychain 的作用,都是手動去ssh-add 的),於是另外一種機制可以幫你解決這個問題,即ssh config

一言蔽之,ssh config 就是一個設定文件,描述不同的秘鑰對應的設定-包括主機名稱、使用者名稱、存取策略等等。

以下我截取了兩個本地配置的片段:

這兩段配置分別對應 Github 和 Coding 這兩個服務所使用的秘鑰。第一行的 Host 只是一個名字,第三行的 Hostname 是對應的真實地址,但是兩者最好保持一致,這樣不用在腦袋裡轉換。

用這樣的配置,當我 git clone https://github.com/user/repo 的时候,id_rsa 秘钥会被使用,当我 git clone https://coding.net/user/repo 的时候,很显然 nightire 秘鑰會被使用。

當然,此設定不限於 Git,所有底層使用 SSH 的應用程式和命令都會遵照設定檔的指示來找到對應的私鑰。

回到本節開始的話題,我相信有了 Keychain 做管理應該是不需要這個設定檔的,但是我還沒機會去做測試。目前的環境一切正常,等到我換新機器重新配置環境的時候我會試試看。

關於 Host 和 Hostname 的對應關係,如果 Hostname 是網域名稱最好保持一致。但這裡有兩個訣竅:
1. 如果同一網域下有兩個不同的配置怎麼辦?
以 Github 為例,如果我有兩個帳戶,一個個人的,一個組織的,並且要使用不同的秘鑰,那麼我可以這麼寫:

這裡 Host 後面對應的是 Github 的兩個用戶名,也就是 github.com/nightiregithub.com/very-geek
2. 如果網域是數字 IP,是否可以簡化呢?
Host 可以幫助你把對應的 IP 變成好記的名字。比方說我在公司內部配置了 Git Server(基於 gitolite 或 Gitlab 或任何工具),正常的存取位址是:git://xxx.xxx.xxx.xxx:repo.git,如下的配置则可以帮你把它简化成:git.visionet:repo.git

非常有用。

有沒有簡單點的辦法?

有。如果 ssh-add 已經可以滿足你的要求(除了啟動以後還要再來一遍以外),那麼你完全可以用腳本自動化這件事。簡單地把你輸入的 ssh-add 指令的內容寫進 .bashrc.bash_profile(或其他任何你使用的 shell 環境設定檔)中去,這樣只要你打開終端,就等於自動做了這件事。

不過如我之前所說,這個機制是依賴 ssh-agent 服務的,而且只能在終端下有效。而用 Keychain 機制的話,是整個系統內都有效的(包括不依賴終端機的應用程式)且無需開啟 ssh-agent 服務。

最後 Keychain 服務不是只有 Mac 才有的,我剛才搜尋了一下,Windows 和 各種 Linux 都有對應的機制,不過我沒用過,只能以 Mac 為例了。了解了這些概念,相信你可以自己查出具體的方法。

巴扎黑

對已經採納答案的小小補充

ssh-add 這個指令不是用來永久性的記住你所使用的私鑰的。實際上,它的功能只是把你指定的私鑰加到 ssh-agent 所管理的一個
session 當中。而 ssh-agent 是用於儲存私鑰的臨時性的 session 服務,也就是說當你重新啟動之後,ssh-agent
服務也重置了。

可以從github的文章中,了解如何加到目前的session中:
Generating a new SSH key and adding it to the ssh-agent

可以透過下面的文章來了解ssh是如何使用公鑰私鑰對的:
Error: Permission denied (publickey)

另,本地設定內容放在檔案:

/Users/you/.ssh/config
伊谢尔伦

我是乾脆都一樣的帳號密碼 github.com coding.net 。這樣都可以用。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板