揭秘 SSH 端口转发:本地、远程和动态隧道详解

学习本地、远程和动态SSH端口转发,以及用于数据库、Web应用和SOCKS代理的实用命令。

解密SSH端口转发:本地、远程和动态隧道详解

SSH端口转发允许您通过加密的SSH连接访问网络服务,而无需直接暴露该服务。当数据库、仪表板或开发服务器可通过SSH主机访问但无法从您的笔记本电脑直接访问时,通常会使用此功能。

三种常见形式是本地转发、远程转发和动态转发。它们使用类似的语法,但监听端口位于不同的位置。

SSH端口转发的作用

SSH端口转发(也称为SSH隧道)通过您的SSH会话将流量从一个主机和端口重定向到另一个主机和端口。目标地址由发起最终连接的一方解析。对于本地转发,SSH服务器连接到目标。对于远程转发,您的SSH客户端连接到目标。

这提供了几个优点:

  • 安全性:加密客户端与目标服务之间原本未加密的流量。
  • 访问控制:允许访问运行在私有网络或防火墙后的服务,这些服务通常无法从您当前位置直接访问。
  • 桥接网络:安全地连接不同的网络段。

本地端口转发 (-L)

本地端口转发是最常见的类型。它允许将连接从您本地机器上的一个端口转发到远程机器上的一个端口,通过SSH服务器进行。本质上,您使远程网络上的服务看起来像是在本地机器上运行。

工作原理:

  1. 您在本地机器上启动SSH客户端。
  2. 您指定一个本地端口(local_port),SSH将监听该端口。
  3. 任何对本地机器上local_port的连接都会通过SSH连接转发到remote_hostremote_port

语法:

ssh -L [local_bind_address:]local_port:remote_host:remote_port [user@]ssh_server_host
  • local_bind_address:本地机器上绑定的可选地址。如果省略,OpenSSH通常绑定到回环地址,除非您的客户端配置另有说明。
  • local_port:本地机器上SSH将监听的端口。
  • remote_host:SSH服务器将连接的目标主机名或IP地址。
  • remote_port:流量将指向的remote_host上的端口。
  • user@ssh_server_host:您的用户名和要连接的SSH服务器的主机名/IP地址。

实际用例: 访问运行在远程服务器私有IP地址上的数据库服务器。

假设一个数据库服务器(例如,PostgreSQL在192.168.1.100:5432上)只能从您公司的内部网络访问。您可以使用本地端口转发从家里的笔记本电脑访问它:

ssh -L 5433:192.168.1.100:5432 your_user@your_ssh_server.com
  • 此命令连接到your_ssh_server.com
  • 它在本地机器上打开端口5433(默认情况下为localhost)。
  • 任何对localhost:5433的连接都会通过your_ssh_server.com转发到192.168.1.100:5432

现在,您可以配置本地数据库客户端连接到localhost:5433,流量将通过安全隧道传输到远程数据库服务器。

提示: 使用ssh -N创建隧道而不执行远程命令。这对于后台隧道很有用。

ssh -N -L 5433:192.168.1.100:5432 your_user@your_ssh_server.com

远程端口转发 (-R)

远程端口转发允许将连接从远程SSH服务器上的一个端口转发到您本地机器或本地机器可访问的另一台机器上的端口。这对于使本地机器上运行的服务可供远程服务器或其网络访问非常有用。

工作原理:

  1. 您在本地机器上启动SSH客户端。
  2. 您指定SSH服务器上的一个远程端口(remote_port),SSH将监听该端口。
  3. 任何对SSH服务器上remote_port的连接都会通过SSH连接转发回您的本地机器,然后转发到指定的destination_hostdestination_port

语法:

ssh -R [remote_bind_address:]remote_port:destination_host:destination_port [user@]ssh_server_host
  • remote_bind_address:(可选)SSH服务器上绑定监听端口的地址。默认为localhost(意味着只有SSH服务器本身可以连接到此端口)。使用0.0.0.0*允许远程网络上的其他机器连接。
  • remote_port:SSH服务器上SSH将监听的端口。
  • destination_host:您的SSH客户端将连接的目标主机名或IP地址(如果服务在本地机器上,通常是localhost)。
  • destination_port:流量将指向的destination_host上的端口。
  • user@ssh_server_host:您的用户名和要连接的SSH服务器的主机名/IP地址。

实际用例: 将本地Web服务器暴露给远程网络。

假设您在笔记本电脑上开发一个Web应用程序,并希望向只能访问公司内部网络的同事演示,并且您有一个可从该网络访问的SSH服务器(your_ssh_server.com)。

在您的笔记本电脑上,运行:

ssh -R 8080:localhost:3000 your_user@your_ssh_server.com
  • 此命令连接到your_ssh_server.com
  • 它告诉your_ssh_server.com监听端口8080
  • 任何对your_ssh_server.com:8080的连接都会通过SSH隧道转发回您的笔记本电脑(localhost)上的端口3000(您的Web服务器正在运行)。

现在,您的同事可以通过在浏览器中导航到http://your_ssh_server.com:8080来访问您的Web应用程序。流量从他们的浏览器到SSH服务器,通过隧道到您的笔记本电脑,然后到您的Web服务器。

警告: 在典型的OpenSSH配置中,remote_port只能从SSH服务器本身访问。要允许远程网络上的其他机器访问转发的端口,请将remote_bind_address显式设置为0.0.0.0*,并确保SSH服务器通过GatewayPorts设置(如clientspecifiedyes)允许这样做。

ssh -R 0.0.0.0:8080:localhost:3000 your_user@your_ssh_server.com

动态端口转发 (-D)

动态端口转发在本地机器上创建一个SOCKS代理。这可以说是最灵活的类型,因为它允许您通过SSH连接隧道任何支持SOCKS代理的应用程序。SSH不是转发特定端口,而是监听本地端口并充当SOCKS代理服务器。

工作原理:

  1. 您在本地机器上启动SSH客户端。
  2. 您指定一个本地端口(local_port),SSH将作为SOCKS代理监听该端口。
  3. 您配置您的应用程序(Web浏览器等)使用localhost:local_port作为其SOCKS代理。
  4. 当应用程序通过此代理发出请求时,SSH将流量转发到SSH服务器,然后SSH服务器代表您的应用程序连接到最终目的地。

语法:

ssh -D [local_bind_address:]local_port [user@]ssh_server_host
  • local_bind_address:(可选)本地机器上绑定监听SOCKS代理端口的地址。默认为localhost
  • local_port:本地机器上SSH将作为SOCKS代理监听的端口。
  • user@ssh_server_host:您的用户名和要连接的SSH服务器的主机名/IP地址。

实际用例: 在公共Wi-Fi上安全浏览网页。

当连接到不受信任的公共Wi-Fi网络时,您的流量容易受到攻击。您可以使用动态端口转发将所有Web浏览流量通过加密的SSH连接隧道传输到受信任的服务器。

在您的笔记本电脑上,运行:

ssh -D 1080 your_user@your_trusted_server.com
  • 此命令连接到your_trusted_server.com
  • 它在本地机器上打开端口1080,充当SOCKS代理。

接下来,配置您的Web浏览器或其他应用程序使用localhost上的端口1080作为SOCKS代理。如果应用程序有SOCKS5远程DNS选项,当您不希望DNS查询在本地网络上发生时,请使用它。

您的浏览器流量被发送到您的SSH服务器,然后SSH服务器连接到目标站点。HTTPS仍然重要;SSH隧道保护到SSH服务器的路径,而不是之后的每一跳。

提示: 您可以将-D-C结合使用以进行压缩,这在较慢的网络链路上可能有益。

ssh -C -D 1080 your_user@your_trusted_server.com

高级考虑和最佳实践

  • SSH服务器配置(sshd_config:某些转发功能需要服务器端权限。在假设隧道可以监听或连接到任何地方之前,请检查AllowTcpForwardingPermitOpenPermitListenGatewayPorts
  • 防火墙:请记住,客户端、服务器或中间网络上的防火墙可能会阻止SSH连接或用于转发的端口。确保必要的端口(通常是SSH本身的22端口)是开放的。
  • 安全性:虽然端口转发加密流量,但隧道的安全性取决于SSH服务器的安全性。使用强SSH密钥,禁用密码认证,并保持SSH服务器更新。
  • 可靠性:对于脚本,添加-o ExitOnForwardFailure=yes,以便如果SSH无法创建请求的转发,则退出。对于长时间运行的隧道,请考虑使用autossh或受监督的服务。

要点

当您的笔记本电脑需要访问私有远程服务时,使用-L。当远程主机需要访问靠近您笔记本电脑的内容时,使用-R。当您需要通过受信任的SSH服务器使用SOCKS代理时,使用-D。保持绑定紧密,检查服务器策略,并将每个隧道视为临时的网络开放。