SSH命令的三种代理功能(-L-R-D)
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。
按照前⽂《》中,相当于再 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 之类的⼯具保持链接。
ssh命令指定端口功能对⽐
正向代理(-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
# serverfault/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
# blog.csdn/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是内核层运⾏的,性能极好,只不过每次重启都需要重新设置下。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。