最近更新: 2023-11-01

SSH金鑰連線與多帳號管理。如何維護多個GitHub帳號的源碼庫

說到 SSH 多組金鑰與帳號管理的需求,我會從 GitHub Desktop 說起。

GitHub Desktop 是個很好用的 git GUI 工具,缺點是它設計上只會記一個 GitHub 帳號。 若你有好幾個 GitHub 帳號,照 GitHub Desktop 設計的操作邏輯,你要重複登出登入切換帳號。 但我們其實可以利用 SSH 金鑰管理機制,直接存取不同帳號的源碼庫。

此外,如果你有申請多家雲端服務商,而他們支援 SSH 連線的話,也是用同一套機制管理多個帳號。

本文分兩章。第一章說明 SSH 金鑰基本操作。第二章說明管理多組金鑰的方式。

  1. 建立一組金鑰
  2. 管理多組金鑰

別管Sign in了

取得工具

SSH 工具基本就是 OpenSSH 這一家。 Linux 現在是必裝套件。而 Windows 10/11 也有,只是需要使用者啟用。

Windows 10/11: 開始功能表 -> 設定 -> 應用程式 -> 應用程式與功能 -> 選用功能。

Windows選用功能

Windows新增OpenSSH客戶端

建立一組金鑰

金鑰建立指令:

$ ssh-keygen -t rsa -b 2048 -C comment -f keyname
  • -t 指定加密格式。rsa 是目前常見的加密格式。
  • -b 指定金鑰位元數。NIST建議 RSA 最小長度為 2048
  • -C 金鑰註解。可用任何文字,方便識別這個金鑰是誰建的。通常會寫電子郵件地址。
  • -f 金鑰檔案名稱。通常省略這個參數,可以日後再改名。

這個指令會產生兩個檔案。主檔名是 -f 指定的金鑰檔案名稱。沒有副檔名的是私鑰。有副檔名 .pub 的是公鑰。

按日常生活用語,應該說是一組配對的鑰匙和鎖頭。私鑰是鑰匙,而公鑰是鎖頭。 向初學者介紹 SSH 時,他們總會搞混私鑰和公鑰。反而一說鑰匙和鎖頭就分清楚了。 只是日常生活是好幾把鑰匙配一個鎖頭。而 SSH 金鑰是一把鑰匙配好幾個鎖頭。

沒有指定 -f 參數時,預設私鑰檔案名稱是 id_rsa,公鑰檔案名稱是 id_rsa.pub。 如果你需要建好幾組金鑰,就要分別為金鑰指定不同名稱。 或者建立金鑰後直接改檔名也行。

私鑰 (id_rsa) 總是留在自己的電腦上,不要外洩。那麼公鑰 (id_rsa.pub) 就是要放出去給別人收著。 按日常生活經驗,鑰匙 (私鑰) 當然是貼身收好。而鎖頭 (公鑰) 則是拿出去鎖外面的個人財產。

私鑰的保管處,預設是家目錄下的 .ssh 子目錄。

  • Linux/BSD 家族系統: ~/.ssh。
  • Windows 10/11: C:\Users\%USERNAME%\.ssh。

本文不分系統一律以 ~/.ssh 表示。

公鑰檔案是純文字文件。內容就是一行三段英文字母和數字。如下:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9fC5qmWpznkXZzMV xxx@192.168.0.99

第一段是金鑰加密格式。 第二段是公鑰內容。 第三段看起來像電子郵件地址的內容,就是你建金錀時輸入的註解。 收到公鑰的人可以改成自己方便辨別的文字。

公鑰 (鎖頭) 可以複製很多份,用來保管多份在外的個人財產。 既然公鑰只是一個純文字檔案,那複製到遠端主機的方式,可以選擇直接傳輸檔案, 也可以把公鑰內容貼在電子郵件的內文寄送。

收到公鑰的人,則需要把公鑰的內容存在 ~/.ssh/authorized_keys 檔案。 authorized_keys 檔案就是公鑰集中保管庫。 儲存方式是用文字編輯器打開公鑰檔案,全選內容複製起來。 然後用文字編輯器打開 ~/.ssh/authorized_keys ,增加新行,把剛才複製的文字內容貼上,儲存。

當然用指令更快:

$ cat id_rsa.pub >>  ~/.ssh/authorized_keys

到此完成金鑰建立與散佈。試著用 ssh 連線遠端主機吧。 如果連線時要你輸入密碼,那就是金鑰設定錯了。 也許你沒把私鑰放在 ~/.ssh,或者對方沒把你的公鑰存進 ~/.ssh/authorized_keys

步驟整理如下:

  1. 建立一組金鑰 (id_rsa / id_rsa.pub)。
  2. 私鑰檔案保管在自己的 ~/.ssh 目錄 (本機 ~/.ssh)。
  3. 複製公鑰內容 (id_rsa.pub) 給對方。
  4. 對方將公鑰內容存入他的公鑰保管庫 (遠端 ~/.ssh/authorized_keys)。
  5. 你現在可以用 ssh 連線遠端主機了。 表面上是不問身份和密碼,實際上是 ssh 直接拿私鑰和遠端公鑰配對證明身份。

雲端服務商不會幫你儲存公鑰,你要自己登入網站處理。 附上一些雲端服務商的公鑰操作說明:

管理多組金鑰

你可以用一組金鑰負責你所有的遠端主機帳號。但也可以每個遠端主機各配一組金鑰。 若你有好幾組金鑰,那麼 ssh 要如何決定拿哪一個私鑰和遠端通訊?

ssh 是在 ~/.ssh/config 這個檔案中組織私鑰和主機使用關係。 沒有你電腦中 ~/.ssh/config 的話,就從建一個空白檔案開始。

每一個遠端主機帳號,都可以設一組使用關係。 格式是:

Host 識別名稱
    HostName        遠端主機的網域名稱或IP
    User            遠端帳號名稱
    IdentityFile    這組合使用的私鑰的檔案路徑

以我在 GitHub 的使用狀況為例。我有兩個 GitHub 帳號,各用一組金鑰。 使用關係是:

  • rocksaying 帳號 : 帳號私鑰 /home/rock/.ssh/id_rsa_key1
  • rocksource 帳號 : 帳號私鑰 /home/rock/.ssh/id_rsa_key2

我在 ~/.ssh/config 就寫兩筆設定:

Host rocksaying@github
    HostName    github.com
    User        git
    IdentityFile /home/rock/.ssh/id_rsa_key1

Host github上的rocksource
    HostName    github.com
    User        git
    IdentityFile /home/rock/.ssh/id_rsa_key2

這裡示範 Host 的名稱可以自由取名,所以用了不同的命名風格。

注意,ssh 存取 GitHub 源碼庫時,使用者連線名稱一律是 git。

ssh 指令連線的主機名稱,首先是找 ~/.ssh/config 設定的 Host 識別名稱。 若 ~/.ssh/config 找不到符合的名稱,才會當作真實的網域名稱。

例如我要存取 rocksource 帳號的源碼庫內容,而這個帳號在 ~/.ssh/config 寫的識別名稱是「github上的rocksource」,那麼我的 git 指令用的 SSH URL 會是:

$ git clone git@github上的rocksource:shirock/rocksources.git

ssh 先根據「github上的rocksource」這個識別名稱 (Host),在 ~/.ssh/config 找到組合項目。 然後知道這組的真實連線位址 (HostName) 是 github.com,帳號登入名稱 (User) 是 git, 使用私鑰 (IdentityFile) 是 /home/rock/.ssh/id_rsa_key2 。

透過 SSH 本身的金鑰管理機制,使用者就可以在 GitHub Desktop 程式中同時維護好幾個帳號的源碼庫,而不必切換帳號。 其他雲端服務商也是同理。