SSH Tunnel 三種方式備忘錄
最近要連某一台主機上的 Transmission 管理介面,Port 是 9091,但主機本身沒有直接對外開放這個 Port,所以最後還是得靠 SSH Tunnel 裡最常見的 Local Port Forwarding 來處理。
這個功能我以前就知道,只是通常久久才會用一次。每次要用的時候,又得重新想一次 -L、-R、-D 到底差在哪裡。既然這次剛好重新整理,就乾脆把重點記下來,之後自己複習也比較快。
文章重點心智圖
先理解前提
SSH Tunnel 的核心概念,其實就是透過一台可以 SSH 連線的主機,幫兩個原本無法直接互通的環境建立通道。
實務上你可以把它想成這樣:
- 你手上有一台可以連上的 SSH Server,通常是跳板機、遠端主機,或某台有對外開放 SSH 的機器。
- 你想存取的真正目標服務,可能只開在內網,或只綁在
localhost,外部碰不到。 - 這時就靠 SSH Tunnel 把流量從一端安全地轉到另一端。
-L、-R、-D 會輕鬆很多。三種方式常見情境
Local Port Forwarding:自己的電腦想連遠端內網服務。Remote Port Forwarding:想讓遠端主機反向連回自己這端的服務。Dynamic Port Forwarding:直接把 SSH 連線變成 SOCKS 代理來使用。
如果硬要一句話總結,這三種都是「透過 SSH,把原本不能直接連的流量轉過去」,差別只是 Port 開在哪一端、給誰用而已。
Local Port Forwarding
這是我自己最常用的一種。典型場景就是:我自己的電腦,想去連遠端機器上的某個服務,但那個服務沒有直接對外開放。
基本指令
|
|
我以前看到這個格式也常常頭很痛,後來比較容易記的方式是:
本機要開的 Port → 透過 SSH Server 幫你轉到哪個 host:port
我的使用範例
假設遠端主機有開 SSH Port 37022,而且 Transmission 只綁在遠端的 localhost:9091,那可以這樣下:
|
|
這時你在自己電腦打開瀏覽器,直接開 http://localhost:9091,就會連到遠端那台機器上的 Transmission 介面。
bind_address 代表什麼
上面的範例省略了 [bind_address:],等同只綁在本機 localhost,也就是只有你自己這台電腦能使用這個轉發 Port。
如果你真的想讓同網段其他機器也能透過你這台電腦使用,就可以明確指定 0.0.0.0:
|
|
0.0.0.0 代表你的本機會對外開一個可被其他人連到的 Port。除非你很清楚自己所在的網路環境與風險,不然一般情況只綁 localhost 就夠了。Remote Port Forwarding
Remote Port Forwarding 則是反過來,把你這一端的服務,暴露到遠端 SSH Server 那邊。
|
|
這裡最容易搞混的是:bind_address 指的是 SSH Server 那一端要綁定的位址,不是你本機。
常見情境
例如你本機有一個只開在 localhost:80 的測試網站,但你想讓遠端主機可以連回來看,就可以這樣做:
|
|
這代表你登入 192.168.50.212 後,在那台遠端主機上打 curl localhost:2121,就會連回你這台電腦的 localhost:80。
轉到其他主機也可以
<host>:<host_port> 不一定非得是你本機,也可以指定其他主機,例如:
|
|
這樣在遠端主機上執行:
|
|
就能拿到 tw.yahoo.com:80 的 HTML 內容。
要讓遠端其他人也能連,需要 GatewayPorts
基於安全考量,Remote Forwarding 預設通常只會綁在 SSH Server 的 localhost,所以單靠下面這種指令:
|
|
很多時候還是不會真的讓外部主機連進來。你還需要調整 SSH Server 上的 sshd_config,通常在 /etc/ssh/sshd_config,加入:
|
|
這個設定常見有三種:
no:預設值,只允許綁在localhost。yes:允許綁到萬用位址,例如0.0.0.0。clientspecified:讓 Client 自己決定要綁在哪個位址。
-R 臨時開洞。Dynamic Port Forwarding
Dynamic Port Forwarding 可以把 SSH 連線直接變成一個 SOCKS Proxy,這個在臨時代理流量時滿方便。
指令
|
|
如果只是單純開代理、不需要進互動式 shell,也可以加上 -N:
|
|
測試方式
|
|
如果兩次拿到的出口 IP 不同,就代表代理有正常生效。
瀏覽器設定重點
各家瀏覽器都能設代理,但這裡最重要的一點只有一個:要選 SOCKS 代理,不是一般的 HTTP 代理。
Firefox:
Windows 11 下的 Chrome、Edge 因為共用系統代理,設定時要特別注意 socks=127.0.0.1 這類格式。我當初找這個點卡了滿久,真的有點雷。
參考資料:How can I set socks proxy on windows? - Super User
設定好之後,可以直接打開 https://ifconfig.me 看出口 IP 有沒有變化。
三種方式快速比較
| 方式 | 典型用途 | Port 開在哪裡 | 我自己使用頻率 |
|---|---|---|---|
-L |
本機連遠端內網服務 | 本機 | 高 |
-R |
讓遠端反向連回本機或其他位置 | 遠端 SSH Server | 低 |
-D |
建立 SOCKS 代理 | 本機 | 中 |
我的看法
這三種方式,說穿了就是把兩個隔離環境,透過一台有 SSH 的中介主機串起來。
如果以我自己的實用度來排,大概會是:Local Port Forwarding > Dynamic Port Forwarding »»» Remote Port Forwarding。
Local Port Forwarding 真的最常見,因為太多內網服務都只有 SSH 能進、服務本身不會直接開給外部。Dynamic Port Forwarding 也很好用,尤其你只是暫時需要代理流量時,很省事。至於 Remote Port Forwarding,不是不能用,而是它通常牽涉到更高的權限與安全風險,所以我自己會比較保守。
另外,SSH 權限真的不要隨便開放給一般使用者。因為一旦能建立 Tunnel,本質上就等於多了一種繞過原本網路限制的手段。功能很方便,但權限控管一定要更小心。
更多參考資料
- 常用 http/https 以及 socks5 代理總結 - 博客園
- Linux ssh 遠端連線 - HackMD
- 淺談 SSH agent forwarding 和 proxy command 的安全風險與應用 - Nic Lin’s Blog
- SSH Tunnels and Port Forwarding - iximiuz
之後如果又忘記 -L、-R、-D 差在哪裡,我應該會先回來看這篇,而不是再從頭 Google 一次。