转自:https://yq.aliyun.com/articles/8469

ssh是一个非常棒的工具, 不但能建立动态转发, 例如chrome的Switchy插件用到的就是这个技术.
http://blog.163.com/digoal@126/blog/static/163877040201141821810103/
还能建立TCP的转发隧道, 例如我以前写过的关于使用ssh 隧道加密和加速WAN传输的几个例子.
http://blog.163.com/digoal@126/blog/static/163877040201342383123592/
http://blog.163.com/digoal@126/blog/static/16387704020115294425540/
上面的例子可以理解为正向的TCP端口转发代理(如local$ ssh -L 7001:1.1.1.1:1000 remote_A), 即本地服务器local建立和远程服务器的SSH连接, 本地监听一个端口7001, 连接本地的监听端口7001相当于"通过远程服务器remote_A访问指定的IP 1.1.1.1和PORT 1000".
这种方法适用于本地网络中其他服务器想访问远程的服务器, 但是其他服务器没有直接访问远程服务器的权限, 通过本地网络中有权限的服务器做端口转发的场景.

还有一种应用场景是这样的, 本地网络环境中没有任何一台服务器可以直接访问远程服务器, 但是远程服务器可以反过来访问本地的某台服务器(或者本地可以访问到的某台服务器), 这样的话也能实现本地服务器去访问远程服务器的目的. 这就是反向代理.
实际的应用场景如,
或者说A和B无法相互访问,但是A能访问C,B也能访问C。怎么通过C让AB能相互访问?
.1. 家里的网络是动态拨号网络, 没有固定IP, 如果想在上班的时候控制家里的电脑怎么办呢? 如果公司有一台服务器是可以在家拨号过去访问的, 那么你可以在家里的电脑上建立和这台公司服务器的反向代理, 到公司后, 就可以连接这台服务器上的反向代理(监听)来连接家里的电脑了.
.2. 有的客户可能不希望提供VPN给你去访问他们的服务器, 但是又需要得到你的远程协助, 怎么办呢?
你可以提供一台服务器让客户主动来访问你的服务器, 客户建立这样的反向代理, 然后你通过这个反向代理来连接客户开放的端口如VNC桌面共享, 进行远程协助. (这种方法比QQ远程协助是更安全的, 因为客户和这台服务器之间的数据时加密的, QQ远程协助毕竟有一定的风险存在.)
以下是反向代理的图例, 如图1 :
箭头表示允许访问的方向, 也就是说Server C可以访问Server A和Server B以及Client A.
而Client B和Client C可以访问Client A.
我们的目的是要让Client 可以访问Server. 这里就要用到SSH的反向端口转发, 或远程端口转发.

反向代理应用场景.
例如, 以下虚线表示Client C最终要访问Server A的22端口.
实现的步骤
1. Client A需要修改一下sshd_config, 开启GatewayPorts, 这样才能监听回环地址以外的地址, 如0.0.0.0, 这样的话其他服务器才能访问到这个端口.
2. Server C建立和Client A的反向端口转发, 让Client A在0.0.0.0上监听7001端口, 访问这个端口的数据转发到IP_SA的22端口.

ssh -CqTfnN -R  0.0.0.0:7001:IP_SA:22   IP_CA

其实再深层次一点, 因为client c和server a已经可以建立ssh了, 那么通过client c和server a建立反向代理, Server A也可以访问Client c. 这样需要经过了多层ssh隧道( IP_CA->IP_SC, IP_SA->IP_CC )

这种反向代理的用法很容易应用到实际的场景中, 例如前面提到的 :
有的客户可能不希望提供VPN给你去访问他们的服务器, 但是又需要得到你的远程协助, 怎么办呢?
你可以提供一台服务器让客户主动来访问你的服务器, 客户建立这样的反向代理, 然后你通过这个反向代理来连接客户开放的端口如VNC桌面共享, 进行远程协助.
如图 :
Public A是一台公用主机, 可以被客户和服务提供商同时访问.
当客户需要远程协助时.
1. 客户在SERVER C上开启一个VNC server
2. 客户将需要远程协助的窗口先登录好, 例如某些内网服务器(SERVER A , SERVER B)的telnet或ssh终端. 以供服务提供商使用.
3. 客户在SERVER C主动建立和这台公用主机的反向代理, 将端口转发到server c的vnc监听端口.
4. 服务提供商使用VNC客户端连接这台公共服务器的SSH代理监听端口, 相当于连接到了server c的vnc server. 以提供远程协助.
5. 客户可以在server c上观看, 录像, 控制这个VNC会话等.

下面来举个例子 :
场景 :
家里有一台WINDOWS服务器, 通过VPN拨号到公司网络.
WINDOWS服务器上跑了两个VMWARE的虚拟机, 分别是FreeBSD和CentOS.
公司有1台主机172.16.3.150, 安装了CentOS,
拨号后, 家里的虚拟机FreeBSD可以访问172.16.3.150.
现在要让公司的其他服务器如172.16.3.167可以访问到家里的192.168.198.129虚拟机.


简单步骤.
.1. 拨号, 略
.2. 172.16.3.150上需要修改sshd_config.

[root@db-172-16-3-150 ~]# vi /etc/ssh/sshd_config
GatewayPorts yes
[root@db-172-16-3-150 ~]# service sshd reload
Reloading sshd: [ OK ]

.3. 通过虚拟机192.168.198.130连接到172.16.3.150开启反向端口代理. (如果130不是LINUX是WINDOWS, 也可以用securecrt类似的软件进行代理配置.)

root@digoal:~ # ssh -CqTfnN -R 0.0.0.0:7001:192.168.198.129:22 172.16.3.150
root@172.16.3.150's password:

.4. 在172.16.3.150上可以看到这个监听.

[root@db-172-16-3-150 ~]# netstat -anp|grep 7001
tcp 0 0 0.0.0.0:7001 0.0.0.0:* LISTEN 2392/sshd
tcp 0 0 :::7001 :::* LISTEN 2392/sshd

.5. 现在到172.16.3.167上连接172.16.3.150的7001端口.

[root@db5 ~]# ifconfig
bond0 Link encap:Ethernet HWaddr 00:23:7D:A3:F0:4E
inet addr:172.16.3.176 Bcast:172.16.3.255 Mask:255.255.255.0
inet6 addr: fe80::223:7dff:fea3:f04e/64 Scope:Link
UP BROADCAST RUNNING MASTER MULTICAST MTU:1500 Metric:1
RX packets:200422824 errors:0 dropped:0 overruns:0 frame:0
TX packets:16849618 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:23012276676 (21.4 GiB) TX bytes:3567071726 (3.3 GiB)
[root@db5 ~]# ping 172.16.3.150
PING 172.16.3.150 (172.16.3.150) 56(84) bytes of data.
64 bytes from 172.16.3.150: icmp_seq=1 ttl=64 time=0.337 ms --- 172.16.3.150 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.337/0.337/0.337/0.000 ms [root@db5 ~]# ssh -p 7001 172.16.3.150
Password for root@digoal.org:
root@digoal:~ # ifconfig
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
ether 00:0c:29:c0:4b:65
inet 192.168.198.129 netmask 0xffffff00 broadcast 192.168.198.255
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active

到这里反向代理的测试完成.

接下来我们看看如何在反向代理的基础上, 再做一层反向代理.
例如我要在172.16.3.167建立和192.168.198.129的反向代理, 让192.168.198.130通过192.168.198.129来访问172.16.3.150.
.1. 首先要修改192.168.198.129的sshd_config

root@digoal:~ # vi /etc/ssh/sshd_config
GatewayPorts yes
root@digoal:~ # service sshd reload
Performing sanity check on sshd configuration.
root@digoal:~ # exit
logout
Connection to 172.16.3.150 closed.

.2. 在172.16.3.167建立和192.168.198.129的反向代理

[root@db5 ~]# ssh -CqTfnN -p 7001 -R 0.0.0.0:7001:172.16.3.150:22 172.16.3.150
Password for root@digoal.org:

.3. 在192.168.198.129上查看监听.

root@digoal:~ # netstat -AaLnSTW
Current listen queue sizes (qlen/incqlen/maxqlen)
Tcpcb Proto Listen Local Address
fffff800076ce800 tcp4 0/0/128 *.7001

.4. 在192.168.198.130上通过192.168.198.129:7001来访问172.16.3.150:22.

[root@digoal ~]# ssh -p 7001 192.168.198.129
The authenticity of host '[192.168.198.129]:7001 ([192.168.198.129]:7001)' can't be established.
RSA key fingerprint is 01:0b:96:e1:a8:be:a3:a3:69:a4:0a:11:5d:2a:6f:c2.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[192.168.198.129]:7001' (RSA) to the list of known hosts.
root@192.168.198.129's password:
Last login: Sat Jun 14 18:20:23 2014 from 10.0.0.60
[root@db-172-16-3-150 ~]#

[注意]
.1. 当使用vncserver共享桌面时, 有几点需要注意, 需要使用或勾选Shared connection选项, 否则一个连上来, 其他的就会断掉.
.2. 使用vncserver共享桌面, 只要把5901端口共享出来就可以了.
例如
在172.16.3.150建立和172.16.3.221的反向隧道, 代理VNCSERVER端口的反向转发.

# ssh -CqTfnN -p 22 -R 0.0.0.0:5901:172.16.3.150:5901 172.16.3.221

这个使用的是172.16.3.221:5901来代理172.16.3.150:5901
在172.16.3.150开启一个vncserver, 让A主机可以连到这个vncserver.
在A主机开启一个vncviewer, 并打开共享连接, 连接到172.16.3.150:5901
在B主机开启一个vncviewer, 并打开共享连接, 连接到172.16.3.221:5901
最终, A变成了监控机, B是操作方.
B的操作, A可以在VNCVIEWER观看到.
使用完成后, 断开172.16.3.150和172.16.3.221的连接即可, 或者关闭172.16.3.150的vncserver服务即可. vncserver -kill :?.
.3. 如果是跨广域网的隧道, 中间经过的某些网络设备可能会有会话空闲自动断开机制, 为了确保隧道不会被这种机制自动干掉, 我们可以设置一下SSH连接的心跳.

# sysctl -w net.ipv4.tcp_keepalive_time=30
net.ipv4.tcp_keepalive_time = 30
# ssh -CqTfnN -o TCPKeepAlive=yes -o ServerAliveInterval=10 -o ServerAliveCountMax=10 -p 22 -R 0.0.0.0:5901:172.16.3.150:5901 目标IP

现在TCP的心跳时间缩短了, 空闲会自动发送TCP心跳包.

[root@150 ~]# netstat -anpo|grep ssh
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2699/sshd off (0.00/0/0)
tcp 0 0 172.16.3.150:62230 目标IP:22 ESTABLISHED 21721/ssh keepalive (21.48/0/0)

.4. 如果目标机的5901端口监听被占用了, 可以换个端口, 那么使用vncviewer或者其他客户端连接时, 需要使用::port指定端口.
例如172.16.3.150::6666
.5. 考虑到跨广域网的带宽有限问题, vncserver启动时, 最好设置一下位宽, 因为大多数操作不需要那么好的色彩, 例如 :

# vncserver :1 -geometry 1200x700 -depth 8 -cc 3

初次配置时, 输入密码

# vi ~/.vnc/xstartup
#twm &
gnome-session & # vncserver -kill :1
# vncserver :1 -geometry 1200x700 -depth 8 -cc 3

参考
man vncserver

[参考]
.1. http://blog.163.com/digoal@126/blog/static/163877040201141821810103/
.2. http://blog.163.com/digoal@126/blog/static/16387704020115294425540/
.3. http://blog.163.com/digoal@126/blog/static/163877040201342383123592/
.4. man ssh

     -R [bind_address:]port:host:hostport
Specifies that the given port on the remote (server) host is to be forwarded to the given host and port
on the local side. This works by allocating a socket to listen to port on the remote side, and whenever
a connection is made to this port, the connection is forwarded over the secure channel, and a connection
is made to host port hostport from the local machine. Port forwardings can also be specified in the configuration file. Privileged ports can be forwarded only
when logging in as root on the remote machine. IPv6 addresses can be specified by enclosing the address
in square braces or using an alternative syntax: [bind_address/]host/port/hostport. By default, the listening socket on the server will be bound to the loopback interface only. This may be
overridden by specifying a bind_address. An empty bind_address, or the address ‘*’, indicates that the
remote socket should listen on all interfaces. Specifying a remote bind_address will only succeed if the
server’s GatewayPorts option is enabled (see sshd_config(5)). If the port argument is ‘0’, the listen port will be dynamically allocated on the server and reported to
the client at run time.

.5. 
linux 通过ssh代理上网
本网段上网需计费,想到通过另一网段的linux服务器做代理免费上网
前提是你有那台linux主机的帐户
然后打开终端输入

ssh -qTfnN -D 7070 user@host

说明: user是你的帐号,host指对方linux主机的ip

-q Quiet mode. 安静模式,忽略一切对话和错误提示。
-T Disable pseudo-tty allocation. 不占用 shell 了。
-f Requests ssh to go to background just before command execution. 后台运行,并推荐加上 -n 参数。
-n Redirects stdin from /dev/null (actually, prevents reading from stdin). -f 推荐的,不加这条参数应该也行。
-N Do not execute a remote command. 不执行远程命令,专为端口转发度身打造。

然后在浏览器中
如果是firefox:安装autoproxy插件,在代理中选择SSH -D即可。默认情况下的配置就是7070端口,所以可以不用修改配置,否则在首选项中更改服务器设置。
如果是Chrome:安装proxy switchy扩展,添加Proxy Profile,在右侧的socks host中输入127.0.0.1和7070,下方选中socks v5,保存,然后切换至该profile即可。

使用 ssh -R 建立反向/远程TCP端口转发代理的更多相关文章

  1. SSH原理常见应用升级及端口转发

    SSH介绍 SSH是Secure Shell Protocol的简写,由IETF网络工作小组(Network working Group)指定:在进行数据传输之前,SSH先对联机数据包通过加密技术进行 ...

  2. TCP端口转发(centos7)

    =============================================== 2019/2/14_第1次修改                       ccb_warlock == ...

  3. powerCat进行常规tcp端口转发

    实战中,我们也会遇到需要我们进行端口转发的情况,比如已经拿下的目标机1是在dmz区,而目标1所在内网的其他目标只能通过目标1去访问,这时候我们就需要端口转发或者代理来进行后渗透.这次就要介绍一个加强版 ...

  4. 免费内网映射外网绑定,tcp端口转发(windows)

    在tcp socket开发过程中,想要外网客户端映射到本地启动的tcp服务端,总结本地tcp端口映射外网方法: 1.打开ngrok后注册用户,网址 ngrok:https://www.ngrok.cc ...

  5. windows操作系统自带的TCP端口转发

    假定需要通过192.168.1.8的14941端口连接192.168.1.118的1494端口,则需要在192.168.1.8主机的命令行输入如下语句netsh  interface ipv6 ins ...

  6. 全平台正向tcp端口转发工具rinetd的使用

    Linux下做地址NAT有很多种方法.比如haproxy.nginx的4层代理,linux自带的iptables等都能实现.其实,Linux下有一个叫rinetd的工具,安装简单,配置也不复杂. 下载 ...

  7. rinetd基于内网TCP端口转发

    在Linux系统中大多数情况选择用iptables来实现端口转发,iptables虽然强大,但配置不便,而且新手容易出错.在此分享另一个TCP/UDP端口转发工具rinetd,rinetd体积小巧,配 ...

  8. 基于常规DNS隧道进行的tcp端口转发dns2tcp的使用

    0x01 安装Dns2TCP dns2tcp 是一个利用DNS隧道转发TCP连接的工具,使用C语言开发. sudo apt-get install dns2tcp 0x02配置dns2tcp 配置DN ...

  9. cdn贝四层协议配置端口映射TCP端口转发

    端口映射就是将外网主机的IP地址的一个端口映射到内网中一台机器,提供相应的服务.当用户访问该IP的这个端口时,服务器自动将请求映射到对应局域网内部的机器上.端口映射有动态和静态之分 1.安装好节点后初 ...

随机推荐

  1. tab切换webuploader失效的解决方法

    <script type="text/javascript"> $(document).ready(function () { $('#tt').tabs({ bord ...

  2. nginx支持ssl双向认证配置

    nginx支持ssl双向认证配置 listen 443; server_name test.com; ssl on; ssl_certificate server.crt; //server端公钥 s ...

  3. awk 调用 shell 命令,并传递参数

    from:awk 调用 shell 命令的两种方法:system 与 print shell 向awk传递命令,这样使用即可: awk -v  ...  但反过来呢?awk调用外部命令,同时也传参呢? ...

  4. [java] 数据处理

    背景: 有一组30天内的温度与时间的数据,格式如下: 详细情况:共30天的8k+项数据,每天内有260+项,每个记录温度的时间精确到秒 任务就是想根据这样的数据找到规律,来完成给定具体的时间预测出此时 ...

  5. android弹出对话框

    我们在平时做开发的时候,免不了会用到各种各样的对话框,相信有过其他平台开发经验的朋友都会知道,大部分的平台都只提供了几个最简单的实现,如果我们想实现自己特定需求的对话框,大家可能首先会想到,通过继承等 ...

  6. 可视化工具gephi源码探秘(二)

    在上篇<可视化工具gephi源码探秘(一)>中主要介绍了如何将gephi的源码导入myeclipse中遇到的一些问题,此篇接着上篇而来,主要讲解当下通过myeclipse导入gephi源码 ...

  7. 面向对象设计原则 单一职责原则(Single responsibility principle)

    单一职责原则(SRP:Single responsibility principle) 又称单一功能原则,面向对象的基本原则之一.它规定 一个类应该只有一个发生变化的原因. 该原则由罗伯特·C·马丁( ...

  8. bzoj 2753: [SCOI2012]滑雪与时间胶囊 -- 最小生成树

    2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec  Memory Limit: 128 MB Description a180285非常喜欢滑雪.他来到一座雪山,这 ...

  9. 20172308《Java软件结构与数据结构》第四周学习总结

    教材学习内容总结 第 6 章 列表 一. 列表集合 列表集合:一种概念性表示法,思想是使事物以线性列表的方式进行组织 特点: 列表集合没有内在的容量大小,它可以随着需要而增大 列表集合更具一般化,可以 ...

  10. Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) E. Tree Folding 拓扑排序

    E. Tree Folding 题目连接: http://codeforces.com/contest/765/problem/E Description Vanya wants to minimiz ...