通过 SSH 反向代理访问内网服务

最近用到,简要记录下来。具体可参考文末的相关链接。

前言

首先,什么是反向代理?下图清晰地解释了它与正向代理的区别。

反向代理的模式中,由于 proxy 的存在,可以使 client 访问本不能直接访问的 server(例如 proxy 和 server 在同一个 LAN)。且 client 只知道自己在访问 proxy,而不知道真正提供服务的是 server。

系统中自带的 ssh 命令,就可以满足正向/反向代理的需求。首先了解 ssh 命令的一些参数:

SSH 参数介绍

参数解释
-f后台执行ssh指令
-C允许压缩数据
-N不执行远程指令
-R将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口
-L将本地机(客户机)的某个端口转发到远端指定机器的指定端口

重点就是 -L、-R 两个参数,下面是它们的原理详解:

原理

-L port:host:hostport
本地主机上分配一个 socket 侦听 port 端口,一旦这个端口上有了连接,该连接就经过 SSH 通道转发出去,同时 Remote 主机和 host:hostport 建立连接。Local 访问 Local 本地的 port 相当于访问 Remote 眼中的 host:hostport。如下图:


-R port:host:hostport
远程主机上分配一个 socket 侦听 port 端口,一旦这个端口上有了连接,该连接就经过 SSH 通道转发出去,同时 Local 主机和 host:hostport 端口建立连接。Remote 访问 Remote 本地的 port 相当于访问 Local 眼中的 host:hostport。如下图:

本地/远程 的区分有时也不是那么强制。一般来说,IP 更为固定的是 远程 端,负责被动接受连接;IP 更为动态的是 本地 端,负责主动发起连接。如果双方都可以主动发起请求,-L -R 都可以用。

按上面的知识,尝试实现下图中的 client → server 通信。

案例网络拓扑

其中 Proxy 1.2.3.4 为公网服务器,client 和 proxy 在不同的 LAN,proxy 和 server 在同一个 LAN。

Server 端命令

# 将远程公网服务器 7890 端口转发至本地 8000 端口
# ssh -fCNR 远程端口:localhost:本地端口 远程用户@远程ip
ssh -fCNR 7890:127.0.0.1:8000 remote_user@1.2.3.4

Proxy 端命令

# 将本地 5678 端口经本地转发到本地 7890 端口
# ssh -fCNL *:侦听端口:转发目标主机:目标端口 localhost
ssh -fCNL *:5678:127.0.0.1:7890 local_user@localhost

# 备注:上面的"转发目标主机",指的是命令最后的localhost眼中的localhost,并且目标可以是外部的主机

之后,client 就可以通过 1.2.3.4:5678 访问 192.168.1.123:8000 服务了。

相关参考

  1. Jerry Sheh. https://jerrysheh.me/post/44ca081e.html, 有改动转载
  2. https://blog.creke.net/722.html, 有改动转载
  3. man ssh 查看帮助文档

发表评论

解决 : *
97 + 69 =