Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15502424
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2010-03-25 14:55:27

深入理解ssh端口转发细节

一.本地端口转发
A机: 172.16.32.123
B机: 172.16.32.102, 10.0.0.2
C机: 10.0.0.1
(说明:C机与B机直连,C机无网关设置,只能与B机进行通信)

B机:(可以使用netstat -nap |grep 7001看到B机上启动了一个监听7001端口的服务)
luther@gliethttp:~$ ssh -CfNg -L 7001:localhost:22 luther@10.0.0.1

A机:(连接B机上的7001端口,因为B机将7001端口监听到的数据,直接转发给了C机,所以A将成功登录到C机)
luther@gliethttp:~$ ssh -p 7001 luther@172.16.32.102
     这样A机就一下子连接到ip地址为10.0.0.1的C机了,实现了连接穿透.

让我们来仔细理解理解,A和C之间因不位于同一网段而不可见,B和A可见,B和C可见,
于是B就可以担当起转发A数据到C的角色.

连接图:A <=> B <==> C

ssh -L ::

我们再来拆解一下语句:
1. B和C建立ssh连接
ssh luther@10.0.0.1
2. 参数-CfNg -L的解释
C - 压缩数据传输
f - 后台用户验证,允许没有shell的不可登陆账号使用
N - 不执行脚本或命令
g - 允许远程主机连接转发端口
L - 本地转发
3. 7001
表示ssh语句执行时,会同时在B机上由ssh命令自动开启一个监听B机上7001端口的service服务
4. :localhost:22
   这个是最不易搞懂的地方,关键是这个参数是由谁来使用,当B机执行ssh的时候,C机上的ssh server
   会接受B机的ssh连接,同时B机的参数:localhost:22被传递到C机的ssh server行,ssh server会解析
   这个参数,C机上的ssh server会将B机ssh发送过来的数据,转发到端口上.
可以使用如下实例验证:
a机: 172.16.32.102
b机: 172.16.32.123
c机: 172.16.32.112
d机: 172.16.32.54

只需要在b机上运行
luther@gliethttp:~$ ssh -CfNg -L 7001:172.16.32.112:22 luther@172.16.32.102
然后在d机上运行
luther@gliethttp:~$ ssh -p 7001 172.16.32.123
数据流图:
d <=> b <=> a <=> c
d机连接b机7001端口,b机将d机发送的数据转发到a机的ssh server上,a机的ssh server根据
参数:即:172.16.32.112:22的定义,
将接收的数据进一步转发到端口上,也就是172.16.32.112的22端口上,
所以d机最终和c机建立了ssh连接[luther.gliethttp]

二.远端端口转发
另一种ssh端口转发方式是使用参数-R,而不是-L.

ssh -R ::
A机: 172.16.32.123
B机: 172.16.32.102, 10.0.0.2
C机: 10.0.0.1
(说明:C机与B机直连,C机无网关设置,只能与B机进行通信)

B机:运行如下命令
luther@gliethttp:~$ ssh -CfNg -R 7001:localhost:22 luther@10.0.0.1

C机:查看由C机上ssh server根据B机ssh连接的参数-R 7001创建的监听端口7001
     我们在C机上使用netstat -nap |grep 7001看到C机上启动了一个监听7001端口的服务,
     而C机上这个监听7001端口的服务是C机的ssh server根据B机执行ssh连接时的
     参数-R 7001而由C机ssh server被动建立起来的.

同时C机上只能使用如下命令和C机自己身上的7001端口建立连接,不能使用ip地址,包括(10.0.0.1)
luther@gliethttp:~$ ssh -p 7001 luther@localhost
或者
luther@gliethttp:~$ ssh -p 7001 luther@127.0.0.1
以上2条命令使得C机可以ssh到B机.
另外也可以和上面-L一样,
B机:运行如下命令
luther@gliethttp:~$ ssh -CfNg -R 7001:172.16.32.123:22 luther@10.0.0.1
这时B机建立与C机的ssh,同时通知C机的ssh server,在C机上开启一个监听端口7001,
这样C机向C机本地的7001端口发送数据的时候,B机就能接收到,然后B机将根据
参数:172.16.32.123:22信息,将C机发送过来的数据转发到A机172.16.32.123的22端口
于是C机执行
ssh -p 7001 luther@localhost
就是等于向A机172.16.32.123的22端口发出ssh连接[luther.gliethttp]

三.比较本地端口转发-L和远端端口转发-R:
ssh -L ::
ssh -R ::
参数-L就是监听端口在执行ssh的机器上建立,参数:主机处理
参数-R就是监听端口在主机上建立,参数:由执行ssh的机器处理

四.动态端口转发-D,设置SOCKS4和SOCKS5代理功能
B机: 172.16.32.102, 10.0.0.2
C机: 10.0.0.1
在C机上执行
ssh -CfNg -D 7001 luther@10.0.0.2
这样C机上将建立一个7001监听端口,C机可以向7001端口发送任何数据,然后B机10.0.0.2会将C机发送的数据
根据C机发送数据的端口号,动态的向外部递交,一般用在SOCKS代理,
C机的localhost:7001就是代理参数,可以在firefox上设置,这样C机就能通过B机上web网了.
到这里我们可以看出-L就是-D的一个具体实例使用,但是-D不能像-L一样,与指定的端口建立连接,所以-D使用在
SOCKS代理上[luther.gliethttp].
Firefox==>Edit==>Preferences==>Advanced
==>Network/Settings==>Manual proxy configuration
==>SOCKS Host: localhost
==>SOCKS Port: 7001
这样C机就能使用firefox上网了[luther.gliethttp]
(注意:因为C机的网关和DNS都没有设置,所以只能使用firefox中直接输入ip的方式上网,
比如的ip地址为64.233.189.103).

五.X协议转发,实现ssh直接打开主机上的GUI程序
A机(redhat): 172.16.32.102
B机(ubuntu): 172.16.32.123
首先A机进入桌面环境,打开一个terminal,
输入
luther@gliethttp:~$ ssh -X root@172.16.32.123  注意-X大写使能X11转发,-x小写禁用X11转发
但是缺点是只能查看,不能拖动拷贝到本机
[root@localhost ~]# firefox         执行远程机172.16.32.123上的firefox程序
[root@localhost ~]# nautilus /      执行远程机172.16.32.123上的nautilus文件浏览器

总结:
A机公司局域网
B机公网linux主机
C机家里的notebook
A机:
luther@gliethttp:~$ ssh -CfNg -R 7001:localhost:22     用户名@B机
C机:
luther@gliethttp:~$ ssh -CfNg -L 7000:localhost:7001   用户名@B机
C机:
luther@gliethttp:~$ ssh -p 7000 A机用户名@localhost    就可以登录公司的A机了
C机:
luther@gliethttp:~$ ssh -X -p 7000 A机用户名@localhost 就可以执行A机上的图形程序了,比如nautilus .
阅读(1778) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~