WSL 與 Windows 共用 SSH 金鑰登入遠端主機
| | 1 | | ![]() |
需求情境如下:我在 Windows 產生了 SSH 金鑰用來免密碼登入多台遠端 Linux 主機(延伸閱讀:從 Windows 使用金鑰免密碼登入 SSH/SFTP/SCP),在同台主機的 WSL (註:Windows 內建的 Linux 子系統,不需裝 VM 或設雙重開機就可以跑 Linux)我想用同一把 SSH 金鑰直接登入前述的多台遠端 Linux 主機,省下為 WSL 另建一把金鑰並逐台主機增設的工程。
先釐清狀況。
Windows 與 WSL 的 ssh 程式採用相同檔案挸格(known_hosts、config、公私鑰檔),共用不是問題,但二者各有自己的 .ssh 資料夾,Windows 在 C:\Users\<userName>\.ssh
,而 WSL 在 ~\.ssh
,相當於 \\wsl$\Ubuntu\home\<userName>\.ssh
。(延伸閱讀:何用 Windows 檔案總管瀏覽 WSL 的資料夾)。
搞清楚這點問題就單純了,無腦做法是把檔案 Copy 過去,再調權限即可。基於安全,.ssh 目錄及金鑰檔案必須設成只有擁有者可以存取,設定方式如下:(假設只有一把 Ed25519 金鑰,其餘類推) 延伸閱讀:數位簽章知識補充包 - ECC 橢圓曲線密碼學、Ed25519、Curve 25519
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
但這做法有個缺點,每當金鑰異動或 Windows 連過新主機 known_hosts 清單有新增,需手動同步才會更新。
一個簡單個解法是用 ln -s /mnt/c/Users/<userName>/.ssh ~/.ssh
建 Symbol Link 將 WSL 的 ~\.ssh
目錄指向 C:\Users\<userName>\.ssh
(若 ~/.ssh 已存在,可將資料合併到 Windows 端後刪除目錄),如此可實現二者共用一組檔案,做到完全同步。
但這個有小眉角:「WSL 預設無法用 chmod 修改 Windows 檔案系統物件的」。解法是在 WSL /etc/wsl.conf
設定加入如下內容:
[automount]
options = "metadata"
這會讓 WSL 在 自動掛載 Windows C: 槽(/mnt/c
) 時啟用 metadata 選項,在 NTFS 擴充屬性 $LXUID、$LXGID、$LXMOD 保存 Linux 端的擁有者、群組及讀寫權限設定,以支援 LINUX 端的群組及權限設定。
設完用 wsl --shutdown
重啟 WSL,之後才能正常用 chmod 改權限。~/.ssh
由於是 Symbol Link,故 chmod 時對象要換 成 /mnt/c/Users/<userName>/.ssh
,而除了金鑰檔,實測 config、known_hosts 也都要改成限擁有者讀寫才能正常使用。我的設定操作指令如下:
chmod 700 /mnt/c/Users/<userName>/.ssh
cd ~/.ssh
chmod 600 id_ed25519
chmod 644 id_ed25519.pub
chmod 600 config
chomd 600 known_hosts
完成後,ssh <remote_host>
連上先前設好金鑰登入的主機時,就會改用金鑰登入了。
之後我發現 WSL 預設不會啟動 ssh-agent,可用以下方式手工啟動或把它加進 .bashrc
每次登入自動執行:
# 執行 ssh-agent,其輸出給果是一段環境變數指令
eval `ssh-agent`
# 檢查環境變數,若傳回數字表成功
echo $SSH_AGENT_ID
若不想每次輸入金鑰密碼,可使用指令 ssh-add id_ed25519
,輸一次密碼將金鑰交給 ssh-agent 存入記憶體,之後使用金鑰時就不需再敲密碼。由於 Linux 的 ssh-agent 是登入後啟動且金鑰是存在記憶體,登出後便會失效。故每次登入都要重跑 ssh-add
讀取金鑰存入記憶體,跟 Windows 用 DAPI 加密存在 Registry做法不同,且私鑰必須留在 .ssh 目錄,相較之下感覺 Windows 的做法更安全一點。
我還找到一些其他做法,例如用 keychain 管理 ssh-agent 省去每次登入重敲金鑰密碼(參考:Sharing SSH keys between Windows and WSL 2)、透過 npiperelay 讓 WSL 直接連 Windows 的 ssh-agent 服務(參考:Setting up shared SSH key agent between Windows 11 and WSL2),或是靠 SSH Agent Forwarding 先 SSH 登 WSL 再拿 Windows 的 ssh-agent 金鑰連出去,後面兩種做法檔案系統不需要放私鑰檔,更安全但部署或使用上較複雜,這裡先做個筆記,待未來有需要再研究。
The post details how to share SSH keys between Windows and WSL for passwordless logins to Linux hosts. It covers copying files, using symbolic links, setting up permissions, and configuring ssh-agent for convenience. Advanced methods include using keychain, npiperelay, and SSH Agent Forwarding for enhanced security.
Comments
# by yoyo
Linux無Registry機制,所有config都是存成檔案 "Everything is a file"