
內網穿透、安全連線、跳板機一次搞定!
前言:為什麼你需要學會 SSH 隧道?
在 IT 日常工作中,你是否遇過以下情境:- 想連線公司內網的資料庫做開發測試,但資料庫不允許直接對外開放連線。
- 在家裡臨時需要存取公司電腦上的檔案,偏偏沒有 VPN 可用。
- 想讓外部的客戶或同事看看你本機上正在開發的測試網站,又不想把服務部署到公開伺服器。
- 公司網路層層封鎖,好幾層跳板機搞得每次連線都像在闖關。
這些問題,SSH 隧道都能幫你解決。
SSH 隧道(也稱為 SSH Port Forwarding,即 SSH 埠轉發)是一種透過加密的 SSH 連線來轉發網路流量的技術。它會在用戶端和伺服器之間建立一條安全、加密的私有通道,所有通過這條通道傳輸的資料都會被加密,等於是把你原本不安全的網路傳輸「裝進一個加密的保護管線」裡,避免被竊聽或攔截。
更重要的是,SSH 幾乎是所有 Linux / Unix 系統內建的協定,Windows 也已經原生支援 OpenSSH,不需要額外安裝任何軟體就能使用這項強大的功能。
一、SSH 隧道的基本觀念
什麼是 SSH 隧道?
簡單來說,SSH 隧道就是「在兩台主機之間挖一條加密的通道」。當你在本機連上遠端 SSH 伺服器之後,凡是進入這條通道的資料都會被自動加密,然後安全地送達到另一端的目標。
SSH 隧道的三大安全優勢
- 全程加密防竊聽:所有通過隧道傳輸的資料都受到 SSH 加密保護,即使是在公共 Wi-Fi 這類不安全的網路上,也沒有人能偷看你的傳輸內容。
- 連線身分驗證:透過 SSH 的金鑰或密碼驗證機制,確保你是與正確的伺服器建立連線,防止駭客偽造伺服器騙取你的資訊。
- 繞過防火牆封鎖:你可以透過 SSH 連線繞過被防火牆阻擋的埠,存取原本無法直接連線的內部服務。
SSH 隧道的三種類型總覽

下面我們會針對每一種轉發模式進行詳細的教學,並搭配實際情境的範例讓你更容易理解。
二、正向轉發|Local Port Forwarding(-L)是什麼?
正向轉發會在你的本機和遠端 SSH 伺服器之間建立一條安全通道,讓你可以把遠端某個服務的埠,「拉」到本機來使用。
白話來說就是:你在本機連上一個埠,但實際上是在存取遠端伺服器上的某個服務。
最經典的例子是你公司內網有一台 MySQL 資料庫(跑在埠 3306),這台資料庫不對外開放直接連線。這時你可以先 SSH 連線到公司內網某一台對外的跳板機,然後透過正向轉發把資料庫的 3306 埠映射到你的本機埠,接著你就可以在本機用 Navicat 或 DBeaver 愉快地連線了。
基本語法
ssh -L [本機埠]:[目標主機]:[目標埠] [帳號]@[SSH伺服器]
實際範例
情境一:連線內網 MySQL 伺服器
假設你的公司有一台對外的跳板機 jump.example.com(帳號:user),內網資料庫 db.internal.com 的 MySQL 跑在埠 3306。
ssh -L 13306:db.internal.com:3306 user@jump.example.com -N
13306:你本機要「開出」的埠,可以自由選擇(建議選 1024 以上、尚未被佔用的埠)。db.internal.com:3306:目標資料庫主機與埠,也就是你真正想要存取的服務。[email protected]:你 SSH 登入的跳板機。-N:建立隧道但不要登入 Shell。不加-N的話,你的終端機會卡在 SSH 登入畫面,無法同時執行其他指令。
執行這條指令之後,你在本機開啟資料庫連線工具,連到 127.0.0.1:13306,就會「穿透」SSH 隧道直接連上 db.internal.com 的 MySQL 伺服器了。
情境二:透過跳板機存取更深層的內網
如果你的目標服務不在跳板機本機上,而是在跳板機後方的另一台內網主機上也沒問題。
ssh -L 13306:192.168.1.100:3306 user@jump.example.com -N
這裡的 192.168.1.100 就是內網中真正跑資料庫服務的那台主機,只要跳板機能連得到它就 OK。
實用小技巧
- 加上
-f參數可將隧道推到背景執行:ssh -fN -L 13306:db.internal.com:3306 [email protected],這樣終端機就不會被佔住。 - 加上
-g參數可讓其他主機也能使用你建立的隧道(需要開啟 GatewayPorts):ssh -g -N -L 8888:192.168.1.100:80 [email protected]。這樣同一區域網路內的其他裝置也能連過來用。
三、反向轉發|Remote Port Forwarding(-R)是什麼?
反向轉發剛好跟正向轉發反過來:你把本機的某個服務「暴露」到遠端的 SSH 伺服器上,讓遠端或者其他外部機器可以連線到你本機的服務。
反向轉發特別適合以下情境:
- 你在本機開發了一個網站(例如跑在埠 8080),想讓外部的客戶或同事看一下測試成果,但本機沒有固定 IP,也沒有對外公開的伺服器。
- 你有一台被 NAT 擋住的內網機器(沒有實體 IP),你想從外部連線回去管理它。透過反向轉發,內網機器主動撥出連線到一台公有雲端伺服器,然後你透過那台公有雲端伺服器就能連進內網機器了。
前提條件
反向轉發需要在遠端 SSH 伺服器上進行設定。請修改遠端伺服器的 /etc/ssh/sshd_config:
GatewayPorts yes
AllowTcpForwarding yes
然後重新載入設定:sudo systemctl reload sshd
基本語法
ssh -R [遠端埠]:[本機目標IP]:[本機目標埠] [帳號]@[遠端SSH伺服器]
實際範例
情境一:讓外部測試本機網站
你的本機跑了一個開發中的網站(埠 8080),你有一台公有雲端伺服器 myserver.com(帳號:user)。你想要讓同事從外部連到 myserver.com:18080 來看你本機的網站。
ssh -R 18080:localhost:8080 user@myserver.com -N
執行之後,外地同事只要在瀏覽器輸入 http://myserver.com:18080,就會透過 SSH 隧道連線到你的本機網站。
情境二:從外網連線被 NAT 擋住的內網機器(內網穿透)
假設你家裡有一台 Linux 主機 pi.local(被 ISP 的 NAT 擋住,沒有真實 IP),你想要從公司連線回家裡這台機器。解法是:
- 先在公有雲端開一台伺服器
vps.example.com,並且設定好GatewayPorts yes。 - 在家裡 Pi 上面執行反向轉發指令:
ssh -R 2222:localhost:22 user@vps.example.com -N
- 接著從公司連到 VPS 的 2222 埠,就可以穿透 NAT 連到你家的 Pi:
ssh -p 2222 pi@vps.example.com
這就是經典的「SSH 反向隧道實現內網穿透」技巧。
四、動態轉發|Dynamic Port Forwarding(-D)是什麼?
動態轉發跟前兩種一對一的埠轉發不同。它不會指定要轉發到哪一個特定的目標埠,而是在本機建立一個 SOCKS 代理伺服器。當你把瀏覽器或其他應用程式的代理設定指向這個 SOCKS 代理時,所有通過這個代理的連線請求,都會動態地透過你的 SSH 隧道轉發出去。
換句話說,動態轉發本質上就是用 SSH 隧道包了一個 SOCKS 代理。你在瀏覽器設定好 SOCKS 代理之後,瀏覽器的每一筆請求都會被導進 SSH 隧道,然後從 SSH 伺服器那邊「出來」,就好像你的瀏覽器直接跑在 SSH 伺服器所在地一樣。
基本語法
ssh -D [本機SOCKS埠] [帳號]@[SSH伺服器]
實際範例
情境:建立安全的瀏覽代理
你想要透過一台位於美國的 SSH 伺服器 us-server.com 來安全地瀏覽網頁。
ssh -D 1080 user@us-server.com -N
執行之後,你的本機就多了一個跑在埠 1080 的 SOCKS 代理伺服器。
接著設定瀏覽器的代理:
Firefox 設定方式:
- 點選右上角選單 → 偏好設定 → 搜尋「proxy」
- 設定「手動 proxy 設定」
- SOCKS 主機填入
127.0.0.1,埠填入1080 - 選擇 SOCKS v5,並勾選「Proxy DNS when using SOCKS v5」(這樣 DNS 查詢也會透過隧道走,避免 DNS 洩漏)
Chrome 可以用命令列啟動來設定代理:
chrome --proxy-server="socks5://127.0.0.1:1080"
設定完成之後,瀏覽器的所有流量都會走進 SSH 隧道,從美國的伺服器出來。
為什麼要用動態轉發而不是 VPN?
如果你只是偶爾需要透過某個伺服器繞開某些限制,或者是臨時測試某些服務,用 -D 開一個 SOCKS 代理顯然比興師動眾架一套 VPN 簡單太多了——而且不需要在客戶端安裝任何第三方軟體。
五、進階篇|跳板機穿透技巧
在真實的企業環境中,網路架構往往不是「本地端 ➜ 單一跳板機 ➜ 目標機」這麼單純。很多時候你會需要:
- 本地端 ➜ 跳板機 A ➜ 跳板機 B ➜ 目標資料庫
- 或者是透過跳板機再搭配埠轉發來存取內網服務
這時候就需要用到 SSH 的跳板機穿透功能了。
ProxyJump(-J)——現代 SSH 的免洗跳板利器
ProxyJump 是 SSH 7.3 版本(2016 年發布)新增的功能,可以讓你一行指令就穿透多層跳板機,不需要逐台手動 SSH 登入。
傳統的做法是:
ssh userA@jumpA(登入跳板機 A)- 再從跳板機 A 執行
ssh userB@jumpB(登入跳板機 B) - 再從跳板機 B 執行
ssh userC@target
光是登入就要輸入三次指令,如果在不同層需要輪換不同的金鑰或密碼,更是噩夢一場。
使用 ProxyJump 之後:
ssh -J userA@jumpA,userB@jumpB userC@target
一條指令直接穿透兩層跳板機,直達目標主機。中間的跳轉完全在背景自動完成,使用者完全不會感覺到換手的過程。
搭配 .ssh/config 設定檔
與其在命令列反覆輸入長長的參數,更好的做法是把設定寫進 ~/.ssh/config 設定檔裡。
Host jumpA
HostName jumpA.example.com
User myuser
IdentityFile ~/.ssh/jumpA_key
Host jumpB
HostName jumpB.internal.com
User myuser
IdentityFile ~/.ssh/jumpB_key
ProxyJump jumpA
Host target
HostName target.db.internal.com
User dbuser
ProxyJump jumpB
設定好之後,你只需要一行 ssh target,就會自動經過跳板機 A → 跳板機 B → 目標機。
這個設定也可以用來搭配埠轉發。比如你想透過這兩層跳板機存取內網的資料庫:
ssh -L 13306:127.0.0.1:3306 target -N
搞定。這麼一來,使用資料庫 GUI 工具連到本機的 13306 埠,就會一路穿越跳板機 A 和跳板機 B,直達內網的資料庫伺服器。
六、確保隧道穩定性|連線保活與自動重連
問題:為什麼 SSH 隧道老是斷掉?
SSH 連線如果有一段時間沒有活動,網路設備(像是防火牆或路由器)可能會主動把連線切掉。這會導致你辛苦建立的隧道在半夜或工作空檔莫名其妙地中斷。
解法一:設定 KeepAlive 讓連線保持心跳
在你的 ~/.ssh/config 中加上以下設定:
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
TCPKeepAlive yes
ServerAliveInterval 60:每 60 秒送一個保活封包。ServerAliveCountMax 3:如果連續 3 次保活封包沒有回應,才判斷連線已經斷開。TCPKeepAlive yes:開啟 TCP 層的保活機制。
解法二:用 Autossh 自動重連隧道
如果你遇上連線很不穩定的場景(例如行動網路經常切換),或者隧道對你來說非常重要,建議使用 Autossh 這個工具來取代原生的 ssh。
Autossh 會包裝 SSH 連線,並且在連線斷掉的時候自動重新建立連線,不需要你手動處理。
安裝 Autossh:
# Ubuntu / Debian
sudo apt install autossh
# CentOS / RHEL
sudo yum install autossh
# macOS
brew install autossh
使用 Autossh:
autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -fN -L 13306:db.internal.com:3306 user@jump.example.com
-M 0:Autossh 預設會用兩個埠來做連線監控,設為 0 可以改用 SSH 內建的 ServerAlive 機制來做監控,跟上面的保活設定比較不會打架。- 後面的參數跟一般 SSH 一模一樣,所以你可以直接把原來的
ssh指令改成autossh,加上 -M 0 後其他照舊。
七、安全注意事項
1️⃣ 優先使用 SSH Key 而不是密碼
使用密碼登入 SSH 存在密碼被暴力破解的風險。建議一律改用 SSH 金鑰對來進行驗證。
產生金鑰對:
ssh-keygen -t ed25519 -C "[email protected]"
然後將公鑰上傳到遠端伺服器:
ssh-copy-id user@remote-server
2️⃣ 不要過度敞開 GatewayPorts
GatewayPorts yes 會讓你在反向轉發時綁定到遠端伺服器的所有網路介面(0.0.0.0),任何人都可以存取你建立的隧道。如果只是要自己或授權的使用者可以存取,建議在轉發命令中明確指定綁定至 127.0.0.1,或者將 GatewayPorts 設為 clientspecified,讓使用者自己決定要綁在哪個 IP 上。
3️⃣ 避免在不安全的網路上使用 SSH 隧道
雖然 SSH 隧道本身是加密的,但是若本機已經中了惡意軟體,駭客仍然可以透過你啟用的本地埠對你的服務進行攻擊。請務必保持本機的防火牆與防毒軟體正常運作。
4️⃣ 使用 -N 參數降低安全風險
如果你只需要隧道而不需要登入 Shell,記得加上 -N 參數,這樣可以避免因為不小心在 SSH 連線上執行其他指令而引入不必要的風險。
八、常見問題與排錯 Q&A
Q1:執行 ssh -L 或 ssh -R 後,連線正常,但 telnet 測試連不上?
A:檢查防火牆設定,以及目標服務是否真的有在該埠上監聽。可以用 ss -tlnp 或 netstat -tlnp 檢查目標伺服器上是否有服務正在監聽指定的埠。另外也別忘了確認雲端安全組或防火牆規則是否開放了相關的埠。
Q2:反向轉發出現 remote port forwarding failed for listen port 錯誤
A:這通常是遠端伺服器的 SSH 設定不允許遠端埠轉發。檢查遠端伺服器的 /etc/ssh/sshd_config 裡 AllowTcpForwarding 是否設為 yes。若你需要綁定到公開網卡(所有人可連線),則 GatewayPorts 也必須設為 yes 或 clientspecified。設定完記得執行 sudo systemctl reload sshd 重新載入。
Q3:SSH 隧道跑起來之後,終端機會卡住?
A:這是正常的!加上 -N 參數後隧道只做埠轉發,不會給你一個完整的 Shell。如果想要讓終端機不被佔用,再加上 -f 參數推送到背景執行即可。兩種寫法擇一:ssh -fN ... 或者另一種終端機執行後直接按 Ctrl + Z 並輸入 bg。
Q4:我需要看更詳細的連線過程和錯誤資訊來除錯!
A:加上 -v 參數即可看到詳細的連線過程。如果不夠詳細,還可以加更多層,像是 -vv 或 -vvv。通常 -vv 就足以看出問題出在哪裡了。執行 ssh -vvv -L ... 可以把加密協商、轉發配置等細節全部印出來,對釐清問題非常有幫助。
九、完整指令懶人包
為了方便你快速套用,以下將本篇文章提到的所有指令整理成對照表格:

結語
SSH 隧道可說是每一位 IT 工作者都應該熟悉的瑞士刀級工具,無論你是開發者、維運工程師還是資安人員,在內網穿透、遠端 debug、爬牆代理等場景都一定會用得上。它的優點在於:
✅ 原生:不需要安裝第三方軟體,Windows / Linux / macOS 都原生支援 OpenSSH。
✅ 安全:全流量走加密通道,連 DNS 查詢都可以保護起來。
✅ 靈活:支援三種轉發模式,涵蓋各種實際應用情境。
✅ 輕量:不像 VPN 那樣需要部署整套基礎設施,一條指令就搞定。
希望這篇文章能幫助你從零開始學會使用 SSH 隧道,也歡迎你把這篇收藏起來,遇到相關的連線需求時可以直接翻閱指令對照表。



















