`

SSH端口转发

 
阅读更多

一、概述
你在咖啡馆享受免费 WiFi 的时候,是不是担心可能有人正在窃取你的密码及隐私?当你发现这个咖啡馆竟然限制访问某些网站,这时候SSH端口转发功能也许能帮上你的忙。

首先我们知道,SSH 会自动加密和解密所有 SSH 客户端与服务端之间的网络数据。同时SSH 还提供了一个非常有用的功能,这就是端口转发。它能够将其他TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务。这一过程也被叫做“隧道”(tunneling)

二、动态端口转发

当你在一个不安全的 WiFi 环境下上网,用SSH动态转发来保护隐私无疑是十分必要的,另外如果就像开始假设的情况,这个咖啡馆限制某些网络的访问,你可以用动态端口转发来解决。
在这个场景我们假设你有一台可以可以连接并信任的SSH服务器,并且这个服务器可以访问internet而且它没有限制你访问。


需要使用这个命令来实现端口转发

   1. ssh -D <local port> username@<SSH Server>

复制代码
像这里描述的场景,那个xServer就是充当SSH Server的角色,我们假设它的IP地址是208.53.210.20
local port根据你的习惯来设定,和其他的应用没有冲突就可以了,一般选择大于1024的端口来使用,这里我们使用7000这个端口,username是连接SSH Server的用户名,例如是user
这里只是举例,你需要根据你的情况设置

本地代理设置
打开终端,输入

   1. ssh -D 7000 user@208.53.210.20

复制代码
输入密码,这时候没有任何回显,输入完成回车,你已经通过SSH连接了xserver并且在你的MacBook上建立了一个代理服务器,你可以通过 xServer的Internet连接来访问互联网了,自然那个咖啡馆的限制对你没有效果了,而且你可以看到从你的MacBook到AirPort Extreme通过Internet到xServer之间的连接和数据传输是加密的

使用
这个代理服务器使用很简单,以Safari为例,打开Safari偏好设置
选择代理,更改设置

选择SOCKS代理,代理服务器地址是本机,填写localhost,端口7000

三、本地转发

使用本地转发的场景还是很多的,这里肯定不能完全枚举,只是说几个典型的应用,如果明白了道理,就可以按照实际的情况发挥了
当然特别强调一点,使用SSH的端口转发特别注意数据传输过程哪部分是加密的哪部分没有加密,不是说使用SSH隧道就是安全的
另外需要说明的是,如果使用SSH隧道“突破”防火墙的制约的时候有可能将本来处于安全防护之内的应用暴露出来,所以对于企业内部通常需要征询网管的同意

使用的命令

   1. ssh -L <local port>:<remote host>:<remote port> <SSH servername>

复制代码
实例一
在企业内部有一台Application Server,它处于防火墙的保护之下,只接受来自Authority Server的连接,对于其他IP的请求会拒绝掉,假如我们需要SSH连接Application Server是不是一定要在Authority Server上面来操作呢?如下图所示的场景,如果使用我们的电脑通过Internet就不能访问Application Server,通讯过程中数据就是不安全的么?(当然Authority Server暴露在公网之下只是讨论这个问题的假设)

当然不是这样,最常规的方式我们可以通过Internet使用SSH登录到Authority Server获得shell,然后在Authority Server上再SSH到Application Server,这样当然可以,整个数据通讯过程是加密的,就是两次登录有些麻烦

这时候就可以使用本地端口转发,假如Authority Server的公网IP地址是,Application Server的内网IP地址是192.168.0.2,当然Authority Server和Application Server是有内网路由连通的
在MacBook上输入下面的命令

   1. ssh -L 7000:192.168.0.2:22 user@221.221.144.168

复制代码
不要关闭这个终端窗口,这时候我们已经通过221.221.144.168建立了本地7000端口到Application server 22端口的安全加密连接
再打开一个终端窗口,SSH连接本地7000端口,就可以顺利连接Application server 22端口登录获得shell,假如连接Application Server的用户名是AppUser,输入这个命令

   1. ssh appuser@localhost -p 7000

复制代码
是的,你已经发现同样是两次登录,是不是显得更麻烦了,如果稍微改变一下上面的图,Application Server不是一个而是多个都需要管理,那这个方式的优点就显示出来了。这里不仔细说明了,你可以使用.ssh/config文件来配置,一次连接 Authority Server建立多个Application Server的转发隧道,当然可以使用密钥的方式免除输入很长的复杂密码

   1. host agent
   2.     User user
   3.     Port 22
   4.     HostName 221.221.144.168
   5.     IdentityFile ~/.ssh/id_rsa
   6.     LocalForward  7000 192.168.0.2:22     "Application1
   7.     LocalForward  7001 192.168.0.3:22     "Application2
   8.     LocalForward  7002 192.168.0.4:22     "Application3
   9.

  10. host Application1
  11.     HostName localhost
  12.     User User1
  13.     Port 7000
  14.     IdentityFile ~/.ssh/id_rsa1
  15.

  16. host Application2
  17.     HostName localhost
  18.     User User2
  19.     Port 7001
  20.     IdentityFile ~/.ssh/id_rsa2
  21.

  22. host Application3
  23.     HostName localhost
  24.     User User3
  25.     Port 7002
  26.     IdentityFile ~/.ssh/id_rsa3

复制代码
实例二
在企业网络内部有一台数据库服务器(192.168.0.2,数据库访问端口1521),由于调试的需要想临时从远程机器防火墙外部连接到这个服务器, 防火墙限制只能连接SSH端口,拒绝直接连接1521端口,这时候,还是可以使用本地端口转发来解决

   1. ssh -L 7000:localhost:1521 user@192.168.0.2

复制代码
这时候,使用数据库的客户端软件访问本地(SSH Client)的7000端口就可以了
详细解释一下数据流程

    * SSH Client上的数据库客户端将数据发送到本机的7000端口上
    * 本机的SSH Client会将7000端口收到的数据加密并转发到SSH Server上。
    * SSH Server会解密收到的数据并将之转发到数据库DBMS服务的1521监听端口上
    * 最后再将从数据库返回的数据原路返回。


整个流程应用并没有直接连接数据库服务器的1521,而是连接到了本地的一个监听端口,SSH端口转发在幕后完成了其余的所有事情,加密,转发,解密,通讯。

需要说明的问题
前面说了本地端口转发的命令是

   1. ssh -L <local port>:<remote host>:<remote port> <SSH servername>

复制代码
在实例二中,却使用这个命令

   1. ssh -L 7000:localhost:1521 user@192.168.0.2

复制代码
1 命令中的 <remote host> 和 <SSH hostname> 必须是同一台机器么?
不是一台主机的情况更为普遍,下面有说明
2 你可能会疑惑上面命令中的 <remote host> 为什么用 localhost,它指向的是哪台机器呢?这样的设置对么?
使用localhost的配置,
指向的是DataBase Server。如果看过讲到的数据流程,localhost是由ssh server来解析的
为什么用 localhost 而不是 IP 地址或者主机名?
其实这取决于如何限制DBMS访问的,如果只允许lookback接口访问的话,那自然就只有localhost或者IP为127.0.0.1才能访问,
如果没有限制,那使用192.168.0.2或者主机名自然也是可以的。

   1. ssh -L 7000:192.168.0.2:1521 user@192.168.0.2

四、远程端口转发

命令是:

   1. ssh -R <local port>:<remote host>:<remote port> <SSH servername>

复制代码
和本地转发的第二个实例一样,只是假设由于网络或防火墙的原因不能用SSH从Macbook(192.168.0.3)连接到Database Server(192.168.0.2,数据库访问端口1521),但是反向连接是允许的。这时候就可以使用远程端口转发。

在数据库服务器(SSH Client)端执行如下命令:

   1. ssh -R 7000:localhost:1521 user@192.168.0.3

复制代码
和本地端口转发相比,这个场景,只是SSH Server 和 SSH Client 的位置交换了一下。
数据流程和本地转发完全一致

    * 在Database Client的应用将数据发送到本机的7000端口
    * 本机的SSH Server将7000端口收到的数据加密并转发到SSH Client上
    * SSH Client解密收到的数据,并转发到DBMS监听的1521端口上
    * 最后将从DBMS获取的数据原路返回。

五、本地转发与远程转发

本地转发,远程转发有什么区别?
转自:《ssh权威指南》读书笔记中的总结

    * 在本地转发中,应用程序客户端与监听端同SSH客户端在一起,应用程序服务器同SSH服务器在一起。
    * 在远程转发中,应用程序客户端与监听端同SSH服务器在一起,应用程序服务器同SSH客户端在一起。


PS: 也不是很明确,我知道如何使用,但是真的很难说明白


什么时候使用本地转发,什么时候使用远程转发?
根据你的网络情况和防火墙的规则情况选择使用本地转发和远程转发
如果你所在的环境下,既允许发起 SSH连接到SSH Server,也允许作为SSH Server接受远程SSH连接。
这时选择本地转发或远程转发都是可以的,能完成一样的功能。

六、多机转发

在4楼的第二个实例中提到SSH server和数据库服务器是不是一定是一台主机
当然不是,请求其他的应用服务器是很常见的应用
以本地端口转发为例(远程端口转发是类似的)

在企业网络内部有一台数据库服务器(192.168.0.3,数据库访问端口1521),我们不能直接连接这个服务器;但是我们可以连接SSH Server(192.168.0.2),并通过SSH Server来请求DBMS,这是本地端口转发的一个典型应用

   1. ssh -L 7000:192.168.0.3:1521 user@192.168.0.2

复制代码

    * SSH Client上的数据库客户端将数据发送到本机的7000端口上
    * 本机的SSH Client会将7000端口收到的数据加密并转发到SSH Server上。
    * SSH Server会解密收到的数据并将之转发到另一台主机上的DBMS服务的1521监听端口上
    * 最后再将从数据库返回的数据原路返回。

七、X转发

X应用转发

八、总结

主要参数和作用


    * -g Allows remote hosts to connect to local forwarded ports.



在SSH Client执行

   1. ssh -g -L 7000:192.168.0.3:1521 192.168.0.2

复制代码
然后在数据库应用的客户端上配置连接SSH Client(192.168.1.2)的7000端口即可。
没有指定-g参数的情况下,7000这个端口只接受本机的连接,指定-g参数SSH Clinet的7000端口可以接受其他主机的连接
这样的设置,可以允许部署在其他机器上的Database Client访问SSH Clinet的7000端口,就好像直接访问Database的1521端口一样

    * -f Requests ssh to go to background just before command execution.
    * -N Do not execute a remote command.(protocol version 2 only)


这两个参数很多时候一起使用,在使用ssh -D动态端口转发代理功能的时候,很多人大多使用iSSH等第三方软件来实现,担心关闭终端启用这个代理端口的进程也随之结束,这时候可以这样使用
动态转发实例

   1. ssh -D 7000 -fN user@208.53.210.20

复制代码
本地转发实例

   1. ssh -L 7000:192.168.0.3:1521 -fN 192.168.0.2

复制代码
使用lsof命令,找到后台进程,使用kill命令结束进程,

   1. lsof -i:7000

复制代码
PS: 这个命令可以写成脚本,我的shell 脚本是在quick silver里面执行的

安全
在上图所示的上述连接中的红色连线,Database<-> SSH Clinet 以及 SSH Server<->Database Server之间的连接并不是安全连接,它们之间没有经过 SSH 的加密及解密。如果他们之间的网络并不是值得信赖的网络连接,我们就需要谨慎使用这种连接方式了。

回顾和思路
介绍了本地端口转发,远程端口转发,动态端口转发以及 X 转发的介绍。
SSH端口转发能够提供两个主要功能:

    * 加密 SSH Client 端至 SSH Server 端之间的通讯数据。
    * 突破防火墙的限制完成一些之前无法建立的TCP连接。

    * 对一些已知端口号的应用,例如 Telnet/SMTP,我们可以使用本地端口转发或者远程端口转发来达到目的。
    * 动态端口转发则可以实现 SOCKS代理从而实现更安全的加密的Web浏览。
    * 更方便的X应用
    * 灵活的使用-g -f -N参数
    * 注意端口转发的安全问题

 

     另篇:   

ssh 是有端口转发功能的。
ssh的三个强大的端口转发命令:

QUOTE:
ssh -C -f -N -g -L listen_port:DST_Host:DST_port user@Tunnel_Host
ssh -C -f -N -g -R listen_port:DST_Host:DST_port user@Tunnel_Host
ssh -C -f -N -g -D listen_port user@Tunnel_Host
-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参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics