這裡介紹如何使用 ssh-agent 管理 SSH 登入認證用的金鑰,免除登入遠端伺服器要重複輸入密碼的麻煩。

資深的 Linux 伺服器的管理者最常使用的管理介面應該就是 SSH 安全加密的連線,而比較注重系統安全防護的人,甚至還會將 SSH 的密碼認證關掉,只留下 SSH 金鑰認證來登入,若沒有金鑰,連管理者自己也進不了系統,讓系統更安全。


伺服器登入用的金鑰通常也都會加上密碼保護,但是加上密碼的金鑰每次要使用時都要輸入一次解鎖密碼,以下介紹如何靠著 ssh-agent 這個小工具來管理金鑰,讓使用者只需要打一次密碼,就可以持續使用金鑰,甚至在遠端的伺服器上也可以使用。

啟動 ssh-agent

在大部分桌面環境的 Linux 系統中,預設都會自動啟動 ssh-agent,我們可以檢查 SSH_AUTH_SOCKSSH_AGENT_PID 這兩個環境變數是否有設定好,藉此判斷 ssh-agent 是否有啟動。

echo $SSH_AGENT_PID
1673
echo $SSH_AUTH_SOCK
/tmp/ssh-OIphRJeGIGMT/agent.1672

原則上只要這兩個環境變數有被設定好、不是空的,就表是 ssh-agent 已經啟動了,而如果這兩個變數都是空的,就要先進行 ssh-agent 的啟用設定或是手動啟動。

若在 Mac OS X 系統上,ssh-agent 啟動時可能只有 SSH_AUTH_SOCK 有被設定,不過不影響使用。

設定 X Window 自動啟動 ssh-agent

X Window 的 /etc/X11/Xsession.options 設定檔可以控制 Xsession 的一些啟動選項,其中有一項 use-ssh-agent 功能就是用來啟動 ssh-agent 用的,加入這個設定即可讓 X Window 在啟動時自動執行 ssh-agent,讓所有 X Window 下的的應用程式都可以直接使用 ssh-agent,這種作法是最常見、也是最方便的。

以下是樹莓派的 /etc/X11/Xsession.options 預設值,大部分的 Linux 發行版應該預設就會含有 use-ssh-agent 的設定,所以不需要特別做更改:

# $Id: Xsession.options 189 2005-06-11 00:04:27Z branden $
#
# configuration options for /etc/X11/Xsession
# See Xsession.options(5) for an explanation of the available options.
allow-failsafe
allow-user-resources
allow-user-xsession
use-ssh-agent
use-session-dbus

關於這個設定檔的各個選項說明,可以參考 Xsession.options(5) 的 man page。

man 5 Xsession.options

手動啟動 ssh-agent

若要手動啟動 ssh-agent,可以執行:

ssh-agent

在啟動 ssh-agent 之後,會輸出幾行設定環境變數的指令稿:

SSH_AUTH_SOCK=/tmp/ssh-OIphRJeGIGMT/agent.1672; export SSH_AUTH_SOCK;
SSH_AGENT_PID=1673; export SSH_AGENT_PID;
echo Agent pid 1673;

ssh 在登入主機時,就是靠著這些環境變數來跟 ssh-agent 取得認證金鑰的,將這幾行指令稿複製起來,貼在終端機中執行,即可將 ssh-agent 的環境設定好。

然而執行 ssh-agent,再用複製貼上的方式設定環境,手續比較繁雜,這兩個步驟可以用以下一行代替:

eval $(ssh-agent)

這是利用 bash 指令稿的語法,把 ssh-agent 的輸出取出來,交給 eval 直接執行,這樣既簡潔又快速。

加入 SSH 認證用金鑰

確認 ssh-agent 已經正常啟動之後,就可以執行 ssh-add 加入 SSH 登入認證用的金鑰:

ssh-add

如果 ssh-agent 沒有預先啟動的話,就會出現這樣的錯誤訊息:

Could not open a connection to your authentication agent.

若遇到這樣的狀況,請先依照上面的步驟設定或手動啟動 ssh-agent,接著再重新執行一次 ssh-add

如果自己的金鑰有設定保護密碼,則執行 ssh-add 時就要輸入一次密碼:

Enter passphrase for /home/pi/.ssh/id_rsa: 
Identity added: /home/pi/.ssh/id_rsa (/home/pi/.ssh/id_rsa)

這樣之後使用 SSH 以該金鑰登入主機時,就可不需要再輸入任何密碼了。

ssh seal@192.1168.0.1

SSH Agent Forwarding

如果我們需要以 SSH 連續登入好多台主機,從使用者端的電腦登入伺服器 A 時,可以直接使用使用者端的金鑰認證登入,但是若從伺服器 A 往後連線至伺服器 B 時,通常因為在伺服器 A 上沒有金鑰可以使用,所以就要以密碼的方式登入主機了。

SSH 遠端連線(LibreOffice 原始檔VRT 圖庫

另外若是後端的伺服器 B 只有開啟金鑰認證登入的話,從伺服器 A 上就會無法登入伺服器 B,只能回到使用者端再開一個連線至伺服器 B,如果又遇到防火牆問題,就更複雜了。

ssh-agent 有一個 forwarding 功能,它可以在不透過網路傳送金鑰的情況下,讓遠端的伺服器使用本地端的金鑰進行認證,金鑰本身只需要儲存一份在使用者端的電腦中,這樣既方便又安全,尤其是在有防火牆的環境下特別實用。

使用 SSH forwarding 的方式很簡單,只要使用 ssh-add 加入金鑰之後,在執行 ssh 時加入一個 -A 參數即可:

ssh -A seal@192.1168.0.1

這樣在連線至 192.1168.0.1 之後,再繼續往後端的伺服器連線時,就會自動透過 SSH 加密的通道,使用本機的金鑰進行遠端登入的認證。

若不想每次加入 -A 參數,也可以直接修改預設的 ~/.ssh/config 設定,加入 ForwardAgent yes

Host serverA
  HostName 192.168.0.1
  ForwardAgent yes

這樣也可以達到相同的效果。

參考資料:StackExchangeAWS Security BlogGitHub DeveloperUnixwiz.net