#websocket #tcp #proxy #tunnel

程序 单管程序

单管程序通过 TCP/HTTP(S) WebSockets 隧道和加密 TCP 应用程序

1 个不稳定版本

0.1.0 2023年7月27日

#2#web-socket

CC0 许可证

52KB
809

单管程序

单管程序是 Colin Percival 的 spiped 的模仿。

动机

单管程序的想法是在开发 sobfs 时产生的,而 sobfs 是受 George Murdocca 的这篇 文章 启发,文章介绍了如何使用 rot-13 加密来击败 IDS 中间盒。这些都是测试和改进 IDS 中间盒安全性的想法。

在编写 sobfs 之后,我了解到了 spiped,这是击败 IDS 中间盒比 sobfs/rot-13 更好的解决方案。

最初,单管程序的目的在于修改 spiped,并使用 Monocypher 中可用的加密原语来替换它们(例如,使用 X25519 替代有限域 Diffie-Hellman,使用 ChaCha20Poly1305 替代 AES-CTR+HMAC 等)。

然而,自从 inception 以来,在这方面没有取得任何进展。

想法从修改 spiped 转变为在 Rust 中重新解释,主要是作者为了学习 Rust 并在密码学和套接字中尝试而进行的技

术练习。

安装 Rust 并运行 cargo build -r. (您想要 -r 用于发布版本,它比调试构建快至少一个数量级。)

操作

单管程序可以以两种“模式”运行:

  • 客户端加密 模式:这是当单管程序在套接字上监听未加密连接时,并将加密连接发送到 服务器
  • 服务器解密 模式:这是当单管程序监听加密连接,并将/代理未加密连接发送到目标套接字时

通过 TCP 隧道

运行单管程序的一种常见方式是通过在 TCP 上隧道加密 TCP 应用程序,如 ssh

以下是客户端和服务器将如何运行的示例

┌────────────────────────────────────────────────────┐                                   ┌──────────────────────────────────────────────────┐
│ client                                             │                                   │  server                                          │
│                                                    │                                   │                                                  │
│ ┌────────────────────────┐        ┌───────────┐    │        (encrypted over tcp)       │   ┌───────────┐       ┌────────────────────────┐ │
│ │ application (e.g. ssh) │◀──────▶│ monopiped │◀───┼───────────────────────────────────┼──▶│ monopiped │◀─────▶│   target (e.g. sshd)   │ │
│ └────────────────────────┘        └───────────┘    │                                   │   └───────────┘       └────────────────────────┘ │
│                                                    │                                   │                                                  │
└────────────────────────────────────────────────────┘                                   └──────────────────────────────────────────────────┘

以隧道 SSH 为例,您将

  • 生成一个共享密钥:dd if=/dev/urandom bs=32 count=1 of=key.bin
  • 在客户端运行: monopiped -l 127.0.0.1:3000 -t server.example.com:2222 -e -k key.bin
  • 在服务器端运行: monopiped -l 0.0.0.0:2222 -t 127.0.0.1:22 -d -k key.bin

然后在客户端,您可以通过运行以下命令连接到SSH服务器:ssh -p3000 127.0.0.1

通过Websockets进行隧道传输

monopiped还支持通过WebSockets加密的TCP应用程序的隧道传输。

以下是客户端和服务器将如何运行的示例

┌────────────────────────────────────────────────────┐                                   ┌────────────────────────────────────────────────────────────────────────────────────────┐
│ client                                             │                                   │  server                                                                                │
│                                                    │           [encrypted over         │                                                                                        │
│ ┌────────────────────────┐        ┌───────────┐    │       WebSockets via HTTP(S)]     │   ┌────────────────────────────┐       ┌───────────┐        ┌────────────────────────┐ │
│ │ application (e.g. ssh) │◀──────▶│ monopiped │◀───┼───────────────────────────────────┼──▶│nginx/caddy/websocket proxy │◀─────▶│ monopiped │◀──────▶│   target (e.g. sshd)   │ │
│ └────────────────────────┘        └───────────┘    │                                   │   └────────────────────────────┘       └───────────┘        └────────────────────────┘ │
│                                                    │                                   │                                                                                        │
└────────────────────────────────────────────────────┘                                   └────────────────────────────────────────────────────────────────────────────────────────┘

与TCP不同的是,还包括一个在服务器端面向monopiped提供服务的web服务器。

以隧道 SSH 为例,您将

  • 生成一个共享密钥:dd if=/dev/urandom bs=32 count=1 of=key.bin
  • 在客户端运行:monopiped -l 127.0.0.1:3000 -t wss://server.example.com/ssh -e -k key.bin
  • 在服务器上运行一个WebSocket代理服务器:(以下是一个Caddy v2示例)
  • 在服务器上运行:monopiped -l 127.0.0.1:3000 -t 127.0.0.1:22 -d -k key.bin -w

然后在客户端,您可以通过运行以下命令连接到SSH服务器:ssh -p3000 127.0.0.1

以下是一个示例 Caddyfile,用于与Caddy v2 web服务器一起使用,以设置到WebSocket后端的路由,其中后端将是在端口3000上侦听WebSocket模式的monopiped

server.example.com:80 server.example.com:443 {
        root * /var/www/html
        file_server
        reverse_proxy /ssh 127.0.0.1:3000
}

上述Caddyfile同时监听HTTP和HTTPS。由于WebSocket或TCP之间的传输是端到端加密的,因此使用HTTP是完全可行的,同时保持机密性和完整性。通过HTTP的流量抓包将仅显示WebSocket二进制负载和其他少量内容。

愿望

目前程序实现了每个连接一个线程的模型。为了最小化资源并提高可伸缩性(如果需要的话),可能将模型切换到使用Tokio的异步网络I/O。

也支持通过WebSockets进行代理将很棒。

依赖关系

~9–23MB
~329K SLoC