SSH端口转发
一、概述
你在咖啡馆享受免费WiFi的时候,是不是担心可能有人正在窃取你的密码及隐私?当你发现这个咖啡馆竟然限制访问某些网站,这时候SSH端口转发功能也许能帮上你的忙。
首先我们知道,SSH会自动加密和解密所有SSH客户端与服务端之间的网络数据。同时SSH还提供了一个非常有用的功能,这就是端口转发。它能够将其他TCP端口的网络数据通过SSH链接来转发,并且自动提供了相应的加密及解密服务。这一过程也被叫做“隧道”(tunneling)
二、动态端口转发
当你在一个不安全的WiFi环境下上网,用SSH动态转发来保护隐私无疑是十分必要的,另外如果就像开始假设的情况,这个咖啡馆限制某些网络的访问,你可以用动态端口转发来解决。
在这个场景我们假设你有一台可以可以连接并信任的SSH服务器,并且这个服务器可以访问internet而且它没有限制你访问。
需要使用这个命令来实现端口转发
1.ssh-D<localport>username@<SSHServer>
复制代码
像这里描述的场景,那个xServer就是充当SSHServer的角色,我们假设它的IP地址是208.53.210.20
localport根据你的习惯来设定,和其他的应用没有冲突就可以了,一般选择大于1024的端口来使用,这里我们使用7000这个端口,username是连接SSHServer的用户名,例如是user
这里只是举例,你需要根据你的情况设置
本地代理设置
打开终端,输入
复制代码
输入密码,这时候没有任何回显,输入完成回车,你已经通过SSH连接了xserver并且在你的MacBook上建立了一个代理服务器,你可以通过xServer的Internet连接来访问互联网了,自然那个咖啡馆的限制对你没有效果了,而且你可以看到从你的MacBook到AirPortExtreme通过Internet到xServer之间的连接和数据传输是加密的
使用
这个代理服务器使用很简单,以Safari为例,打开Safari偏好设置
选择代理,更改设置
选择SOCKS代理,代理服务器地址是本机,填写localhost,端口7000
三、本地转发
使用本地转发的场景还是很多的,这里肯定不能完全枚举,只是说几个典型的应用,如果明白了道理,就可以按照实际的情况发挥了
当然特别强调一点,使用SSH的端口转发特别注意数据传输过程哪部分是加密的哪部分没有加密,不是说使用SSH隧道就是安全的
另外需要说明的是,如果使用SSH隧道“突破”防火墙的制约的时候有可能将本来处于安全防护之内的应用暴露出来,所以对于企业内部通常需要征询网管的同意
使用的命令
1.ssh-L<localport>:<remotehost>:<remoteport><SSHservername>
复制代码
实例一
在企业内部有一台ApplicationServer,它处于防火墙的保护之下,只接受来自AuthorityServer的连接,对于其他IP的请求会拒绝掉,假如我们需要SSH连接ApplicationServer是不是一定要在AuthorityServer上面来操作呢?如下图所示的场景,如果使用我们的电脑通过Internet就不能访问ApplicationServer,通讯过程中数据就是不安全的么?(当然AuthorityServer暴露在公网之下只是讨论这个问题的假设)
当然不是这样,最常规的方式我们可以通过Internet使用SSH登录到AuthorityServer获得shell,然后在AuthorityServer上再SSH到ApplicationServer,这样当然可以,整个数据通讯过程是加密的,就是两次登录有些麻烦
这时候就可以使用本地端口转发,假如AuthorityServer的公网IP地址是,ApplicationServer的内网IP地址是192.168.0.2,当然AuthorityServer和ApplicationServer是有内网路由连通的
在MacBook上输入下面的命令
1.ssh-L7000:192.168.0.2:[email protected]
复制代码
不要关闭这个终端窗口,这时候我们已经通过221.221.144.168建立了本地7000端口到Applicationserver22端口的安全加密连接
再打开一个终端窗口,SSH连接本地7000端口,就可以顺利连接Applicationserver22端口登录获得shell,假如连接ApplicationServer的用户名是AppUser,输入这个命令
1.sshappuser@localhost-p7000
复制代码
是的,你已经发现同样是两次登录,是不是显得更麻烦了,如果稍微改变一下上面的图,ApplicationServer不是一个而是多个都需要管理,那这个方式的优点就显示出来了。这里不仔细说明了,你可以使用.ssh/config文件来配置,一次连接AuthorityServer建立多个ApplicationServer的转发隧道,当然可以使用密钥的方式免除输入很长的复杂密码
1.hostagent
2.Useruser
3.Port22
4.HostName221.221.144.168
5.IdentityFile~/.ssh/id_rsa
6.LocalForward7000192.168.0.2:22"Application1
7.LocalForward7001192.168.0.3:22"Application2
8.LocalForward7002192.168.0.4:22"Application3
9.
10.hostApplication1
11.HostNamelocalhost
12.UserUser1
13.Port7000
14.IdentityFile~/.ssh/id_rsa1
15.
16.hostApplication2
17.HostNamelocalhost
18.UserUser2
19.Port7001
20.IdentityFile~/.ssh/id_rsa2
21.
22.hostApplication3
23.HostNamelocalhost
24.UserUser3
25.Port7002
26.IdentityFile~/.ssh/id_rsa3
复制代码
实例二
在企业网络内部有一台数据库服务器(192.168.0.2,数据库访问端口1521),由于调试的需要想临时从远程机器防火墙外部连接到这个服务器,防火墙限制只能连接SSH端口,拒绝直接连接1521端口,这时候,还是可以使用本地端口转发来解决
1.ssh-L7000:localhost:[email protected]
复制代码
这时候,使用数据库的客户端软件访问本地(SSHClient)的7000端口就可以了
详细解释一下数据流程
*SSHClient上的数据库客户端将数据发送到本机的7000端口上
*本机的SSHClient会将7000端口收到的数据加密并转发到SSHServer上。
*SSHServer会解密收到的数据并将之转发到数据库DBMS服务的1521监听端口上
*最后再将从数据库返回的数据原路返回。
整个流程应用并没有直接连接数据库服务器的1521,而是连接到了本地的一个监听端口,SSH端口转发在幕后完成了其余的所有事情,加密,转发,解密,通讯。
需要说明的问题
前面说了本地端口转发的命令是
1.ssh-L<localport>:<remotehost>:<remoteport><SSHservername>
复制代码
在实例二中,却使用这个命令
1.ssh-L7000:localhost:[email protected]
复制代码
1命令中的<remotehost>和<SSHhostname>必须是同一台机器么?
不是一台主机的情况更为普遍,下面有说明
2你可能会疑惑上面命令中的<remotehost>为什么用localhost,它指向的是哪台机器呢?这样的设置对么?
使用localhost的配置,
指向的是DataBaseServer。如果看过讲到的数据流程,localhost是由sshserver来解析的
为什么用localhost而不是IP地址或者主机名?
其实这取决于如何限制DBMS访问的,如果只允许lookback接口访问的话,那自然就只有localhost或者IP为127.0.0.1才能访问,
如果没有限制,那使用192.168.0.2或者主机名自然也是可以的。
1.ssh-L7000:192.168.0.2:[email protected]
四、远程端口转发
命令是:
1.ssh-R<localport>:<remotehost>:<remoteport><SSHservername>
复制代码
和本地转发的第二个实例一样,只是假设由于网络或防火墙的原因不能用SSH从Macbook(192.168.0.3)连接到DatabaseServer(192.168.0.2,数据库访问端口1521),但是反向连接是允许的。这时候就可以使用远程端口转发。
在数据库服务器(SSHClient)端执行如下命令:
1.ssh-R7000:localhost:[email protected]
复制代码
和本地端口转发相比,这个场景,只是SSHServer和SSHClient的位置交换了一下。
数据流程和本地转发完全一致
*在DatabaseClient的应用将数据发送到本机的7000端口
*本机的SSHServer将7000端口收到的数据加密并转发到SSHClient上
*SSHClient解密收到的数据,并转发到DBMS监听的1521端口上
*最后将从DBMS获取的数据原路返回。
五、本地转发与远程转发
本地转发,远程转发有什么区别?
转自:《ssh权威指南》读书笔记中的总结
*在本地转发中,应用程序客户端与监听端同SSH客户端在一起,应用程序服务器同SSH服务器在一起。
*在远程转发中,应用程序客户端与监听端同SSH服务器在一起,应用程序服务器同SSH客户端在一起。
PS:也不是很明确,我知道如何使用,但是真的很难说明白
什么时候使用本地转发,什么时候使用远程转发?
根据你的网络情况和防火墙的规则情况选择使用本地转发和远程转发
如果你所在的环境下,既允许发起SSH连接到SSHServer,也允许作为SSHServer接受远程SSH连接。
这时选择本地转发或远程转发都是可以的,能完成一样的功能。
六、多机转发
在4楼的第二个实例中提到SSHserver和数据库服务器是不是一定是一台主机
当然不是,请求其他的应用服务器是很常见的应用
以本地端口转发为例(远程端口转发是类似的)
在企业网络内部有一台数据库服务器(192.168.0.3,数据库访问端口1521),我们不能直接连接这个服务器;但是我们可以连接SSHServer(192.168.0.2),并通过SSHServer来请求DBMS,这是本地端口转发的一个典型应用
1.ssh-L7000:192.168.0.3:[email protected]
复制代码
*SSHClient上的数据库客户端将数据发送到本机的7000端口上
*本机的SSHClient会将7000端口收到的数据加密并转发到SSHServer上。
*SSHServer会解密收到的数据并将之转发到另一台主机上的DBMS服务的1521监听端口上
*最后再将从数据库返回的数据原路返回。
七、X转发
X应用转发
八、总结
主要参数和作用
*-gAllowsremotehoststoconnecttolocalforwardedports.
在SSHClient执行
1.ssh-g-L7000:192.168.0.3:1521192.168.0.2
复制代码
然后在数据库应用的客户端上配置连接SSHClient(192.168.1.2)的7000端口即可。
没有指定-g参数的情况下,7000这个端口只接受本机的连接,指定-g参数SSHClinet的7000端口可以接受其他主机的连接
这样的设置,可以允许部署在其他机器上的DatabaseClient访问SSHClinet的7000端口,就好像直接访问Database的1521端口一样
*-fRequestssshtogotobackgroundjustbeforecommandexecution.
*-NDonotexecutearemotecommand.(protocolversion2only)
这两个参数很多时候一起使用,在使用ssh-D动态端口转发代理功能的时候,很多人大多使用iSSH等第三方软件来实现,担心关闭终端启用这个代理端口的进程也随之结束,这时候可以这样使用
动态转发实例
复制代码
本地转发实例
1.ssh-L7000:192.168.0.3:1521-fN192.168.0.2
复制代码
使用lsof命令,找到后台进程,使用kill命令结束进程,
1.lsof-i:7000
复制代码
PS:这个命令可以写成脚本,我的shell脚本是在quicksilver里面执行的
安全
在上图所示的上述连接中的红色连线,Database<->SSHClinet以及SSHServer<->DatabaseServer之间的连接并不是安全连接,它们之间没有经过SSH的加密及解密。如果他们之间的网络并不是值得信赖的网络连接,我们就需要谨慎使用这种连接方式了。
回顾和思路
介绍了本地端口转发,远程端口转发,动态端口转发以及X转发的介绍。
SSH端口转发能够提供两个主要功能:
*加密SSHClient端至SSHServer端之间的通讯数据。
*突破防火墙的限制完成一些之前无法建立的TCP连接。
*对一些已知端口号的应用,例如Telnet/SMTP,我们可以使用本地端口转发或者远程端口转发来达到目的。
*动态端口转发则可以实现SOCKS代理从而实现更安全的加密的Web浏览。
*更方便的X应用
*灵活的使用-g-f-N参数
* 注意端口转发的安全问题另篇:
ssh 是有端口转发功能的。
ssh的三个强大的端口转发命令:
QUOTE:
ssh-C-f-N-g-Llisten_port:DST_Host:DST_portuser@Tunnel_Host
ssh-C-f-N-g-Rlisten_port:DST_Host:DST_portuser@Tunnel_Host
ssh-C-f-N-g-Dlisten_portuser@Tunnel_Host
-fForkintobackgroundafterauthentication.
后台认证用户/密码,通常和-N连用,不用登录到远程主机。
-pportConnecttothisport.Servermustbeonthesameport.
被登录的ssd服务器的sshd服务端口。
-Lport:host:hostport
将本地机(客户机)的某个端口转发到远端指定机器的指定端口.工作原理是这样的,本地机器上分配了一个socket侦听port端口,一旦这个端口上有了连接,该连接就经过安全通道转发出去,同时远程主机和host的hostport端口建立连接.可以在配置文件中指定端口的转发.只有root才能转发特权端口.IPv6地址用另一种格式说明:port/host/hostport
-Rport:host:hostport
将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口.工作原理是这样的,远程主机上分配了一个socket侦听port端口,一旦这个端口上有了连接,该连接就经过安全通道转向出去,同时本地主机和host的hostport端口建立连接.可以在配置文件中指定端口的转发.只有用root登录远程主机才能转发特权端口.IPv6地址用另一种格式说明:port/host/hostport
-Dport
指定一个本地机器“动态的'’应用程序端口转发.工作原理是这样的,本地机器上分配了一个socket侦听port端口,一旦这个端口上有了连接,该连接就经过安全通道转发出去,根据应用程序的协议可以判断出远程主机将和哪里连接.目前支持SOCKS4协议,将充当SOCKS4服务器.只有root才能转发特权端口.可以在配置文件中指定动态端口的转发.
-CEnablecompression.
压缩数据传输。
-NDonotexecuteashellorcommand.
不执行脚本或命令,通常与-f连用。
-gAllowremotehoststoconnecttoforwardedports.
在-L/-R/-D参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接