1 个不稳定版本
0.1.0 | 2023年7月27日 |
---|
#2 在 #web-socket
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