muonsocks
简介
这是对 rofl0r 的优秀 microsocks 程序的增强,包含以下 更改:
- 支持 SOCKS4a 客户端
- 支持禁用出站 ipv4 或 ipv6
- 支持更改 uid 和 chroot
- 支持绑定到多个 ip/port 元组
- 重写了 SOCKS5 解析器,能够容忍跨多个 recv() 分割的输入
- 通过更大的缓冲区减少 poll 调用次数来提升性能
- 使用 TCP_NODELAY 以降低延迟影响
- 使用无锁列表而非动态数组用于线程
- 初始化后内存分配极少,且堆碎片化程度低
- 增强了错误处理
muonsocks 作为服务器完全支持 SOCKS5 和 SOCKS4a TCP 代理。
它继承了 microsocks 的优秀设计,因此唯一的实际限制 是由可用的 RAM 和文件描述符限制决定的。 OOM 不会 导致终止,并且显式内存分配和堆 碎片化被最小化。
与 microsocks 的约 600 LoC 相比,它约为 1000 LoC,因此它 不是最精简的,但它仍然是一个非常小的程序(在 amd64 上动态 链接到 glibc 时约为 27KiB)。
要求
- Linux 或 BSD 系统
- GCC 或 Clang
- GNU Make
标准用法
编译并安装 muonsocks。
- 构建 muonsocks:
make - 将
muonsocks可执行文件安装到常规位置。 我建议/usr/local/bin。
为 muonsocks 设置用户账户和 chroot 目录。 示例:
$ su -
# umask 077
# groupadd muonsocks
# useradd -d /var/empty -s /sbin/nologin -g muonsocks muonsocks
然后可以类似地运行该程序:
# muonsocks -u muonsocks -C /var/empty -4 -i 192.168.0.1 -i 10.0.0.1 -p 1080
这将运行一个 SOCKS5 服务器,监听 192.168.0.1:1080 和 10.0.0.1:1080 上的请求,且仅发送出站 IPv4 请求。
我建议通过 s6](http://www.skarnet.org/software/s6) 等进程监督程序来运行 muonsocks。 这将允许在 发生意外或不可恢复的错误时可靠地运行。
有关命令行选项的完整信息,请运行:
$ muonsocks -?
历史 / 设计缘由
我此前使用过一个我自己编写的名为 nsocks 的 SOCKS 服务器。它采用了一种事件驱动模型,试图利用 Linux 的 splice() 来减少 kernel->userspace->kernel 的拷贝。然而,事件驱动模型对于 HTTP 等纯服务器比对于代理更为适用;对于事件驱动代理而言,在所有情况下都难以妥善控制缓冲,但在使用线程和谨慎使用阻塞写入时,缓冲则是自然的。splice() 也仅带来了微乎其微的性能提升,却使程序变得显著复杂。
当我对修复 nsocks 中的许多边缘情况感到厌倦时,我最终使用了原始的 microsocks,并预期只是临时使用它;我添加了一些我需要的功能,并移植了 nsocks 中经过充分测试的部分,例如 SOCKS4 支持。由于 nsocks 是用 C++ 编写的,我直接使用了 C++,而不是将我的代码移植到 C。
经过相对较少的工作,我本地的 microsocks 版本(我最终将其命名为 muonsocks)运行无故障,我最终也没有动力去编写另一个服务器。几年后,我最终将其移植回 C 并进行了进一步的改进。
下载
以下是原始 microsocks 的 README
MicroSocks - 多线程、小巧、高效的 SOCKS5 服务器。
一个可以在你的远程机器上运行的 SOCKS5 服务,用于通过它们隧道连接, 如果由于某种原因 SSH 无法满足你的需求。
它非常轻量,对资源的占用也非常少:
对于每个客户端,都会生成一个栈大小为 8KB 的线程。 主进程基本上不消耗任何资源。
唯一的限制是文件描述符的数量和 RAM。
它还被设计得非常健壮:通过简单地拒绝新连接来优雅地处理资源耗尽, 而不是像如今大多数程序那样调用 abort()。
另一个优点是易用性:无需配置文件,一切都可以通过命令行完成, 甚至快速设置都不需要任何参数。
历史
这是 "rocksocks5" 的继任者,其编写时有着 不同的目标:
- 优先使用标准 libc 函数而非自研函数
- 没有人为限制
- 不追求最小的二进制大小,而是追求最小的源代码大小, 以及最大的可读性、可重用性和可扩展性。
因此,ipv4、dns 和 ipv6 开箱即用 并且可以使用相同的代码,而 rocksocks5 有几个编译时 定义,以便将最终二进制文件的大小降低到极端值, 例如仅启用 ipv4 支持时静态链接为 10 KB。
尽管如此,如果针对大小进行优化,这个 程序静态链接 musl libc 后甚至不到 50 KB。即使在最便宜的路由器上也很容易使用。
命令行选项
muonsocks -1 -i listenip -p port -U user -P password -b bindaddr
所有参数均为可选。 默认情况下 listenip 为 0.0.0.0,port 为 1080。
选项 -1 启用 auth_once 模式:当某个特定 ip 地址 使用 user/pass 成功认证后,它将被添加到白名单 中,并可在无需认证的情况下使用代理。 这对于像 firefox 这样不支持 user/pass 认证的程序非常有用。要使其生效,你基本上需要 使用另一个支持该功能的程序建立一个连接,然后就可以使用 firefox 了。