The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何透過 ssh 連入 Multipass 建立的 Ubuntu VM 並啟用 Port forwarding

如果要從 Host 主機連入 Multipass 建立的 Ubuntu VM,其實只要執行 multipass shell microk8s-vm 就可以進入了,完全也不用輸入密碼。不過,透過 multipass shell 無法使用 Port forwarding (埠號轉送),沒辦法把我在 Ubuntu 底下的 Ports 轉送到我的 Windows 本機。我原本以為這件事不難,結果卻卡關了一下,這篇文章我就來說說解法。

Multipass

理解 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).

Permissions for 'C:\ProgramData\Multipass\data\ssh-keys\id_rsa' are too open.

簡單來說,就是 ssh 要求用金鑰認證的人,其「私密金鑰」的權限不能太開放,否則會不安全,所以你必須把「其他人可以閱讀」的權限移除,才能使用這把金鑰登入遠端主機。

調整 SSH 私密金鑰的 NTFS 權限

你可以參考以下步驟進行 NTFS 權限調整:

  1. 先查詢現有檔案權限

    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
    
  2. 先賦予自己擁有完整權限,並同時移除權限繼承

    請以系統管理員身份啟動 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 則是賦予「完整權限」的意思。

  3. 此時金鑰的 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 轉送埠號

  1. 我先在 microk8s-vm 執行以下命令

    microk8s dashboard-proxy
    

    此時會在 Linux VM 內監聽 127.0.0.1:10443 這個 PORT

    image

  2. 另開一個 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/ 連入網站了!👍

相關連結