同一台電腦設定不同 SSH keys 連線多個 Github/GitLab 帳號
最近在收到了公司配的新電腦,由於新電腦不管是蓄電還是性能都比我自己的舊筆電好滿多的,因此最近去咖啡廳都比較喜歡帶公司的電腦出門。這台電腦目前已經設置好連線公司 GitLab 的 SSH Key,但最近越來越常用這台電腦後開始需要用這台電腦連上自己的 github 帳號來操作自己的 repo,之前我還沒有遇過一台電腦要在兩個以上的 Github/GitLab 帳號開發的經驗,因此查了一些文章並且記錄我做的設定。
關於使用 Secure Shell Protocol (SSH) 連線 Github 的相關知識,我非常建議去閱讀 Github 官方的 Connecting to GitHub with SSH 系列文章,我的設定與資料來源主要也是參考此系列文,GitLab 用戶則可以參考這篇 Use SSH keys to communicate with GitLab
關於 SSH
SSH(Secure Shell Protocol)是一種加密的網絡通信協議,它可讓我們的個人電腦安全地連接到遠程伺服器,並將訊息加密過後再傳送,確保只有知道解密規則的人才可以取得訊息。我們的 Github/Gitlab repo 實際上就是遠程伺服器上的一個資料夾,SSH 在這裡的作用就是幫我們的電腦與 Github/Gitlab 伺服器之間安全地建立通信連接,其中包括了身份驗證、安全地資料傳輸、訪問權限控制等工作。使用 SSH 金鑰,我們每次連線 Github/GitLab 以及推送 commit 時就不需重複提供用戶名稱和 token,簡單來說, SSH 對於個人電腦和 Github/GitLab 帳戶來說是一種安全且方便的和認證與資料傳輸方式。
SSH 在 Github/GitLab 如何運作?
關於 SSH 的基本工作原理以及公鑰、私鑰的用途在本篇就不多做贅述。那麽我們是怎麼透過 ssh 與 Github/GitLab 連線驗證身份與加密訊息的呢? SSH 有兩種身份驗證的方式,一種是密碼驗證,一種是金鑰驗證。Github 與 GitLab 使用的都是金鑰驗證。
金鑰驗證的工作原理很簡單,就是讓用戶在電腦上產生兩把鑰匙,一把是只有自己才知道的私鑰
,另一把是外界(要連線的伺服器)的公鑰
。首先讓用戶將公鑰
上傳到 Github/GitLab 主機上。當我們要與伺服器端連線時,會依照下列步驟完成 ssh 身份驗證並建立連線,以下以客戶端代稱使用者,伺服器端代稱 Github/GitLab 主機:
- 客戶端向伺服器端提出連線登入請求
- 伺服器端向客戶端發送一段隨機字符串
- 客戶端用自己的密鑰將隨機字符串加密成數位簽章
- 伺服器端拿客戶存放在伺服器端的公鑰檢驗數位簽章是否正確,如果簽章正確,伺服器就認為使用者登入成功。
產生 SSH Keys
確認已存在的 SSH Keys
如果我們的電腦中有可用的 SSH 密鑰,可以直接使用該密鑰設置 Github/GitLab 的 SSH 連線,但通常是建議替不同的連線建立不同的 SSH Keys,這麼做會比較方便管理自己的連線,當我日後決定不再使用 SSH 連線自己的 Github 帳戶,我只需要刪除用來連線 Github 的 SSH key 就可以了,同時也可以避免刪除某個密鑰造成非預期的連線失效。
- 查看
.ssh
資料夾中既存的 SSH Keys
# Lists the files in your .ssh directory, if they exist
ls -al ~/.ssh
- 默認情況下,GitHub 支持的公鑰文件名是以下之一
- id_rsa.pub
- id_ecdsa.pub
- id_ed25519.pub
- 默認情況下,GitLab 支持的公鑰文件名是以下之一
- id_rsa.pub
- id_dsa.pub
- id_ecdsa.pub
- id_ed25519.pub
- id_ed25519_sk.pub
- id_ecdsa_sk.pub
分別產生個人帳戶與公司的 SSH Keys
貼上下面的指令,替換為自己的 GitHub/GitLab 電子郵件地址,這會創建一個新的 SSH 密鑰,並且使用提供的電子郵件作為標籤。
$ ssh-keygen -t ed25519 -C "your_email@example.com"
接著,命令行會詢問我們要把新產生的 SSH Key pair 放在哪裡,如果直接按 Enter 的話它會把原本存在的 SSH Key 覆蓋掉,因此一定要填寫,建議填寫絕對路徑。取檔名時可以取方便辨識的名稱,像是: id_ed25519_personal
/ id_ed25519_company
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/XXX/.ssh/id_ed25519): /Users/XXX/.ssh/id_ed25519_personal
接著命令行會繼續詢問這組 Key 需不需要密碼,如果之後連線不想打密碼的話直接按 Enter 留空就可以了
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
產生成功後就會出現這樣的訊息,這麼一來 SSH Key 就算產生成功了:
Your identification has been saved in /Users/XXX/.ssh/id_ed25519_personal
Your public key has been saved in /Users/XXX/.ssh/id_ed25519_personal.pub
The key fingerprint is:
...
SSH 設定
添加 SSH 公鑰到 Github/GitLab 帳戶設定
首先我們要先把剛剛產生的 SSH 公鑰添加到 Github/GitLab 帳戶 SSH 設定中,id_ed25519_personal.pub
就是我剛剛產生用來連線個人 github 的 ssh 公鑰,id_ed25519_company.pub
則是我剛剛產生用來連線公司 gitlab 的 ssh 公鑰
# 複製用於連線個人 github 的公鑰到 github SSH keys 設定區
cat ~/.ssh/id_ed25519_personal.pub
# 複製用於連線公司 gitlab 的公鑰到 gitlab SSH keys 設定區
cat ~/.ssh/id_ed25519_company.pub
設定 ~/.ssh/config
要讓 SSH 使用非預設名稱的 SSH 私鑰文件,我們需要在 SSH 配置文件(~/.ssh/config) 中明確指定要使用的私鑰文件的路徑,以及不同的連線主機要用的連線設定
- 首先查看
~/.ssh
有沒有一個config
檔案,如果沒有就自己建立一個空的檔案。接著分別設置公司 GitLab 帳戶與個人 Github 帳戶連線的設定:
Host gitlab.company
HostName <公司主機ip>
User git
Port <port號>
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_ed25519_company
Host github.personal
HostName github.com
User git
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_ed25519_personal
- 選項解釋
Host | 連線至遠端的別稱(可以取自己喜歡的名稱) |
---|---|
HostName | 遠端的 Domain 或 IP |
Port | 遠端的 SSH 連接埠(為預設 22 的話可以不填) |
User | SSH 連接的用戶名,若用 git 且沒有設定 IdentityFile ,則 git 會使用默認名稱為 id_rsa 的 SSH 私鑰文件 |
PreferredAuthentications | 偏好使用的驗證(這邊的值都為 publickey) |
IdentityFile | 指定使用的私鑰位置(可為相對或絕對位置,但建議使用絕對位置) |
將 Key 加入 ssh-agent
控管
ssh-agent
是一個控制 SSH 金鑰的代理程式。當連線到 SSH 伺服器時,伺服器會要求我們提供與帳戶相關聯的 SSH 金鑰。如果將 SSH 金鑰加入 ssh-agent 中,ssh-agent 會在我們第一次使用 SSH 金鑰時,要求輸入密碼,然後將 SSH 金鑰保留在記憶體中。這樣,當我們連線到其他 SSH 伺服器時,ssh-agent 會自動提供相關的 SSH 金鑰,而無需再次輸入密碼。
但由於我已經手動配置配置 ~/.ssh/config
了因此即便沒有將 SSH Keys 加入 ssh-agent ,不同的 SSH 連線仍然可以自動找到相關的私鑰來驗證,因此我就沒有設置 ssh-agent 了。