http://loopholes.blog.51cto.com/9445813/1621786
之前一直在纠结什么是端口转发,现在写下自己的理解,并试验本地端口,远程端口转发
SSH(Secure Shell,安全外壳协议),在SSH的通道上传输数据都是通过加密的,每次连接SSH会执行指纹核对来确认用户连接到正确的远程主机上,如果在其它协议的数据通过SSH端口进行转发,SSH连接作为其它协议传输的通道(隧道),这种方式也叫做SSH端口转发或SSH隧道.
作用:加密数据传输、突破防火墙限制
分类:本地转发、远程转发、动态转发
一、本地端口转发
本地转发中的本地是指将本地的某个端口转发到其他主机的某个端口,这样当我们的程序连接本地的这个端口时,其实间接连上了其他主机的某个端口,当我们发数据包到这个端口时数据包就自动转发到了那个远程端口上了
命令语法:ssh -L [bind-address:]port:host:hostport server_address
解释下:bind_address表示本地主机的ip(绑定地址),这是针对系统有多块网卡,不指定默认是127.0.0.1
port:本地主机指定监听的端口
host:远程主机的ip
hostport:指定远程主机的端口,如果远程主机是HTTP,就是80,FTP(21)。。。
server_address:远程主机的ip,也可以是能够访问到远程主机的另一个ip(我们通过实验来理解)
另外有几个参数需要知道:
-L:指定本地(客户端)主机上的指定端口转发到给定的远端的主机和端口
-N:不执行远程指令
- f:放在后台执行
实验:主机A(192.168.31.100)、主机B(192.168.31.150)、主机C(192.168.31.163)三台主机
A、B、C都可以互相连接
在主机A上执行命令:# ssh -Nf -L 192.168.31.100:7900:192.168.31.163:22 192.168.31.150
这里需要注意的是本例中我们选择了 7900 端口作为本地的监听端口,在选择端口号时要注意非管理员帐号是无权绑定 1-1023 端口的,所以一般是选用一个 1024-65535 之间的并且尚未使用的端口号即可。
当执行完这条命令后,我们发现终端没有反应,那是因为放到后台执行了,那我们怎么知道是否开启了端口转发?
netstat -nt:列出tcp网络数据的端口
netstat -ntlp:列出系统已在监听的网络连接端口及PID
上图我们发现,主机A的7900端口已被监听了,是被ssh(ssh就是客服端)监听的,和192.168.31.150(主机B)建立了一个SSH隧道,并且我们知道主机B和主机C是可以通信的,我们可以通过主机A的端口访问时,其实就是间接用主机B在访问,为了效果我们可以用主机C访问主机A:(-p:是指定远程端口)
在主机C上执行:ssh 192.168.31.100 -p 7900(如果没有隧道前,主机C登录主机A时,登陆的ip肯定是主机C的ip,有了隧道后,通过主机A的端口和主机B建立的隧道,就是主机B在登录的ip)
上面我们说到命令语法:ssh -L [bind-address:]port:host:hostport server_address
server_address 可以和host不一样,也可以一样
# ssh -Nf -L 192.168.31.100:7900:192.168.31.163:22 192.168.31.163
上面这条的意思是,“192.168.31.100”和“192.168.31.163”建立一个ssh隧道,
只要通过192.168.31.100这台主机的“端口”访问,就相当于是192.168.31.163这台主机在访问
实验二:主机C(192.168.31.163)不允许主机A访问,但是允许主机B访问,通过ssh隧道实现A访问C
搭建环境:在主机C上为了不让主机A访问,可以在/etc/hosts.deny这个配置文件中添加一行:“sshd:192.168.31.100”,加上主机A的ip即可,连接已被关闭
环境搭好了,我们在主机A上执行:ssh -Nf -L 192.168.31.100:9000:192.168.31.163:22 192.168.31.163
隧道有了,我们在被拒绝访问的主机A上执行:ssh -p 9000 192.168.31.100(意思是连接主机A的9000端口,而9000端口又与主机B连成隧道,当用主机A的9000端口访问时,则是在用主机B访问,所以主机A被禁止访问也无妨)
最后需要提醒的是,如果想关闭某个ssh隧道,只能用kill杀死相关进程,隧道被关闭后,指定的连接也会关闭。
二、远程端口转发可以实现访问内网
SSH远程端口转发:
远程转发和本地很相似,原理也差不多,但是不同的是,本地转发是在本地主机指定的一个端口,而远程转发是在远程的主机上指定一个端口将指向该端口的连接转发到本地端口。本质一样,区别在于需要转发的端口是在远程主机上还是在本地主机山。
但远程转发使用的命令选项也不同:
ssh -R [bind-address:]post:host:hostport server_address
这里需要注意的是:
bind-address指定的是远程主机ip,不是本机
port:远程主机指定监听的端口
host:你需要访问的主机
hostport:指定被访问主机的端口
server_address:远程主机和谁?建立的隧道,指定谁
我们都知道内网通过路由器(SNAT)可以访问外网,而外网是无法访问到内网的,我们利用ssh来实现访问内网,要搭建这种环境,我首先想到的是VMware的NAT模式,我将主机C设置NAT模式
主机A:192.168.31.100(外网)
主机B:192.168.31.150(外网)
主机C:192.168.200.133(内网)
在主机C执行命令:ssh -Nf -R 192.168.31.150:9000:192.168.200.133:22 192.168.31.150
netstat -nt:
主机C已经和192.168.31.150(主机B)建立好隧道了
这时你在主机C上执行 netstat -ntlp 并没有什么监听的9000端口,因为你是在对方主机上开的一个端口,你需要在主机B上执行netstat -ntlp:
我们发现,127.0.0.1:9000这是什么意思呢?这是说指本机,并没有随便指定一个ip,那样太危险,后面也变成sshd监听,就是ssh服务端,所以我们也叫 反向隧道。
在外网的主机B上执行:ssh -p 9000 127.0.0.1
主要不再是ssh -p 9000 192.168.31.150了,完成