- 端口轉發兩大功能
- 加密SSH Client 端至SSH Server 端之間的通訊數據
- 突破防火牆或內網的限制完成一些之前無法建立的TCP 連接
正向端口轉發
L
表示正向轉發;-N
表示非不執行命令,只做端口轉發;-f
表示在後臺運行
ssh -NfL <local port>:<dest addr>:<dest port> <usr@jump addr>
# 舉例
client$ ssh -NfL 1080:server:1081 jumpbox
- 把client的1080端口通過跳板機jump轉發到server的1081端口
- 在client端建立轉發連接
- 數據傳遞過程
- 首先數據會發送到本機1080端口
- 再在本機開一個隨機端口,充當ssh客戶端,把數據流量發送到jumpbox22端口的ssh服務端
- jumpbox收到數據以後,解密數據,臨時開一個隨機端口充當客戶端,再把流量發送到server的1081端口
- 本地到 ssh 跳板機這一段,是完全加密的。跳板機到服務器的這一段,依然是明文的
反向端口轉發
-R
表示反向轉發
ssh -NfR <client port>:<dest addr>:<dest port> <usr@client addr>
# 舉例
jump$ ssh -NfR 1080:server:1081 client
-
主要針對內網的情況。本地計算機在外網,ssh 跳板機和目標服務器都在內網,而且本地計算機無法訪問內網之中的跳板機,但是跳板機可以訪問本機計算機
- 由於本機無法訪問跳板機,就無法從外網發起隧道,必須反過來,從跳板機發起隧道
-
把client的1080端口通過跳板機jump轉發到server的1081端口
- 在jump端建立轉發連接
- 數據傳遞過程同上
-
跳板機同時也可以是目標服務器,此時實現了外網的用戶端訪問位於內網的服務器
server$ ssh -NfR 10086:localhost:22 <usr@client addr>
# client訪問
client$ ssh root@server -p 10086
- 這裏的用戶端一般是位於外網的跳板機,這樣用戶可以通過跳板機訪問服務器
- client可以首先登陸到位於外網的機器,然後輸入wwt用戶在server密碼就可以登陸到server,但是這樣還是略顯麻煩
- 可以把 jump 機的ssh端口開放在 0.0.0.0 而不是默認的127.0.0.1就可以直接在 client 端登陸到server
- 需要修改jump機的
/etc/ssh/sshd_config
文件,添加GatewayPorts yes
。然後重啓sshd服務 - 這時候還需要把遠程端口轉發命令做點小修改
server$ ssh -NfR 0.0.0.0:10086:localhost:22 <usr@junmp addr>
# client訪問
# 注意這裏的用戶是server上的用戶,不是jump上的
client$ ssh wwt@jump -p 10086
動態端口轉發(socks5代理)
-D
表示動態轉發
ssh -NDf 1080 <user@proxy addr>
- 這種轉發採用了 SOCKS5 協議,需要支持把 HTTP 請求轉成 SOCKS5 協議,才能把本地端口的請求轉發出去
- 在瀏覽器設置代理
socket proxy:127.0.0.1:1080
- 在瀏覽器設置代理
curl -x socks5://localhost:1080 http://www.example.com
- 前面的代理都是靜態代理,也就是建立時就指定好了server地址
- 動態轉發要把本地端口綁定到 ssh 跳板機。至於 ssh 跳板機要去訪問哪一個網站,完全是動態的,所以叫做動態轉發
實戰
- 現在有兩個位於不同內網的主機A,B;兩者無法直接通行;另外有一個跳板機器jumpbox
- 實現要讓A主機SSH到B上
B$ ssh -NfR 10086:localhost:22 jumpbox # 把本地22反向轉發到jumpbox的10086
A$ ssh -NfL 10001:localhost:10086 jumpbox # 把本地10001轉發到jumpbox的10086
# 此時A可以SSH到B了
A$ ssh localhost -p 10001