From:https://zhuanlan.zhihu.com/p/57630633
ssh 命令除了登陸外還有三種代理功能:
- 正向代理(-L):相當於iptable 的port forwarding
- 反向代理(-R):相當於frp 或者ngrok
- socks5 代理(-D):相當於ss/ssr
如要長期高效的服務,應使用對應的專用軟件。如沒法安裝軟件,比如當你處在限制環境下想要訪問下某個不可達到的目標,或者某個臨時需求,那麼ssh 就是你的兜底方案。
正向代理:
所謂“正向代理”就是在本地啟動端口,把本地端口數據轉發到遠端。
用法1:遠程端口映射到其他機器
HostB 上啟動一個PortB 端口,映射到HostC:PortC 上,在HostB 上運行:
HostB$ ssh -L 0.0.0.0:PortB:HostC:PortC user@HostC
這時訪問HostB:PortB 相當於訪問HostC:PortC(和iptable 的port-forwarding 類似)。
用法2:本地端口通過跳板映射到其他機器
HostA 上啟動一個PortA 端口,通過HostB 轉發到HostC:PortC上,在HostA 上運行:
HostA$ ssh -L 0.0.0.0:PortA:HostC:PortC user@HostB
這時訪問HostA:PortA 相當於訪問HostC:PortC。
兩種用法的區別是,第一種用法本地到跳板機HostB 的數據是明文的,而第二種用法一般本地就是HostA,訪問本地的PortA,數據被ssh 加密傳輸給HostB 又轉發給HostC:PortC 。
反向代理:
所謂“反向代理”就是讓遠端啟動端口,把遠端端口數據轉發到本地。
HostA 將自己可以訪問的HostB:PortB 暴露給外網服務器HostC:PortC,在HostA 上運行:
HostA$ ssh -R HostC:PortC:HostB:PortB user@HostC
那麼鏈接HostC:PortC 就相當於鏈接HostB:PortB。使用時需修改HostC 的/etc/ssh/sshd_config,添加:
GatewayPorts yes
相當於內網穿透,比如HostA 和HostB 是同一個內網下的兩台可以互相訪問的機器,HostC是外網跳板機,HostC不能訪問HostA,但是HostA 可以訪問HostC。
那麼通過在內網HostA上運行ssh -R
告訴HostC,創建PortC端口監聽,把該端口所有數據轉發給我(HostA),我會再轉發給同一個內網下的HostB:PortB。
同內網下的HostA/HostB也可以是同一台機器,換句話說就是內網HostA把自己可以訪問的端口暴露給了外網HostC。
按照前文《韋易笑:內網穿透:在公網訪問你家的NAS》中,相當於再HostA上啟動了frpc,而再HostC上啟動了frps。
本地socks5 代理
在HostA 的本地1080 端口啟動一個socks5 服務,通過本地socks5 代理的數據會通過ssh 鏈接先發送給HostB,再從HostB 轉發送給遠程主機:
HostA$ ssh -D localhost:1080 HostB
那麼在HostA 上面,瀏覽器配置socks5 代理為127.0.0.1:1080,看網頁時就能把數據通過HostB 代理出去,類似ss/ssr 版本,只不過用ssh 來實現。
使用優化
為了更好用一點,ssh後面還可以加上:-CqTnN
參數,比如:
$ ssh -CqTnN -L 0.0.0.0:PortA:HostC:PortC user@HostB
其中-C
為壓縮數據,-q
安靜模式,-T
禁止遠程分配終端,-n
關閉標準輸入,-N
不執行遠程命令。此外視需要還可以增加-f
參數,把ssh放到後台運行。
這些ssh 代理沒有短線重連功能,鏈接斷了命令就退出了,所以需要些腳本監控重啟,或者使用autossh 之類的工具保持鏈接。
功能對比
正向代理(-L)的第一種用法可以用iptable 的port-forwarding 模擬,iptable 性能更好,但是需要root 權限,ssh -L 性能不好,但是正向代理花樣更多些。反向代理(-R)一般就作為沒有安裝frp/ngrok/shootback 時候的一種代替,但是數據傳輸的性能和穩定性當然frp 這些專用軟件更好。
socks5 代理(-D)其實是可以代替ss/ssr 的,區別和上麵類似。所以要長久使用,推薦安裝對應軟件,臨時用一下ssh 挺順手。
--
補充下iptable的 port-forwarding
怎麼設置,十分管用的功能,兩個函數即可:
#! /bin/sh
# create forward rule by source interface
# http://serverfault.com/questions/532569/how-to-do-port-forwarding-redirecting-on-debian
PortForward1() {
local IN_IF=$1
local IN_PORT=$2
local OUT_IP=$3
local OUT_PORT=$4
local IPTBL="/sbin/iptables"
echo "1" > /proc/sys/net/ipv4/ip_forward
$IPTBL -A PREROUTING -t nat -i $IN_IF -p tcp --dport $IN_PORT -j DNAT --to-destination ${OUT_IP}:${OUT_PORT}
$IPTBL -A FORWARD -p tcp -d $OUT_IP --dport $OUT_PORT -j ACCEPT
$IPTBL -A POSTROUTING -t nat -j MASQUERADE
}
# create forward rule by source ip
# http://blog.csdn.net/zzhongcy/article/details/42738285
ForwardPort2() {
local IN_IP=$1
local IN_PORT=$2
local OUT_IP=$3
local OUT_PORT=$4
local IPTBL="/sbin/iptables"
echo "1" > /proc/sys/net/ipv4/ip_forward
$IPTBL -t nat -A PREROUTING --dst $IN_IP -p tcp --dport $IN_PORT -j DNAT --to-destination ${OUT_IP}:${OUT_PORT}
$IPTBL -t nat -A POSTROUTING --dst $OUT_IP -p tcp --dport $OUT_PORT -j SNAT --to-source $IN_IP
}
第一個函數是按照網卡名稱設置轉發:
PortForward1 eth1 8765 202.115.8.2 8765
這時,本地eth1 網卡的8765 端口就會被轉發給202.115.8.2 的8765 端口。
第二個函數是按照本機的ip 地址,比如本機是192.168.1.2:
PortForward2 192.168.1.2 8765 202.115.8.2 8765
那麼任何訪問本機192.168.1.2 這個地址8765 端口,都會被轉發到202.115.8.2:8765
這個iptable的port forwarding
是內核層運行的,性能極好,只不過每次重啟都需要重新設置下。
沒有留言:
張貼留言