openKylin论坛

 找回密码

[原创]Ssh Tunnel简介 [复制链接]

Ssh Tunnel,即通常所说的Ssh隧道,其基本原理非常简单,如下图所示:

从图中可以看到,由于防火墙的设置,客户端浏览器Firefox想要直接访问Web服务器Nginx是不行的;但经过ssh工具可在客户端和服务器之间建立一条Ssh隧道,而Firefox直接访问本地的12345端口即可间接的访问到Nginx,这是否很神奇?

怎么做到的?从操作上来说,有两种方法可以做到。
1,在客户端上操作(假设为Linux系统,因此采用ssh命令):
$ ssh -Nf -L 127.0.0.1:12345:192.168.30.163:80 lenky@192.168.30.163

用Firefox访问Web服务端口:http://127.0.0.1:12345/
查看当前连接,客户端的情况:  
lenky@lenky-local:~$ sudo netstat -natp | grep 12345
tcp        0      0 127.0.0.1:12345         0.0.0.0:*               LISTEN      4011/ssh
tcp        0      0 127.0.0.1:12345         127.0.0.1:52194         ESTABLISHED 4011/ssh
tcp        0      0 127.0.0.1:52194         127.0.0.1:12345         ESTABLISHED 2604/firefox
lenky@lenky-local:~$ sudo netstat -natp | grep ssh
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      925/sshd
tcp        0      0 127.0.0.1:12345         0.0.0.0:*               LISTEN      4011/ssh
tcp        0      0 192.168.30.162:57567    192.168.30.163:22       ESTABLISHED 4011/ssh
tcp6       0      0 :::22                   :::*                    LISTEN      925/sshd

即:Firefox(52194) <---> Ssh(12345)

服务器端情况:
   
lenky@lenky-VirtualBox:~$ sudo netstat -natp
激活Internet连接 (服务器和已建立连接的)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3463/nginx: master
tcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN      955/dnsmasq
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      3185/sshd
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      754/cupsd
tcp        0      0 192.168.30.163:22       192.168.30.162:57567    ESTABLISHED 4115/sshd: lenky [p
tcp        0      0 192.168.30.163:47634    192.168.30.163:80       ESTABLISHED 4208/sshd: lenky
tcp        0      0 192.168.30.163:80       192.168.30.163:47634    ESTABLISHED 3464/nginx: worker
tcp6       0      0 :::80                   :::*                    LISTEN      3463/nginx: master
tcp6       0      0 :::22                   :::*                    LISTEN      3185/sshd
tcp6       0      0 ::1:631                 :::*                    LISTEN      754/cupsd
tcp6       1      0 ::1:45743               ::1:631                 CLOSE_WAIT  847/cups-browsed

即:Ssh(47634) <---> Nginx(80)

整个连接起来就是:
(Firefox(52194) <---> Ssh(12345))客户端 <---> Ssh(192.168.30.162:57567) <---> Ssh(192.168.30.163:22) <---> 服务器(Ssh(47634) <---> Nginx(80))

2,在服务器端操作(假设同样是Linux系统,因此采用ssh命令):
$ ssh -Nf -R 127.0.0.1:12345:192.168.30.163:80 lenky@192.168.30.162

在客户端用Firefox访问Web服务端口:http://127.0.0.1:12345/
查看当前连接,客户端的情况:
   
lenky@lenky-local:~$ sudo netstat -natp | grep 12345
tcp        0      0 127.0.0.1:12345         0.0.0.0:*               LISTEN      4445/sshd: lenky
tcp        0      0 127.0.0.1:52207         127.0.0.1:12345         ESTABLISHED 2604/firefox
tcp        0      0 127.0.0.1:12345         127.0.0.1:52206         TIME_WAIT   -
tcp        0      0 127.0.0.1:12345         127.0.0.1:52207         ESTABLISHED 4445/sshd: lenky
tcp6       0      0 ::1:12345               :::*                    LISTEN      4445/sshd: lenky
lenky@lenky-local:~$ sudo netstat -natp | grep ssh
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      925/sshd
tcp        0      0 127.0.0.1:12345         0.0.0.0:*               LISTEN      4445/sshd: lenky
tcp        0      0 127.0.0.1:12345         127.0.0.1:52207         ESTABLISHED 4445/sshd: lenky
tcp        0      0 192.168.30.162:22       192.168.30.163:55747    ESTABLISHED 4325/sshd: lenky [p
tcp6       0      0 :::22                   :::*                    LISTEN      925/sshd
tcp6       0      0 ::1:12345               :::*                    LISTEN      4445/sshd: lenky

即:Firefox(52207) <---> Ssh(12345)

服务器端情况:
   
lenky@lenky-VirtualBox:~$ sudo netstat -antp
激活Internet连接 (服务器和已建立连接的)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3463/nginx: master
tcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN      955/dnsmasq
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      3185/sshd
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      754/cupsd
tcp        0      0 192.168.30.163:47641    192.168.30.163:80       ESTABLISHED 4344/ssh
tcp        0      0 192.168.30.163:80       192.168.30.163:47641    ESTABLISHED 3464/nginx: worker
tcp        0      0 192.168.30.163:55747    192.168.30.162:22       ESTABLISHED 4344/ssh
tcp6       0      0 :::80                   :::*                    LISTEN      3463/nginx: master
tcp6       0      0 :::22                   :::*                    LISTEN      3185/sshd
tcp6       0      0 ::1:631                 :::*                    LISTEN      754/cupsd
tcp6       1      0 ::1:45743               ::1:631                 CLOSE_WAIT  847/cups-browsed

即:Ssh(47641) <---> Nginx(80)

整个连接起来就是:
(Firefox(52207) <---> Ssh(12345))客户端 <---> Ssh(192.168.30.162:22) <---> Ssh(192.168.30.163:55747) <---> 服务器(Ssh(47641) <---> Nginx(80))

上面用到的ssh命令的格式说明如下(更具体的介绍请看man手册):
ssh -C -f -N -g -L [bind_address:]listen_port:DST_Host:DST_port user@Tunnel_Host
ssh -C -f -N -g -R [bind_address:]listen_port:DST_Host:DST_port user@Tunnel_Host
其中-L和-R的参数格式为[要打开的监听IP:]要打开的监听端口:要映射到的监听 IP:要隐射到的监听端口,监听IPbind_address默认为127.0.0.1。

-f Fork into background after authentication.
后台认证用户/密码,通常和-N连用,不用登录到远程主机。
-p port Connect to this port. Server must be on the same port.
被登录的ssd服务器的sshd服务端口。
-L port:host:hostport
将本地机(客户机)的某个端口转发到远端指定机器的指定端口. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同时远程主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
-R port:host:hostport
将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口. 工作原理是这样的, 远程主机上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转向出去, 同时本地主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有用 root 登录远程主机才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
-D port
指定一个本地机器 “动态的'’ 应用程序端口转发. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 根据应用程序的协议可以判断出远程主机将和哪里连接. 目前支持 SOCKS4 协议, 将充当 SOCKS4 服务器. 只有 root 才能转发特权端口. 可以在配置文件中指定动态端口的转发.
-C Enable compression.
压缩数据传输。
-N Do not execute a shell or command.
不执行脚本或命令,通常与-f连用。
-g Allow remote hosts to connect to forwarded ports.
在-L/-R/-D参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接。

总得来说,Ssh Tunnel通常主要是实现3个基本功能:
1) 数据加密传输:采用了SSH加密。
2) 穿透防火墙:作为通用端口22或443,大多被防火墙放通。
3) 远程接入:这属于第1个功能的延生,在SSL VPN里应用得淋漓尽致。
楼主
发表于 2013-12-24 11:03:01
回复

使用道具 举报

openKylin

GMT+8, 2024-5-13 13:48 , Processed in 0.028429 second(s), 20 queries , Gzip On.

Copyright ©2022 openKylin. All Rights Reserved .

ICP No. 15002470-12 Tianjin

快速回复 返回顶部 返回列表