underclassHero 2019-11-04
SSH是个强大的工具,其连通后的数据流是双向的,通常能用其来实现内网的“穿透”,尤其是其动态端口转发的功能,基于SOCKS5协议,能够让其他应用借助该“隧道”进行信息交互,但是通常大部分应用的交互协议使用的是http/https,而socks5协议工作在会话层,无法进行应用层的代理,此时可以借助工具Privoxy,Privoxy可以基于socks代理创建http代理,当然privoxy还有很多其他功能,不在此赘述,详情可以访问User Manual。下面围绕一个图例进行讲解。
------------------ | | HOST <------> Jump Server <------> ECS | | ------------------
HOST主机想要访问ECS,但访问ECS的唯一方式是通过Jump server来访问,而HOST与Jump server,Jump server与ECS之间能够通信的唯一方式是ssh,且Jump server以及ECS无法连接外部网络,现在分几种情况:
最容易想到的方法是,先HOST通过ssh登录到Jump server,然后通过Jump server再登录到ECS,然而这种方法需要分两个步骤,且传文件时也极不方便,有没有更直接简单点的方法呢,答案是肯定的,请看下面这条命令:
ssh -4 -o TCPKeepAlive=yes -o ServerAliveInterval=300 -o ProxyJump=<jump-server username>@<jump-server ip> -f <ecs username>@<ecs ip>
-4
意味着选用IPV4,-o
等同于配置/etc/ssh/ssh_config
,后面接配置参数,其中ProxyJump
就是配置中间的ssh代理-f
后台运行该进程通过上述命令即可”透明“连接ECS,传文件时也方便了许多。
请先了解SSH的端口转发概念及原理,可参考实战 SSH 端口转发
运行下面这条命令:
ssh -o TCPKeepAlive=yes -o ServerAliveInterval=300 -Nf -D <proxy-port> <jump-server username>@<jump-server ip>
-N
通常用于端口转发命令之中,意味着不执行远程命令。-D
动态端口转发,后面接端口号执行上述命令后,所有通过HOST的`<proxy-port>`的数据将转发到Jump server的任意端口(虽然Jump server只开通了ssh的连接端口,但在动态端口转发时,Jump server作为SSH server,会将收到的数据分配到特定的端口,至于是哪个端口,用户无需关心),它们之间的通信基于SOCKS5协议,此时HOST的`127.0.0.1:<proxy-port>`可以作为正常的SOCKS代理来使用。
Privoxy
,若是无法网络安装,可下载源码后自己进行编译安装,步骤请参考https://www.privoxy.org/user-...。config
配置文件。一般在/etc/privoxy/config
或/usr/local/etc/privoxy/config
中能找到,主要修改两处,一处是listen-address 127.0.0.1:8118
,privoxy默认监听的端口是本机的8118端口,可根据需要进行修改;另一处是forward-socks5
,特别注意与forward-socks5t
的区别,forward-socks5
在转发时运用远程的DNS进行解析,而forward-socks5t
则有所不同(可以参考https://lists.privoxy.org/pip...),config
文件里默认只有forward-socks5t
,而使用forward-socks5t
会出现很多意想不到的问题,因此最好还是在forward-socks5t
下面增加一条forward-socks5 / 127.0.0.1:<proxy-port> .
,即可将步骤1创建的socks5代理转为http代理。如果想要把存储在HOST主机的docker images推到位于Jump server之后的container registry,则可以利用这个http代理,因为docker daemon之间是通过http/https协议通信的,具体操作方式请参考https://docs.docker.com/confi...
有了前面的铺垫,Jump server访问公网配置也就十分简单了,只要能将SSH动态端口转发连接到HOST(当然,请保证HOST能访问公网),再用privoxy实现http代理即可,步骤和前面是一样的,但是SSH clien和SSH server的角色互换了,现在Jump server是SSH client,HOST为SSH server,不过这儿存在一个问题:如果HOST也处于NAT网络中,则Jump server无法主动发起SSH动态端口转发的连接请求,这该怎么办呢?这时就要运用到SSH的远程端口转发功能了,在HOST运行下面的命令:
ssh -o TCPKeepAlive=yes -o ServerAliveInterval=300 -Nf -R 2222:127.0.0.1:22 <jump-server username>@<jump-server ip>
-R
意味着远程端口转发,上述命令在HOST主机上运行,表示访问Jump server的2222
端口都会被转发到HOST本机的22
端口,因此运行完这个命令后,Jump sever只要通过ssh连接自己的2222端口,就相当于通过ssh连接到HOST的22端口,这样就解决了Jump server无法主动连接处于NAT网络内HOST的问题了。
总之,只要ssh连接成功,就能想办法创建出http代理,后面的步骤与前面类似,就不在此赘述了。
参考