用 VS Code Remote - SSH 連到 GCP VM:金鑰、主機設定與排錯

這篇保留 2020 年以 VS Code Remote - SSH 連到 GCP Compute Engine 的操作紀錄,並補上目前容易踩到的兩個差異:GCP VM 可能使用 OS Login,而 VS Code 應先以終端機的 SSH 連線成功為前提。不要一開始就從編輯器嘗試連線,因為那會把帳號、金鑰、網路與 VS Code Server 的問題混在一起。

1. 建立並保護 SSH 金鑰

舊筆記使用 ssh-keygen 產生預設的 id_rsa。新環境建議明確指定演算法與檔名,避免覆蓋既有金鑰:

ssh-keygen -t ed25519 -f ~/.ssh/gcp-dev -C "gcp-dev"

產生後會有私鑰 ~/.ssh/gcp-dev 與公鑰 ~/.ssh/gcp-dev.pub。私鑰只留在自己的電腦,不能貼進 GCP Console、Git 或聊天室;公鑰才是要登錄到 VM 的內容。若私鑰權限過寬,OpenSSH 會拒絕使用它:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/gcp-dev
終端機產生的 SSH 公鑰與私鑰檔案
產生後應只把 .pub 公鑰交給遠端系統;私鑰保留在本機。

2. 確認 GCP 使用的是哪一種 SSH 管理方式

若 VM 使用 metadata 型 SSH key,可在該 VM 的 SSH Keys 設定加入公鑰。下圖是舊版 Console 的操作位置;目前介面可能不同,但原則相同。

在 GCP Compute Engine VM 設定中加入 SSH 公鑰
GCP VM 的 SSH 公鑰設定畫面(舊版介面)。

不過,若 VM 啟用了 OS Login,Guest Agent 會忽略寫在 metadata 的金鑰。這是出現 Permission denied (publickey) 時最容易漏掉的一點:先確認 VM 是否採用 OS Login,再依 IAM 權限設定登入,不要同時猜測 metadata 和本機金鑰兩邊。

3. 先用終端機連線

在把設定交給 VS Code 前,先用同一把私鑰測試:

ssh -i ~/.ssh/gcp-dev your-user@VM_EXTERNAL_IP

若這一步成功,表示使用者名稱、網路路徑與金鑰都正確。失敗時加上 -v 查看客戶端選了哪一把 key:

ssh -v -i ~/.ssh/gcp-dev your-user@VM_EXTERNAL_IP

不要把完整除錯輸出公開,其中可能含有帳號、主機名稱與本機檔案路徑。若是防火牆或公司網路限制,應由 VM 的網路規則和來源 IP 範圍處理,而非為了測試把 SSH 對所有來源長期開放。

4. 用 SSH config 交給 VS Code

終端機測通後,在本機 ~/.ssh/config 建立一個容易辨識的主機別名:

Host gcp-dev
    HostName VM_EXTERNAL_IP
    User your-user
    IdentityFile ~/.ssh/gcp-dev
    IdentitiesOnly yes

安裝 VS Code 的 Remote - SSH 擴充功能後,從 Command Palette 選擇 Remote-SSH: Connect to Host…,再選 gcp-dev。第一次連線會在遠端主機安裝 VS Code Server;連上後再開啟專案資料夾,而不是只停在空白視窗。

VS Code Remote SSH 使用使用者名稱與 GCP 外部 IP 建立連線
舊版 VS Code 的連線示意;現在建議直接選擇 SSH config 中的別名。

Permission denied 的檢查順序

  1. 先確認 ssh -i ... 在終端機是否能連線。
  2. 確認使用者名稱正確;GCP 的登入帳號不一定等於本機 macOS 帳號。
  3. 確認 VS Code 使用的 IdentityFile 與終端機測試的是同一把私鑰。
  4. 確認 VM 的 OS Login 狀態與 IAM 權限,或 metadata 中的公鑰是否已正確儲存。
  5. 在 VS Code 的 Remote - SSH Output 查看詳細紀錄;若終端機尚未成功,不要把問題歸咎於擴充功能。

參考資料

Author image
關於 Richard Zheng
About me 喜歡爬山,瑜伽,溜冰,喜歡新奇的事,最喜歡的還是寫程式帶來的成就感,對於資訊會不斷的出現新事物也能抱持好奇與熱忱。近期開始將學習的心得寫在Blog,發現思路更清晰也加深了記憶。 紙上得來終覺淺,絕知此事要躬行