還記得之前有一篇介紹git for windows最新版本的Credential Manager有問題導致沒有辦法和遠端repo溝通(Windows安裝 git 2.19.1 之後做git clone-pull-push出現)。透過那一篇,理論上和遠端repo驗證就沒什麽問題了。
不過我自己在使用的時候發現,不知道爲什麽Azure DevOps的repo雖然跳出來輸入的是正確的帳號和密碼,但是git就是出現驗證失敗(github就不會)。
好吧,那換一種驗證方式,改成使用ssh。
不過用ssh又遇到另外一個問題,每一次和遠端溝通都要輸入passphrase超級麻煩,這個時候突然想起以前寫過(何謂ssh,在Windows下如何使用ssh,如何在Windows透過ssh下載和上傳程式到github)透過ssh agent不用一直輸入密碼。
興奮的打開那一篇,學著裡面輸入Start-SshAgent
,結果出現了error:1058
。
什麽鬼,難道不能夠讓我開開心心的pull/push然後不輸入密碼嗎?
這篇將來介紹到底在Windows 1803之後做了什麽導致ssh agent啓動不起來。
問題描述
首先,先來看看我指的是什麽意思。
Start-SshAgent
是Posh-git
裡面的一個helper的powershell方法,本質上就是做兩個事情:
- 啓動ssh-agent.exe
- 呼叫ssh-add.exe把密碼暫時記錄
一般都是需要用ssh的時候在啓動起來,因此當有需要的時候,輸入了Start-SshAgent
卻出現了了Unable to start ssh-agent service, error:1058
:
什麽鬼?怎麽不行了呢?之前那臺電腦也是Windows 10就好好的。
解決方式 - TL;DR
以下解法適合 Windows 10 1803的作業系統 - 不知道未來微軟是否會調整,但是至少在1803會有這個問題。
需要執行以下幾個動作即可解決:
- 把ssh-agent這個service從disabled狀態改成manual
-
可以透過gui的方式去設定(顯示名稱是:
OpenSSH Authentication Agent
),如果透過powershell則是:Set-Service ssh-agent -StartupType Manual
- 調整git使用内建帶的ssh agent
-
透過指令執行:
git config --global core.sshCommand "'C:/Windows/System32/OpenSSH/ssh.exe'"
做完了以上兩個動作之後,未來需要啓動ssh agent的時候只需要輸入Start-SshAgent
。接下來和遠端溝通都不需要一直輸入passphrase - 太棒了。
如果對於爲什麽要做上面兩個事情有興趣的話請繼續往下看。
爲什麽以前可以work
在説明原因之前,先把時間往回拉一點點,以前爲什麽直接呼叫Start-SshAgent
可以work?
在説明這個部分之前,需要先瞭解ssh-agent.exe
這個程式。
本質上Start-SshAgent
做的事情就是兩個動作:
- 啓動ssh-agent.exe
- 透過呼叫ssh-add.exe把預設的passphrase加入
那麽有個問題就出來了,ssh-agent這個程式是從那來?
這個程式是和Git For Windows一起進來的,實際的程式位置在:c:\Program Files\Git\usr\bin\ssh-agent.exe
。
所以Start-SshAgent這個從poshgit來的powershell function就是方便執行的一個helper而已。
一切都很美好直到......
Windows 1803的更新
在Windows 1709的時候,微軟做了一件很好的事情,也就是内建Open ssh,變成是一個類似IIS的feature,使用者可以自己決定是否要安裝。
所以,1709還沒事,因爲你不安裝,那麽等同於和以前一樣。
但是在1803不同,1803預設是安裝的,但是他又很好心怕你吃資源所以對應的Windows Service是出於Disabled
的狀態。
這個時候問題就來了,既然Windows内建了Open SSH,那麽到底應該用Git for Windows的還是用Windows内建的呢?
Start-SshAgent的問題
既然Windows自己會帶,那麽當然是用Windows的比較好,因爲ssh-agent根本就在Path裡面,可以透過指令:Get-Command ssh
看到:
這件事情在Poshgit也有多方討論,因此最後決定是會去呼叫Windows裡面的ssh-agent service。這個時候問題就來了。
還記得上面提到1803很好心的做了什麽?他預設把ssh-agent disable了,可以透過指令:Get-Service ssh-agent | select -property Status,Name,DisplayName,Starttype
那麽呼叫Start-SshAgent
就gg了,因爲沒有辦法啓動一個disabled的服務。所以出現error 1058:
因此,這個時候第一步的解法是把他改成Manual
,可以透過指令完成
Set-Service ssh-agent -StartupType Manual
Git for Windows的問題
啓動ssh-agent沒有問題了,這個時候很開心的去做一些遠端操作,卻發現,每一次操作還是要輸入passphrase。
Why?不是已經啓動ssh-agent了嗎?
原因很簡單,因爲git for windows預設使用的是它自帶的ssh-agent。換句話説,他不吃Windows自帶的Open SSH。
知道問題就好解決了,那就是設定讓git吃Windows的Open SSH。
因此可以透過設定config:
git config --global core.sshCommand "'C:/Windows/System32/OpenSSH/ssh.exe'"
結語
以上就是整個的解決過程 - 當然在找資料的時候撞了很多墻,整個理清下來大概就是這樣。
這個故事其實也告訴一件事情,調整系統的任何東西都是有影響。
個人覺得,之前1709的做法很好,要不要安裝由使用者決定。到了1803,就算要預設安裝我也可以理解,但是爲什麽Service要處於Disabled的狀態呢?如果是爲了節省資源那和不如放在Manual的狀態就好?
反過來看poshgit的Start-SshAgent
,如果說有多一個判斷Service是否為Disabled,如果是改成Manual的動作整個使用體驗會上一大階。