• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

Linux下的SSH端口转发

实用教程 开心洋葱 2686次浏览 0个评论

任务一:正向端口转发

  现在开始我们的第一个任务:假设主机D上面安装有数据库服务,监听的端口是8888,如果我想通过Office域中的主机A直接访问D主机中的数据库那该怎么办呢?这就要用到SSH的正向端口功能了。在这先要说明一下,在Linux中,所有的端口转发的操作都可以通过使用自带的工具ssh来完成。

  完成任务一的命令很简单,如下:

  ssh -L 8000:host-d.prod.mycompany.com:8888 oracle@host-c.prod.mycompany.com -N

  现在解释一下上面的命令:

  参数-L

  表示在本地开启监听的端口,后面紧跟的参数格式为::,表示将本地的8000端口转发到远程主机D的8888端口。

  orainst@host-c.prod.mycompany.com

  这个参数指定要使用ssh登录的主机以及登录的用户名,这里使用的主机和前一个参数中的主机必须是在同一个网域当中,并且能相互访问,当然也可以是同一个机器。

  参数-N

  不执行远程的命令。这个参数在这里是可选的。

  现在在主机A上面运行上面的命令之后输入正确的密码,然后我们先登录主机A查看一下当前端口的状态:

  oracle@host-a[orcl]:~$ netstat -natp|grep 8000

任务二:反向端口转发

  因为网域Prod不能以任何的方式访问网域Office,假设这两个网域所处的物理位置完全的不同,那当那一天处于网域Prod的时候又想操作处于网域Office中的主机A,那怎么办呢?这就是要用到反向端口转发的时候了。

反向端口转发的基本思想就是从主机A建立到主机C的ssh连接的同时在主机C上打开一个端口可以反向连接到主机B上面的某一个端口,当然从主机控制上面来说连接到主机B的22(ssh端口)是最实惠的了,现在要做的就是在主机A上面运行如下的命令:

  ssh -R 8888:localhosthost-b.office.mycompany.com:22 oracle@host-c.prod.mycompany.com -N

  同样的,先解释下上面的命令:

  参数-R

  创建一个反向的端口转发,后面紧跟的参数格式为 ::,这里监听的端口是8888,反向连接要到C主机原来根本无法访问的主机B的22端口。

  oracle@host-c.prod.mycompany.com

  这个参数指定要使用ssh登录的主机以及登录的用户名,这里使用的主机和前一个参数中的主机必须是在同一个网域当中,并且能相互访问,当然也可以是同一个机器。

  参数-N

  不执行远程的命令。这个参数在这里是可选的。

 

任务三:动态端口转发

  动态端口转发实际上是建立一个ssh加密的SOCKS4/5代理通道,任何支持SOCKS4/5协议的程序都可以使用这个加密的通道来进行代理访问,现在这种方法最常用的地方就是翻墙了,使用的方法也很简单,命令如下:

  ssh -D 8888 username@proxyhost.mycompany.com -N

  命令解释:

  参数-D

  建立一个动态的SOCKS4/5的代理通道,紧接着的是本地监听的端口号。

  username@proxyhost.mycompany.com

  这个参数指定要使用ssh登录的主机以及登录的用户名,这里使用的主机和前一个参数中的主机必须是在同一个网域当中,并且能相互访问,当然也可以是同一个机器。

  参数-N

  不执行远程的命令。这个参数在这里是可选的。

 
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".
这种方法适用于本地网络中其他服务器想访问远程的服务器, 但是其他服务器没有直接访问远程服务器的权限, 通过本地网络中有权限的服务器做端口转发的场景.
 
还有一种应用场景是这样的, 本地网络环境中没有任何一台服务器可以直接访问远程服务器, 但是远程服务器可以反过来访问本地的某台服务器, 这样的话也能实现本地服务器去访问远程服务器的目的. 这就是反向代理.
实际的应用场景如, 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的反向端口转发, 或远程端口转发.
 
使用 ssh -R 建立反向/远程TCP端口转发代理 - 德哥@Digoal - PostgreSQL
 
反向代理应用场景.

例如, 以下虚线表示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 )

使用 ssh -R 建立反向/远程TCP端口转发代理 - 德哥@Digoal - PostgreSQL
 
这种反向代理的用法很容易应用到实际的场景中, 例如前面提到的 :
有的客户可能不希望提供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会话等.
 
使用 ssh -R 建立反向/远程TCP端口转发代理 - 德哥@Digoal - PostgreSQL

下面来举个例子 : 
场景 : 
家里有一台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虚拟机.
 
使用 ssh -R 建立反向/远程TCP端口转发代理 - 德哥@Digoal - PostgreSQL

简单步骤.

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 1200×700 -depth 8 -cc 3 
初次配置时, 输入密码
# vi ~/.vnc/xstartup 
#twm &
gnome-session &

 
# vncserver -kill :1
# vncserver :1 -geometry 1200×700 -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


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明Linux下的SSH端口转发
喜欢 (0)

您必须 登录 才能发表评论!

加载中……