在本教程中,我们将介绍 Linux 中的 SSH 端口转发。这是 SSH 实用程序的一项功能,Linux 管理员使用该实用程序在不同系统之间创建加密且安全的中继。
您可以使用 SSH 端口转发(SSH 隧道)在两个或多个系统之间创建安全连接。然后应用程序可以使用这些隧道来传输数据。
您的数据的安全性取决于其加密程度,这就是 SSH 端口转发成为流行机制的原因。请继续阅读以了解更多信息,并了解如何在您自己的系统上设置 SSH 端口转发。
什么是 SSH 端口转发?
简而言之,SSH 端口转发涉及在两个或多个系统之间建立 SSH 隧道,然后将系统配置为通过该连接传输指定类型的流量。
您可以用它来做一些不同的事情:本地转发、远程转发和动态端口转发。每个配置都需要其自己的设置步骤,因此我们将在本教程后面逐一介绍它们。
本地端口转发用于使外部资源在本地网络上可用。建立到远程系统的 SSH 隧道,来自本地网络的流量可以使用该隧道来回传输数据,访问远程系统和网络,就像它是本地网络的一部分一样。
远程端口转发恰恰相反。 SSH 隧道已建立,但远程系统能够访问您的本地网络。
动态端口转发设置 SOCKS 代理服务器。您可以将应用程序配置为连接到代理并通过它传输所有数据。最常见的用途是私人网页浏览或使您的连接看起来来自不同的国家或地区。
您可以使用 SSH 端口转发来设置虚拟专用网络 (VPN)。为此,您需要一个名为 sshuttle 的额外程序。我们将在本教程后面介绍详细信息。
为什么要使用 SSH 端口转发?
由于 SSH 创建加密连接,因此如果您有以明文传输数据或使用未加密协议的应用程序,那么这是一个理想的解决方案。对于遗留应用程序尤其如此。
使用它从外部连接到本地网络也很流行,例如,员工使用 SSH 隧道连接到公司的内部网。
您可能认为这听起来像 VPN。两者类似,但创建 ssh 隧道是针对特定流量的,而 VPN 更适合建立一般连接。
SSH 端口转发允许您通过建立 SSH 隧道来访问远程资源。唯一的要求是您可以通过 SSH 访问远程系统,并且理想情况下,可以为无密码 SSH 配置公钥身份验证。
可以进行多少次会话?
从技术上讲,您可以根据需要指定任意数量的端口转发会话。网络使用 65,535 个不同的端口,您可以转发任何您想要的端口。
转发流量时,请了解使用某些端口的服务。例如,端口 80 保留用于HTTP。因此,如果您打算转发 Web 请求,则只需在端口 80 上转发流量。
您在本地系统上转发的端口不必与远程服务器的端口匹配。例如,您可以将本地主机上的端口 8080 转发到远程主机上的端口 80。
如果您不关心本地系统上使用的端口,请选择 2,000 到 10,000 之间的一个,因为这些端口很少使用。较小的数字通常为某些协议保留。
本地转发
本地转发涉及将端口从客户端系统转发到服务器。它允许您在系统上配置一个端口,以便到该端口的所有连接都将通过 SSH 隧道转发。
在 ssh 命令中使用 -L 开关指定本地端口转发。该命令的一般语法如下:
$ ssh -L local_port:remote_ip:remote_port user@hostname.com
查看下面的示例:
$ ssh -L 80:example1.com:80 example2.com
此命令会将所有对 example1.com 的请求转发到 example2.com。此系统上打开 Web 浏览器并尝试导航到 example1.com 的任何用户都将在后台将其请求发送到 example2.com 并显示不同的网站。
当配置对公司内部网或其他专用网络资源的外部访问时,此类命令非常有用。
测试 SSH 端口转发
要查看端口转发是否正常工作,可以使用 netcat 命令。在客户端计算机(运行 ssh -L 命令的系统)上,使用以下语法键入 netcat 命令:
$ nc -v remote_ip port_number
如果端口被转发并且数据能够成功地遍历连接,Netcat将返回一条成功消息,如果不起作用,连接将超时。
如果您在端口转发工作时遇到问题,请确保您能够正常 ssh 到远程服务器并且已正确配置端口。另外,请验证连接没有被防火墙阻止。
持久 SSH 隧道(使用 Autossh)
Autossh 是一个可用于创建持久 SSH 隧道的工具。唯一的先决条件是您需要在系统之间配置公钥身份验证,除非您希望每次连接中断和重新建立时都提示您输入密码。
默认情况下,您的系统上可能未安装 Autossh,但您可以使用 apt、yum 或您的发行版使用的任何包管理器快速安装它。
$ sudo apt-get install autossh
autossh 命令看起来与我们之前运行的 ssh 命令几乎相同。
$ autossh -L 80:example1.com:80 example2.com
Autossh 将确保在由于不活动、远程计算机重新启动、网络连接丢失等原因关闭隧道时自动重新建立隧道。
远程转发
远程端口转发用于让远程计算机访问您的系统。例如,如果您希望公司专用网络上的系统可以访问本地计算机上的服务,您可以配置远程端口转发来实现此目的。
要进行此设置,请使用以下语法发出 ssh 命令:
$ ssh -R remote_port:local_ip:local_port user@hostname.com
如果您的计算机上有本地 Web 服务器,并且希望从远程网络授予对其的访问权限,则可以将远程系统上的端口 8080(通用 http 替代端口)转发到本地系统上的端口 80(http 端口)。
$ ssh -R 8080:localhost:80 geek@likegeeks.com
动态转发
SSH动态端口转发将使SSH充当SOCKS代理服务器。这将跨一系列端口转发流量,而不是在特定端口上转发流量(本地和远程端口转发的方式)。
如果您曾经使用代理服务器访问被阻止的网站或查看位置受限的内容(例如在 Netflix 上查看在您所在国家/地区无法使用的内容),那么您可能使用过 SOCKS 服务器。
它还提供隐私性,因为您可以通过具有动态端口转发的 SOCKS 服务器路由流量,并防止任何人窥探日志文件以查看您的网络流量(访问的网站等)。
要设置动态端口转发,请使用 ssh 命令和以下语法:
$ ssh -D local_port user@hostname.com
因此,如果我们想将端口 1234 上的流量转发到我们的 SSH 服务器:
$ ssh -D 1234 geek@likegeeks.com
建立此连接后,您可以配置应用程序以通过它路由流量。例如,在您的网络浏览器上:
输入环回地址 (127.0.0.1) 和您为动态端口转发配置的端口,所有流量将通过 SSH 隧道转发到远程主机(在我们的示例中为 likegeeks.com SSH 服务器)。
多重转发
对于本地端口转发,如果您想设置多个端口转发到远程主机,则只需每次使用新的 -L 开关指定每条规则。命令语法如下:
$ ssh -L local_port_1:remote_ip:remote_port_1 -L local_port_2:remote_ip:remote_port2 user@hostname.com
例如,如果要将端口 8080 和 4430 分别转发到 192.168.1.1 端口 80 和 443(HTTP 和 HTTPS),则可以使用以下命令:
$ ssh -L 8080:192.168.1.1:80 -L 4430:192.168.1.1:443 user@hostname.com
对于远程端口转发,您可以通过使用 -R 开关指定每条新规则来设置多个要转发的端口。命令语法如下:
$ ssh -R remote_port1:local_ip:local_port1 remote_port2:local_ip:local_port2 user@hostname.com
列出端口转发
您可以看到当前建立了哪些 SSH 隧道lsof命令.
$ lsof -i | egrep '\<ssh\>'
在此屏幕截图中,您可以看到已建立 3 个 SSH 隧道。添加 -n 标志以列出 IP 地址而不是解析主机名。
$ lsof -i -n | egrep '\<ssh\>'
限制转发
默认情况下,SSH 端口转发是相当开放的。您可以根据需要自由创建本地、远程和动态端口转发。
但是,如果您不信任系统上的某些 SSH 用户,或者您只是想增强总体安全性,则可以对 SSH 端口转发设置一些限制。
您可以在 sshd_config 文件中配置几个不同的设置来限制端口转发。要配置此文件,请使用 vi、nano 或您喜欢的文本编辑器对其进行编辑:
$ sudo vi /etc/ssh/sshd_config
许可证开放可用于指定允许端口转发的目的地。如果您只想允许转发到某些 IP 地址或主机名,请使用此指令。语法如下:
PermitOpen host:port
PermitOpen IPv4_addr:port
PermitOpen [IPv6_addr]:port
允许TCP转发可用于打开或关闭 SSH 端口转发或指定允许哪种类型的 SSH 端口转发。可能的配置有:
AllowTCPForwarding yes #default setting
AllowTCPForwarding no #prevent all SSH port forwarding
AllowTCPForwarding local #allow only local SSH port forwarding
AllowTCPForwarding remote #allow only remote SSH port forwarding
要查看有关这些选项的更多信息,您可以查看手册页:
$ man sshd_config
低延迟
SSH 端口转发出现的唯一真正问题是通常存在一点延迟。如果您正在做一些小事情(例如访问文本文件或小型数据库),您可能不会注意到这是一个问题。
当进行网络密集型活动时,这个问题变得更加明显,特别是当您将端口转发设置为 SOCKS 时代理服务器.
延迟的原因是 SSH 通过 TCP 建立 TCP 隧道。这是一种非常低效的数据传输方式,并且会导致网络速度变慢。
您可以使用 VPN 来防止出现此问题,但如果您决定坚持使用 SSH 隧道,则有一个名为 sshuttle 的程序可以解决此问题。 Ubuntu 和基于 Debian 的发行版可以使用 apt-get 安装它:
$ sudo apt-get install sshuttle
如果您的发行版上的包管理器的存储库中没有 sshuttle,您可以从 GitHub 克隆它:
$ git clone https://github.com/sshuttle/sshuttle.git
$ cd sshuttle
$ ./setup.py install
使用 sshuttle 设置隧道与普通 ssh 命令不同。要设置转发所有流量的隧道(类似于 VPN):
$ sudo sshuttle -r user@remote_ip -x remote_ip 0/0 -vv
在终端中使用 ctrl+c 组合键断开连接。或者,要将 sshuttle 命令作为守护程序运行,请将 -D 开关添加到命令中。
想要确保连接已建立并且互联网可以在新的 IP 地址上看到您吗?你可以运行这个卷曲命令:
$ curl ipinfo.io