ssh-agent 以圖形方式啟動時不加入金鑰

ssh-agent 以圖形方式啟動時不加入金鑰

最近我將以下腳本新增至我的自動啟動(在 KDE 中):

eval `ssh-agent`
ssh-add

該腳本應在登入時啟動,並詢問我的密碼並加載我的密鑰。效果幾乎沒問題。腳本正確執行,代理啟動,環境變數全部設定完畢,系統要求我輸入密碼。唯一的問題是此後密鑰未載入。但是,如果我隨後在終端機中輸入 ssh-add ,系統會要求我輸入密碼,並且金鑰將儲存在我的 X 會話的其餘部分中。

我究竟做錯了什麼?儘管要求我輸入密碼,但為什麼密鑰未載入?

PS:我在 Debian jessie 上運行。

答案1

我能想到有兩種可能的情況會導致這種情況。

這兩者都源自於許多桌面管理器推出自己的 ssh 金鑰代理程式。這樣做是因為代理程式需要在桌面管理器之前啟動,以便由桌面管理器(您的終端模擬器)啟動的應用程式拾取導出的變數。

  1. 在您啟動桌面管理器後,您的桌面管理器將啟動自己的 ssh 代理,並最終取代它。

    我不確定您在何時或如何啟動 ssh 代理,但如果桌面管理器在您的代理之後啟動,其導出的變數將覆蓋您創建的變數。

  2. 您的桌面管理器會在您之前啟動自己的 ssh 代理,而您的桌面管理器不會被保留。

    如果您只是啟動終端機視窗並執行,那麼在您關閉終端視窗後,eval $(ssh-agent); ssh-add由此匯出的變數將不會保留。ssh-agent啟動新的終端機視窗後,您將獲得由桌面管理器啟動的 ssh 代理程式設定的變數。


工作方式ssh-agent是在背景啟動一個守護進程,然後列印幾個需要設定的變數。

$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-JLbBwVBP4754/agent.4754; export SSH_AUTH_SOCK;
SSH_AGENT_PID=4755; export SSH_AGENT_PID;
echo Agent pid 4755;

因此,當您設定時eval $(ssh-agent),您只需設定所有這些變數。

現在,變數只能由子級繼承,因此為了使它們保留在桌面管理器中,必須在桌面管理器啟動之前設定它們。這可能很難做到正確,並且因發行版而異。這就是許多桌面管理器自己這樣做的原因。
請注意,有時也會在 pam 堆疊初始化期間完成此操作。

答案2

正如帕特里克指出的那樣,您可能會ssh-agent與桌面環境生成的實例競爭。好吧,「競爭」可能不是正確的詞 - 允許其他應用程式與代理對話的變數必須位於其環境中。由於桌面會話中的所有應用程式都是由桌面環境的某些部分(假設它是會話管理器)以某種方式產生的,因此您首先需要將變數放入會話管理器的環境列表中。這可以透過兩種方式發生:

  1. 會話管理器在內部執行此操作(取決於您在某處設定的某些選項)。這將包括由 PAM 模組產生的代理程式(從登入/會話管理器呼叫)。

  2. 透過像您這樣的用戶腳本。然而,這並不像看起來那麼簡單。當會話管理器運行您的腳本時,它會建立一個新進程 - 腳本解釋器。在其環境中設定變量,但不能輕鬆匯出回會話管理器(其父進程)。這相當於在 shell 中執行相同的操作 - 運行腳本不會對目前 shell 的環境產生任何影響。您必須source這樣做 - 然後命令將由當前 shell 執行,從而使您可以存取更新/建立的變數。在會話管理器中執行此操作會相當複雜(因為它不是 shell 解釋器)。因此你ssh-agent並沒有真正競爭。它只是坐在那裡,從你的腳本載入身份ssh-add,沒有人真正知道它。

要了解發生了什麼,請檢查1的輸出

ps fax | grep -E "(ssh|gpg)-[a]gent"

並將你的腳本更改為

echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" > ~/ssh-agent.stdout
echo "SSH_AGENT_PID=$SSH_AGENT_PID" >> ~/ssh-agent.stdout
eval `ssh-agent | tee -a ~/ssh-agent.stdout`

這會將變數的內容列印到文件中~/ssh-agent.stdout,然後在處理之前添加該位置的輸出ssh-agent(從而導出變數)。將檔案內容與環境變數進行比較SSH_AUTH_SOCKSSH_AGENT_PID例如在新建立的 shell 終端中。在大多數情況下,您將能夠分辨哪個是先啟動的,因為 PID 是(循環)單調成長的。之所以存在該部分,是因為某些 DE也使用提供 SSH 代理服務gpg-agent的能力。gpg-agent

您也可以ssh-agent完全刪除該行呼叫 - 如果您的腳本在 SSH 代理程式產生桌面環境後執行,您將看到密碼對話方塊(順便說一下,對於正確的代理),因為環境變數將存在。如果沒有,則表示您的腳本在 DE 的代理實例之前運行,因此根本無法存取任何代理程式。


1括號是巧妙的技巧grep從進程列表中刪除自身。

相關內容