SSH Tunnel (Port Forwarding) 詳解
SSH 不只能用來遠端登入,它還有一個超強大的功能叫做 SSH Tunnel (通道),或是 Port Forwarding (連接埠轉發)。
它可以讓你透過加密的 SSH 連線,將「本機的某個 Port」映射到「遠端的某個 Port」,或是反過來。這在穿越防火牆、連線內網服務(如 MySQL、Redis)或臨時架設 VPN 時非常有用。
有三種最常用的模式:Local (-L)、Remote (-R)、Dynamic (-D)。
1. Local Port Forwarding (-L)
場景:你想從本機連線到遠端伺服器 (Server A) 內部網路的資料庫 (Database B),但資料庫只允許內網連線。
簡單說就是:把遠端的東西拉回來本機用。
# 語法:ssh -L [本機IP]:[本機Port]:[目標IP]:[目標Port] [跳板機User]@[跳板機IP]
ssh -L 3306:localhost:3306 user@remote-server.com
- 這行指令的意思是:「在我的電腦開一個 3306 Port,當我連線到
localhost:3306時,請透過remote-server.com幫我轉送到它自己 (localhost) 的3306Port」。 - 現在,你只要連線本機的 3306,就像是在連線遠端的 MySQL 一樣!
進階用法:連線到遠端的內網其他機器
# 透過 remote-server 連線到它內網的 192.168.1.50 的 80 Port
ssh -L 8080:192.168.1.50:80 user@remote-server.com
現在打開瀏覽器 http://localhost:8080,就能看到那台內網機器的網頁了。
2. Remote Port Forwarding (-R)
場景:你在本機開發的一個網頁,想給遠端的朋友(或是 Internet 上的人)看,但你的電腦在內網沒有 Public IP。
簡單說就是:把本機的東西推給遠端用。
# 語法:ssh -R [遠端IP]:[遠端Port]:[本機IP]:[本機Port] [遠端User]@[遠端IP]
ssh -R 8080:localhost:80 user@remote-server.com
- 這行指令的意思是:「在
remote-server.com上開一個 8080 Port,當有人連線到remote-server.com:8080時,請轉送到我這台電腦 (localhost) 的80Port」。 - 如果遠端伺服器有 Public IP,現在全世界都可以透過
http://remote-server.com:8080看到你的網站了!
注意: 預設 SSH Server (
sshd_config) 的 GatewayPorts 通常是 no,這會導致 -R 監聽的 Port 只允許 localhost (127.0.0.1) 連線。如果要讓外網連線,必須在遠端伺服器的 /etc/ssh/sshd_config 設定 GatewayPorts yes 並重啟 sshd。3. Dynamic Port Forwarding (-D)
場景:你想透過遠端伺服器上網(隱藏 IP、翻牆、繞過公司防火牆)。這就是簡易版的 VPN (SOCKS5 Proxy)。
# 語法:ssh -D [本機Port] [遠端User]@[遠端IP]
ssh -D 1080 user@remote-server.com
- 這會在你的電腦開一個
1080Port (SOCKS Proxy)。 - 接著去瀏覽器或網路設定,將 SOCKS5 Proxy 指向
127.0.0.1:1080。 - 之後你的所有上網流量都會「鑽」進 SSH 通道,從
remote-server.com出去。
實用技巧
不執行指令 (-N)
通常我們建立 Tunnel 只是為了轉發封包,不需要真的登入 Shell 打指令。加上 -N 可以只建立連線不開啟 Shell。
ssh -N -L 3306:localhost:3306 user@remote-server.com
背景執行 (-f)
搭配 -N 使用,讓 SSH 連線建立後直接在背景執行。
ssh -f -N -L 3306:localhost:3306 user@remote-server.com
斷線自動連線 (Autossh)
SSH 連線久了可能會斷掉。如果你需要長時間維持通道,建議安裝 autossh 工具,用法跟 ssh 幾乎一樣,但斷線會自動重連。
autossh -M 0 -f -N -L 3306:localhost:3306 user@remote-server.com