Linux下SSH端口转发:配置和示例
在90年代中期(确切地说是1995年),赫尔辛基大学(芬兰)的一位名叫塔图·伊洛宁的研究员设计了一种协议,最终取代了所有远程登录程序。Tatu Ylönen设计新协议的主要目的是阻止密码嗅探攻击。
换言之,1995年以前的远程登录程序用于通过网络以明文格式发送登录凭据和其他关键信息。因此,任何有一点技术知识的人都可以嗅出数据包并读取密码。
TatuYlönen提出的新设计和实现称为SSH(secureshell.)。系统管理员日夜使用这个工具来访问他们的远程系统。
SSH通过对客户端和服务器进行身份验证,并使用强大的加密算法保护传输的数据,从而保护了远程登录的主要任务。然而,还有许多其他协议需要保护。
在1995年首次引入SSH之后,该协议经过了几次迭代,目前的安全版本是SSH版本2协议。在ssh的启发下,有一个更好的修改过的应用程序,现在可以使用了。与ssh相比,它有几个高级特性。我们已经讨论过这个修改过的版本,它是ssh的一个很好的替代品。
许多Linux发行版附带的SSH应用程序称为OpenSSH。而且它有几个很好的特性,甚至可以帮助保护其他一些不安全的协议。我可以说,你可以使用任何不安全的功能。
有太多弱身份验证的应用程序,可以使用SSH来保护它们。我们可能正在考虑如何保护另一个将在另一个端口上运行的应用程序,而不是使用ssh本身的ssh。
是的,那是可以做到的。本文的主要目的是解释如何使用安全的SSH连接来保护其他不安全的应用程序。
The idea behind this is to forward or tunnel other insecure communication channels inside an ssh secure channel. You can say that the insecure protocol, will travel inside the secure SSH connection.
因此,保护SSH连接的安全特性现在也可以用于保护其他协议。这里要注意的要点是,使用SSH保护的应用程序甚至不会意识到这一点,因此不需要对该应用程序进行重大修改(但是需要修改SSH设置)。
使用SSH保护其他不安全应用程序的另一个好处是,SSH提供的安全性将是应用程序本身提供的现有安全层之外的一个添加安全层。因此,可以使用它来实现冗余的安全级别。
使用SSH保护其他不安全应用程序/协议的这一特性称为端口转发,有时也称为隧道。它被称为隧道,因为其他应用程序流量正在通过SSH通道进行隧道。在本文结束之前,我们将了解为什么它也被称为端口转发。
使用SSH端口转发/隧道的主要原因是什么。?
第一个主要原因是我们已经讨论过的(为了保护其他不安全的协议)。然而,除此之外,我们还可以使用此功能的其他原因。下面将提到其中几个原因。
服务器所在的防火墙只允许通信到端口22.
我们需要使用SSH压缩特性压缩通过有线发送的流量。
请注意,我们只能使用SSH隧道或者端口转发来隧道TCP流量。但是,有一些技术甚至可以使用SSH端口转发隧道UDP通信。在本文中,我将不讨论UDP隧道。我将单独写一篇关于SSH-UDP隧道的文章,因为它需要一些特别的关注。
在进入配置部分之前,让我们首先了解这种隧道/转发是如何工作的。
. 我用telnet来展示这个例子(telnet是不安全的)。
如果我们看到这个图表,那么很明显telnet客户机软件会将其连接流量发送到本地SSH。然后本地SSH将它发送到目标服务器的SSH。目标服务器的SSH将把流量提交回telnet。因此,整个数据通过有线加密。
现在让我们看看如何配置它。客户端和服务器端都启用SSH转发功能(SSH是第一步)。这可以通过修改ssh配置文件 /etc/ssh/sshd_config来完成。我们需要添加一行来启用TCP端口转发。如下所示。
AllowTcpForwarding yes
一旦我们添加了上述行,我们需要重新启动SSH服务,以使新配置生效。
# service ssh restart
现在我们需要知道两个端口号。一个是默认的telnet端口23,我们已经知道了,另一个是仲裁端口号,它目前没有在机器上使用。为了演示这个示例,我将使用端口号8888(我们可以使用我们希望的任何端口号)。请记住,要使用1024以上的端口号,我们需要root权限)。
不,我们要做的是要求SSH服务器将所选端口8888上的所有请求转发到目标服务器(我们的远程telnet服务器)的23端口。这可以通过以下命令完成。我们先看一下命令的语法,然后再看这个命令。
#ssh -L<Local Port>:<Local Machine>:<Target Port> <Target Machine>
本地端口:是我们选择的随机端口(本例中是8888)
本地机:在这里输入localhost,因为它是localsystem
目标端口:这是目标服务端口号,在我们的例子中是23,因为我们正在隧道telnet
目标机:目标服务器的IP地址/主机名
因此,通过SSH隧道telnet流量的命令如下所示。
#ssh -L8888:localhost:23 192.168.0.106
在我的例子中,目标服务器是内联网192.168.0.106中的一台机器。将其替换为远程服务器IP地址。
意外地运行上面的命令会将我们登录到目标主机中(在询问密码之后,如果我们有基于密钥的身份验证设置,这会更好,因为这样不会询问我们密码)。
什么?我不想登录目标服务器,但我只想在我的系统和目标服务器之间创建一个隧道,这样我就可以通过它转发telnet流量。所以问题是,当我们运行上述命令时,本地系统首先会通过将我们登录到该服务器中来创建一个连接,这样我们就可以通过身份验证,其他通信量(telnet通信量)将通过该连接。如果我们注销或者关闭此ssh连接,那么telnet流量将无法使用ssh隧道(因为该连接不存在,我们将如何隧道它)。
因此,我们需要在前面显示的命令中使用一个添加选项。选项是 -N和 -f。
#ssh -N -f -L8888:localhost:23 192.168.0.106
当然,上面的命令也会询问我们一个密码(如果我们使用的是密码ssh身份验证),但不会将我们登录到目标服务器中。它将分叉一个SSH进程,并在那里等待请求被隧道化。
现在,我们可以使用本地主机端口8888登录到目标服务器的telnet。因此,当我们运行下面的命令时,我们将登录到目标telnet服务器中。
#telnet localhost 8888
对于我们刚刚使用SSH隧道建立的telnet会话,有一件有趣的事情。如果我们运行“ who”命令(在目标服务器上,通过telnet登录后),将显示我们是从“ localhost登录的,而不是服务器IP地址。
因为我们实际上是从本地主机端口8888登录,而ssh正在执行所有的技巧,将本地主机端口8888上的流量传输到目标服务器ssh端口,在对内容进行解密之后,它将把流量传递到telnet端口23.
除了telnet和其他不安全的远程登录程序之外,需要SSH隧道的应用程序是VNC。因为telnet的展示只是为了说明这个目的,现在没有人真正使用telnet。VNC是一个高度使用的不安全应用程序。VNC服务器发送和接收的数据都是明文格式的,因此需要配置SSH隧道之类的东西来保护它。
默认情况下,VNC侦听端口5900、5901、5902. 因此,我们可以很容易地设置一个端口转发来隧道化不安全的VNC会话。命令基本相同。。
#ssh -N -f -L5900:localhost:5901 192.168.0.106
上面的命令意味着,如果我们在本地主机上使用vncviewer连接到5900号端口,我们将连接到目标服务器vnc。在我们的例子中,我们可以简单地运行下面的vncviewer命令来连接。
#vncviewer localhost:2
请注意,上面命令中使用的端口2是VNC session port,这对于不同的用户是不同的,(这个端口与TCP端口无关)。另外,如果我们注意到,我们没有提到在创建隧道时使用的TCP端口(端口5900),这是因为vncviewer将使用默认端口,以防我们不提。在隧道配置过程中,我们特意将默认端口5900配置为本地端口。
我们在前面的示例中看到的端口转发称为本地端口转发。为什么叫本地端口转发?。这是因为,目标服务器的端口(与我们建立连接的服务器)以本地端口的形式可用。我们已使用本地端口8888连接远程telnet端口23.
在配置SSH端口转发时,我们还使用了选项 -L。我代表本地。现在有另一种类型的端口转发称为远程端口转发。让我们看看是什么。
什么是远程端口转发?
不要混淆这两者(远程端口转发和本地端口转发),因为它们几乎非常相似,只是有一点差别。这种微小的差别有时会成为混淆的根源。
当我们位于目标服务器内部并希望为客户端设置端口转发时,将使用此远程转发。它被称为远程端口转发,因为我们正在从远程服务器(目标服务器)设置此端口转发。例如,假设我们在目标服务器192.168.0.106内(运行telnet服务器的同一台服务器,我们之前设置了一个本地端口转发到该服务器)。我们可以通过下面的命令配置远程端口转发。
#ssh -N -f -R8888:192.168.0.106:23 192.168.0.105
在上面显示的命令中,我们使用了 -R选项来设置远程端口转发,因为我们在目标系统中(192.168.0.106)。在目标系统中,我们正在为我们的客户机(192.168.0.105)配置端口转发以安全登录。
因此,如果我们从目标服务器运行带有-R选项的命令,该命令将登录到客户机系统内部,打开一个端口并通过SSH将其转发回自己,那么它被称为远程端口转发。
唯一需要注意的是我们已经从目标机器执行了命令,这样客户机就可以通过下面的命令安全地连接到它。请注意,客户端将使用与本地端口转发期间相同的命令连接它。就客户机连接所使用的方法而言,没有区别。
#telnet localhost 8888
因此,最后要说明的区别,并避免进一步的混淆。。。
当我们位于包含应用程序的服务器(例如telnet服务器)内时,使用远程端口转发
当我们在客户端计算机上并且应用程序在远程计算机上时,请使用本地端口转发。
现在有第三种端口转发称为动态端口转发。它通常用于绕过防火墙规则和其他过滤。让我们看看这个动态端口转发是如何工作的。
什么是动态端口转发?
让我们举一个例子来了解这个东西是如何工作的。为了使这个例子有趣,让我们假设你在你的大学网络中。大学防火墙只允许你浏览几个网页维基百科, 谷歌,等等,因此我们无法打开脸谱网,或者youtube.com.
假设你家里有一台服务器,它有公共IP地址。上面安装了SSH服务器,我们可以从任何地方访问它。现在我们只需从大学工作站在终端上运行以下命令。
$ssh -D 6868 user<@remot-host>
在上面的命令中,我们请求打开大学工作站(localhost)上的一个本地端口6868,该端口将把所有请求转发到该端口,并将其转发到远程主机(这将是我们在家中的服务器)。
现在的问题是你将如何使用这个来浏览受限制的?
在开始浏览那些受限制的网页之前,让我们先了解一下发生了什么。当我们运行上述命令时,我们家中的服务器已成为SOCKS代理服务器。袜子代表插座安全。它的作用类似于代理服务器,它将与客户机建议的任何目的地建立TCP连接。
因此,简而言之,远程主机(我们在家中的服务器)充当本地主机6868上发送的所有连接的代理。与普通的HTTP代理服务器不同,SOCKS代理服务器不解释流经它的HTTP流量。一个普通的HTTP代理足够智能,可以理解流经它的HTTP协议,但是它只理解HTTP流量,不能用来隧道所有通过它的TCP流量。我们的SOCKS代理服务器可以用来隧道通过它的任何类型的TCP流量(只要你发送流量的应用程序知道SOCKS代理)。
因此,如果我们使用的是网络浏览器,它知道如何向我们的SOCKS服务器发送SOCKS消息。因此,让我们继续配置我们的web浏览器,将所有http流量发送到本地主机端口6868(它将把它们临时发送到我们的远程家庭ssh服务器)
在Firefox中,我们可以通过编辑--->首选项--->高级--->网络--->设置来配置SOCKS代理。从窗口中选择manual proxy configuration(手动代理配置)。
保存设置并重新启动firefox后,现在就可以使用我们新配置的SOCKS代理服务器访问所有URL。Firefox将请求转发到本地主机6868端口,后者将通过安全SSH隧道将请求转发到远程家庭服务器。
如果我们从不安全的网络访问internet,也可以使用此技术。比如说,你在一家酒店里使用他们的wifi。但是你想隐藏你在互联网上访问的任何东西。