如果要從 Host 主機連入 Multipass 建立的 Ubuntu VM,其實只要執行 multipass shell microk8s-vm
就可以進入了,完全也不用輸入密碼。不過,透過 multipass shell
無法使用 Port forwarding (埠號轉送),沒辦法把我在 Ubuntu 底下的 Ports 轉送到我的 Windows 本機。我原本以為這件事不難,結果卻卡關了一下,這篇文章我就來說說解法。
理解 multipass shell 登入 VM 的原理
為什麼我們可以用這麼簡單的命令登入 Linux 呢?
multipass shell microk8s-vm
想也知道他背後肯定使用了 SSH 金鑰來連線,但重點是文件沒寫這份金鑰在哪裡啊?我是從 GitHub Issue #309 找到的,不過這份 Issue 講的是 macOS 的路徑,沒說 Windows 路徑在哪!
sudo ssh \
-i /var/root/Library/Application\ Support/multipassd/ssh-key/id_rsa \
-L 9000:localhost:80 \
multipass@<multipass instance ip>
我有找到!就在這裡:
C:\ProgramData\Multipass\data\ssh-keys\id_rsa
所以理論上,我們可以這樣登入 VM:
ssh -i C:\ProgramData\Multipass\data\ssh-keys\id_rsa ubuntu@192.168.1.14
結果卻遇到以下問題:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions for 'C:\\ProgramData\\Multipass\\data\\ssh-keys\\id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "C:\\ProgramData\\Multipass\\data\\ssh-keys\\id_rsa": bad permissions
multipass@192.168.1.14: Permission denied (publickey).
簡單來說,就是 ssh
要求用金鑰認證的人,其「私密金鑰」的權限不能太開放,否則會不安全,所以你必須把「其他人可以閱讀」的權限移除,才能使用這把金鑰登入遠端主機。
調整 SSH 私密金鑰的 NTFS 權限
你可以參考以下步驟進行 NTFS 權限調整:
-
先查詢現有檔案權限
icacls C:\ProgramData\Multipass\data\ssh-keys\id_rsa
從回應結果可以發現,原來這個檔案被賦予了 BUILTIN\Users
可讀、可執行的權限(RX
),那是因為這個檔案的 NTFS 權限是自動從上層目錄繼承來的(I
)!
C:\ProgramData\Multipass\data\ssh-keys\id_rsa NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Users:(I)(RX)
Successfully processed 1 files; Failed processing 0 files
-
先賦予自己擁有完整權限,並同時移除權限繼承
請以系統管理員身份啟動 Windows PowerShell 並執行以下命令:
icacls C:\ProgramData\Multipass\data\ssh-keys\id_rsa /inheritance:r /grant "$(whoami):F" /grant "NT AUTHORITY\SYSTEM:F"
這裡 /inheritance:r
是「移除繼承」的意思,若寫 /inheritance:e
則代表「啟用繼承」的意思。另外,這裡 /grant
是授權的意思,命令中出現了兩次,那是因為我們移除了繼承權限後,需要同時授權給兩個帳戶,一個是自己 ($(whoami)
),也就是目前登入者的身分,另一個是系統帳戶 SYSTEM
,而 :F
則是賦予「完整權限」的意思。
-
此時金鑰的 NTFS 權限就被現縮到很小了,而且可以成功連接 Linux VM
icacls C:\ProgramData\Multipass\data\ssh-keys\id_rsa
C:\ProgramData\Multipass\data\ssh-keys\id_rsa NT AUTHORITY\SYSTEM:(F)
WILLSUPERPC\user:(F)
Successfully processed 1 files; Failed processing 0 files
你也可以用 PowerShell 的 Get-Acl
查看 ACL 資訊:
PS> Get-Acl C:\ProgramData\Multipass\data\ssh-keys\id_rsa | fl
Path : Microsoft.PowerShell.Core\FileSystem::C:\ProgramData\Multipass\data\ssh-keys\id_rsa
Owner : BUILTIN\Administrators
Group : NT AUTHORITY\SYSTEM
Access : NT AUTHORITY\SYSTEM Allow FullControl
WILLSUPERPC\user Allow FullControl
Audit :
Sddl : O:BAG:SYD:PAI(A;;FA;;;SY)(A;;FA;;;S-1-5-21-1610181907-3261981930-2611305422-1003)
測試連線成功!
ssh -i C:\ProgramData\Multipass\data\ssh-keys\id_rsa ubuntu@192.168.1.14
使用 SSH 的 Port forwarding 轉送埠號
-
我先在 microk8s-vm
執行以下命令
microk8s dashboard-proxy
此時會在 Linux VM 內監聽 127.0.0.1:10443
這個 PORT
-
另開一個 Terminal 視窗,透過以下命令連入 VM,並搭配 -L {localport}:{host}:{hostport}
參數進行埠號轉送
ssh -i C:\ProgramData\Multipass\data\ssh-keys\id_rsa -L 8443:localhost:10443 -N ubuntu@192.168.1.14
這裡的 -N
代表「不登入」的意思,單純用來建立 Port forwarding 而已。
接著你就可以在 Windows 本機輸入 https://127.0.0.1:8443/ 連入網站了!👍
相關連結