通过双向流建立多个 HTTP 连接隧道

通过双向流建立多个 HTTP 连接隧道

我希望通过单个非网络双向流(特别是 QEMU virtio 串行流,但这并不重要)转发 http 服务器(在 Linux 上)。基本上我想要的是:

[XXX listen @ 8080] <-> some bidirectional stream <-> [YYY listen on stream, forward to http] <-> [web server:80] 

我的想法是,我希望能够将普通的 Web 浏览器(来自 Linux)指向在 8080 上侦听的 XXX,并且所有内容都将通过双向流和 YYY 传递到/来自远程 Web 服务器。我不能要求主机上的 root 访问权限。

我觉得 XXX 和 YYY 程序可能是 socat(或其他一些标准的隧道相关程序),但它只是逃避我。关于最简单的方法有什么想法吗?

答案1

您想要通过串行链路传送 IP 数据包 – 太棒了!幸运的是,这个问题与 IP 数据包一样古老,并且有“首选”解决方案:

  • 如果您可以忍受缺乏自动配置,(也:真的老式的。您可能不想使用这个。)
  • 购买力平价如果您希望它能够为任一端分配 IP 地址

这两种协议都旨在通过串行线路封装 IP 数据包 - 这正是您想要的:HTTP 连接实际上是 TCP 连接,而 TCP 运行在 IP 之上,这已经带来了在一个网络上“多路复用”多个不同连接的能力连接如你所愿。

因此,假设 PPP 是您选择的方法:

# on the host machine that has access to the internet
pppd lock proxyarp <host IP>:<VM IP> /path/to/specified/virtioserialsocket

# on the VM
pppd lock defaultroute <VM IP>:<host IP> /dev/virtio-port/<virtioserialdev>

# At this point, you should be able to ping <VM IP>
# from the host, and <host IP> from the VM. If not,
# check `ip route`.
#
# You will now want to set up routing / NAT such that
# either the VM appears as a "normal" computer on the
# network that your host is on, as well, or such that
# all connections to some port are transparently NAT'
# ed over /dev/ppp0 on your host.
# 
# Since that depends on what you're trying to achieve
# here, I can only point out this has been done in a
# lot of other places, and documented.

但是,老实说。如果您有带有 virtio 的 QEMU,您还可以在来宾中模拟网卡 – 然后只需通过模拟网络执行 IP 操作。这更容易,性能更高,不需要额外的软件,并且开箱即用!

答案2

我确实觉得最初的问题可以通过 PPP/SLIP 以某种方式解决,但它并没有真正满足我的要求,因为主机上需要太多配置。理想情况下,如果 socat 有 SLIP 选项并且可以通过它转发本地端口,那就太棒了。唉。


如果您假设具有 HTTP 服务器的主机具有 SSH 服务器(在我的情况下确实如此),那么以下解决方案可以满足我的要求:

在具有 HTTP 服务器的计算机上运行 socat 将虚拟串行端口转发到 SSH 服务器(大概也可以使用 socat 转发实际的串行端口):

socat file:/dev/vport1p1,ignoreeof tcp:127.0.0.1:22

ignoreeof选项对我来说至关重要——如果您不使用它,socat 就会立即断开连接。根据您的串行设备,这可能很重要,也可能不重要。

在流的另一端,我的虚拟串行端口只是侦听主机上的端口(-chardev socket,id=X,host=127.0.0.1,port=1234是 QEMU 选项),因此我们可以通过 SSH 连接到它并以这种方式进行端口转发:

 ssh -L 8080:127.0.0.1:80 -p 1234 user@localhost

建立 SSH 隧道后,您只需将浏览器指向 localhost:8080 即可正常工作。

相关内容