SSH:通往另一台電腦的隧道
SSH 是你手上這台裝置和另一台電腦之間的加密通道:你打的字送過去,那台機器執行,印出來的文字帶回來,中間經過的每一個節點都看不懂內容。要在手機上跑 agent,SSH 就是手機連到「agent 實際運行的那台機器」的那條路。
上一篇的結論是:agent 在終端機裡最能做事,因為它能讀整個檔案系統,也能真的執行指令。那個終端機不必在你口袋裡。它可以是家裡那台從來沒關過的 Mac mini,也可以是公司那台工作站,只要你的手機連得過去。
為什麼是另一台機器,不是雲端服務?
網頁版 agent 和雲端 IDE 也會讓你連上一台機器。差別在那台機器是誰的。
SSH 連的是你自己那台。檔案在那裡,API key 在那裡,你裝過的套件和設好的環境變數也都在那裡。不用把任何東西搬到別人的伺服器上,改動留在原地,事後不必再同步回來。
反過來也有取捨。如果你沒有任何一台一直開著的機器,或是一整組人需要完全相同的起點,雲端環境是比較好的答案。換用自己的機器,代價是:它要一直開著、要連得到,而且設定由你負責。
連線要打的只有三樣東西:host、user、port
每一次 SSH 連線都需要三個東西,指令把它們寫在同一行:
ssh -p 22 sax@mac-mini
| 部分 | 指的是什麼 |
|---|---|
| Host | 要連哪台機器:像 mac-mini 這種名稱,或 100.101.102.103 這種位址 |
| User | 那台機器上的哪個帳號。你拿到的是那個帳號的檔案、權限和 shell,不會再多 |
| Port | 那台機器上的哪扇門。SSH 預設是 22,所以這個欄位通常留空 |
卡住的人多數卡在第一項和第三項。host 必須是手機真的路由得到的位址,下一節就在講這件事。user 則必須真的存在於那台機器上:agent 以那個帳號執行,它能碰到的東西,剛好就是那個帳號能碰到的。
為什麼不用 LAN 位址,也不用公網 IP?
你第一個找到的位址在網路設定裡,長得像 192.168.1.23。先從同一個 Wi-Fi 下的筆電試它,那正是它的用途。但它是路由器發出的私網位址,只在你自己的網路裡有效。手機切換到行動數據就沒有路能走到它,別人的網路也沒有。
第二種是家裡網路對外顯示的公網位址,再在路由器上做 port forwarding,把那個 port 指到這台機器。這條路走得通,也是要避開的那一條。掃段的機器人對全世界的位址全天候嘗試登入,一個對外開放的 port 一天之內就會開始累積登入嘗試。路由器的設定只要有一處錯了,暴露出去的是整個網路,不是一台機器。
該用的是第三種位址:只有你自己的裝置看得見的私網位址。Tailscale 會給每台機器一個 MagicDNS 名稱或一個 100.x 位址,公網上沒有別人知道它們存在。host 欄位就填這個,在家和在外都一樣。
金鑰比較安全,也更省事
SSH 收密碼,也收金鑰。這件事常被講成安全和方便之間的取捨,但金鑰兩邊都贏。
一對金鑰就是兩個小小的文字檔。私鑰留在會發起連線的那台裝置上。公鑰由私鑰算出來,複製到你要連的那台機器,放進那個帳號 ~/.ssh 裡的 authorized_keys。這條運算只有單向:公鑰從私鑰推得出來,反過來做不到。ssh-keygen 幾秒就產生一對,剩下的都是複製貼上。
登入時兩半互相證明配對,你一個字都不用打。密碼必須扛得住別人反覆猜,金鑰夠長,猜沒有用。設定一次,之後每一次連線都走同一套流程。
私鑰最好加 passphrase(金鑰口令),因為金鑰就是一個檔案。從一台沒鎖的筆電上把它複製走,別人就握有你的金鑰。加了口令,那個檔案沒有口令就毫無價值,而且口令跟帳號密碼不同:它從不過網路,只在本地解鎖金鑰。真正傳出去的,是對一個挑戰簽好的短答案。
在手機上,這個差別更重要。打出來的密碼每一次連線都要走過線路,任何摸得到那個 port 的人都多一次猜的機會。金鑰則是回答一個挑戰,金鑰本身從不離開你的裝置。如果金鑰都設好了還是被擋在外面,常見原因沒幾個:路徑錯、帳號錯、檔案權限錯。
App 把我的密碼和金鑰放在哪裡?
Agentmux 不收集任何個人資料。使用統計是匿名、可選的,關掉它不會改變連線的方式。密碼、金鑰和口令都放進作業系統的硬體級憑證儲存,不是一般檔案。你的 SSH 流量不會被記錄下來:那條通道在你的裝置和你的機器之間加密,App 本身不是中繼站。
第一次連線,為什麼要先問你信不信這組指紋?
連一台沒連過的機器時,在密碼或金鑰之前,你會先看到一行說無法確認主機真實性的訊息、一串十六進位字元,和一個 yes 或 no。那串字元是伺服器的指紋,也就是那台機器簽名用的 host key 濃縮出來的摘要。沒有出錯,這是 SSH 在驗證另一個方向。
密碼或金鑰證明的是「你對那台機器來說是誰」,host key 證明的是「那台機器對你來說是誰」。少了 host key 這半邊,任何一台站在你手機和家裡 Mac mini 之間的設備,都能冒充那台機器回答,把你送出去的每一個字讀走。第一次連線時你沒有存過的指紋可以比對,所以 client 請你先相信它,然後從那之後記住這個值。
這一步在之後才派上用場。重新連一台指紋變過的機器,client 會直接拒絕。要嘛是你重裝過系統,要嘛是有別的東西在代替它回答。
一定要把電腦架成伺服器嗎?
很多人聽到 SSH 就想到機房和機櫃。你要做的只是打開一個開關。Mac 上是「系統設定 → 一般 → 共享 → 遠端登入」,Linux 上通常是啟動一個叫 sshd 的服務,多數發行版預設就裝好了。
開關打開之後,那台機器什麼都沒變。它還是你平常那台電腦,只是多了一扇可以從外面敲的門。不想記住順序的話,設定頁會問你三個問題,再依你的情況列出一張清單。
SSH 不是 VPN,也不是遠端桌面
SSH 不做下面三件事:
| 它不是 | 那樣的話會是什麼 | SSH 實際做什麼 |
|---|---|---|
| VPN | 你手機送出的所有流量都走進家裡網路 | 一條通道連到一台機器上的一個 port,其他東西不會因此連得到 |
| 掛載的檔案系統 | 遠端的磁碟變成你能直接打開的資料夾 | 需要時才搬位元組:檔案瀏覽器得自己一個檔案一個檔案去抓、去傳 |
| 遠端桌面 | 你看到整個桌面畫面,用手指去點 | 雙向都是文字:送出去的是按鍵,回來的是印出的文字 |
最後一列是真的限制,不是這個工具的缺點。只存在於「一個可以點的視窗」裡的軟體,SSH 操作不了。上一篇畫的是同一條界線:會用文字對話的 agent,才塞得進這條隧道。
然後你把手機收起來,隧道斷了,agent 跟著死。除非那個 session 本來就不住在你的連線裡面,那就是 tmux 負責的事。