Loading... # next-socks5:基于 Rust 的轻量级 SOCKS5 服务器实战指南 # 一、概述 ## 1. 简介 ### A. 是什么 next-socks5 是一个用 Rust 编写的轻量级、可扩展的 SOCKS5 服务器,完整实现了 RFC 1928 与 RFC 1929 协议规范。项目由 ZingerLittleBee 开源维护,采用纯 Rust 编写,无任何 C 依赖,可生成完全静态的 musl 二进制文件以及基于 scratch 的约 3.5 MB 容器镜像。 项目核心特点: - 自研协议栈:手写 SOCKS5 协议解析,依赖足迹刻意保持精简 - 双模式运行:TUI 终端仪表盘与适合容器的 headless 模式 - 安全默认:默认开启出口流量过滤,防止 SSRF 与开放中继 - 多种部署:支持一键脚本、Docker、预编译二进制、源码编译四种方式 ### B. 为什么学 传统 SOCKS5 实现(如 Dante、3proxy)存在以下痛点: - 老牌服务器多为 C 语言实现,依赖复杂,编译环境要求高 - 缺乏现代运维所需的可观测性工具 - UDP 中继在 NAT 与容器环境下配置繁琐 - 安全默认不足,容易因配置疏忽变成开放中继 next-socks5 通过 Rust 的内存安全特性、TUI 仪表盘的实时观测能力、以及为 NAT/Docker 场景设计的 UDP 配置选项,系统性地解决了这些问题。 ### C. 学完能做什么 - 在自建服务器或云主机上快速部署一个安全的 SOCKS5 代理 - 使用 TUI 仪表盘实时观测吞吐、连接数与错误统计 - 在 NAT、Docker bridge 等复杂网络环境下正确配置 UDP 中继 - 根据 RFC 1928 规范理解 SOCKS5 协议的工作原理 ## 2. 前置知识 ### A. 必备技能 - 基本的 Linux 命令行操作能力 - 了解 TCP/UDP 协议基础 - 熟悉代理服务器的基本概念 ### B. 推荐知识 - Rust 编程基础(仅在源码编译时需要) - Docker 与 docker compose 的使用 - 防火墙配置(iptables、ufw 或 nftables) # 二、核心特性 ## 1. 协议支持 ### A. SOCKS5 命令 next-socks5 支持 RFC 1928 定义的核心命令: | 命令 | 支持情况 | 说明 | |------|---------|------| | CONNECT | 完整支持 | 用于 TCP 流量代理,如 HTTP、HTTPS | | UDP ASSOCIATE | 完整支持 | 用于 UDP 流量代理,如 DNS、QUIC | | BIND | 设计拒绝 | 按设计返回回复码 0x07,出于安全考虑不开放 | ### B. 认证机制 支持两种认证方式: - No-Auth(0x00):无认证,适用于受信任网络 - Username/Password(0x02):用户名密码认证,符合 RFC 1929 规范 认证模式下可配置多组凭证:客户端只要匹配列表中任意一组用户名密码即可通过,无需为每个用户开放独立端口。 ### C. 地址类型 支持三种 ATYP(Address Type): - 0x01:IPv4 地址 - 0x04:IPv6 地址 - 0x03:Domain 域名(服务器端执行 DNS 解析) 无论是 CONNECT 还是 UDP ASSOCIATE 目标,服务器都会执行 DNS 解析,避免客户端泄露真实 DNS 请求。 ### D. RFC 错误码映射 完整覆盖 RFC 1928 定义的回复码 0x00 至 0x08,典型映射关系: | 场景 | 回复码 | 含义 | |------|--------|------| | 成功 | 0x00 | succeeded | | 连接数超限 | 0x02 | connection not allowed by ruleset | | 网络不可达 | 0x03 | network unreachable | | 主机不可达 | 0x04 | host unreachable | | 连接被拒 | 0x05 | connection refused | | TTL 过期 | 0x06 | TTL expired | | 不支持的命令 | 0x07 | command not supported | | 不支持的地址类型 | 0x08 | address type not supported | ## 2. 安全设计 ### A. 出口过滤默认开启 服务器默认拒绝转发到以下地址段,作为 SSRF 与开放中继的防护: - 回环地址(127.0.0.0/8、::1) - 链路本地地址(169.254.0.0/16),包括云元数据地址 169.254.169.254 - 私有地址段(RFC 1918:10.0.0.0/8、172.16.0.0/12、192.168.0.0/16) 如确实需要访问内部目标,可通过配置文件中的 egress 段放宽限制。 ### B. 防 slowloris 攻击 握手阶段(greeting + auth + request)设置了独立的超时时间(默认 10 秒),超过 handshake_ms 未完成握手的连接将被强制断开,防止慢速攻击占用连接资源。 ### C. 连接数限制 提供两个可选的并发上限配置: - max_connections:全局并发上限,防止文件描述符耗尽 - max_per_ip:单 IP 并发上限,防止单客户端独占资源或暴力破解 两个限制默认不启用,需要根据实际场景显式配置。 ## 3. 性能与体量 ### A. 性能表现 在单台 4 核云主机(loopback 测试)上: - 中继吞吐:约 2 GB/s - 单请求附加延迟:约 1.6 ms - 新建连接速率:约 6000 次/秒 profiling 结果显示代理本身受限于内核网络栈,不存在锁竞争,proxy 不是性能瓶颈。 ### B. 体量小巧 - 静态 musl 二进制:约 3.5 MB 容器镜像(scratch 基础镜像) - 无 C 依赖:纯 Rust 实现,便于跨平台分发 - Headless 构建:可移除 ratatui 与 crossterm 依赖,进一步减小体积 ```mermaid graph LR A[客户端] -->|SOCKS5 协议| B[next-socks5 服务器] B -->|出口过滤检查| C{是否允许?} C -->|允许| D[目标服务器] C -->|拒绝| E[返回错误] D -->|响应数据| B B -->|代理响应| A subgraph 服务器内部 F[协议解析] --> G[认证校验] G --> H[命令处理] H --> I[CONNECT 中继] H --> J[UDP ASSOCIATE 中继] end ```  # 三、安装方式 ## 1. 一键脚本(推荐) ### A. 基础用法 一键脚本会自动选择 binary 或 docker 方式,生成凭证与空闲端口,并启动服务: ```bash # 默认安装:binary 方式,开启认证,自动生成用户名密码与端口 curl -fsSL https://raw.githubusercontent.com/ZingerLittleBee/next-socks5/main/install.sh | sh ``` ### B. 常用参数 通过 -s -- 将参数传递给 install.sh: ```bash # 指定端口 curl -fsSL https://raw.githubusercontent.com/ZingerLittleBee/next-socks5/main/install.sh \ | sh -s -- --port 1080 # 使用 Docker 方式(host 网络,UDP ASSOCIATE 可用) curl -fsSL https://raw.githubusercontent.com/ZingerLittleBee/next-socks5/main/install.sh \ | sh -s -- --method docker # 显式指定凭证 curl -fsSL https://raw.githubusercontent.com/ZingerLittleBee/next-socks5/main/install.sh \ | sh -s -- --method docker --auth --user alice --pass secret --port 1080 # 仅监听本地 curl -fsSL https://raw.githubusercontent.com/ZingerLittleBee/next-socks5/main/install.sh \ | sh -s -- --no-auth --listen 127.0.0.1 --port 1080 ``` ### C. 完整参数表 | 参数 | 说明 | 默认值 | |------|------|--------| | --method <binary\|docker> | 安装方式 | binary | | --auth / --no-auth | 是否启用认证 | --auth | | --user / --pass | 认证凭证 | 随机生成 | | --port <port> | 监听端口 | 随机空闲端口 | | --listen <addr> | 绑定地址 | 0.0.0.0 | | --udp-port-range <range> | UDP 中继端口范围 | 操作系统临时端口 | | --udp-advertise <ip> | UDP 通告 IP(NAT 后) | 绑定的本地 IP | | --version <tag> | 指定版本 | latest | | --bin-dir <dir> | 二进制安装目录(binary 方式) | /usr/local/bin | | --dir <dir> | compose 部署目录(docker 方式) | ./next-socks5-deploy | | --no-service | 仅安装不启动服务 | 关闭 | ### D. 平台与初始化系统支持 binary 安装目标为 Linux(musl x86_64/aarch64),会自动配置 systemd 或 OpenRC 服务。若系统两者均不存在,二进制与配置文件仍会被安装,但不会自动启动,需要手动启动或选择 docker 方式。脚本仅依赖 POSIX sh,无需 bash。 ## 2. Docker 部署 ### A. 通过安装脚本生成 Compose 最简单的方式:让安装脚本自动生成 docker-compose.yml 与 config.toml 并启动容器: ```bash curl -fsSL https://raw.githubusercontent.com/ZingerLittleBee/next-socks5/main/install.sh \ | sh -s -- --method docker --auth --port 1080 ``` 文件生成在 ./next-socks5-deploy/ 目录,可通过 --dir 覆盖,随后执行 docker compose up -d。 ### B. 手动 docker run 无认证模式,使用 host 网络以保证 UDP ASSOCIATE 可用: ```bash docker run -d --name next-socks5 --network host \ ghcr.io/zingerlittlebee/next-socks5:latest --listen 0.0.0.0:1080 ``` 使用配置文件(启用认证): ```bash docker run -d --name next-socks5 --network host \ -v "$PWD/config.toml:/etc/next-socks5/config.toml:ro" \ ghcr.io/zingerlittlebee/next-socks5:latest --config /etc/next-socks5/config.toml ``` ### C. docker-compose 编排 ```yaml services: next-socks5: image: ghcr.io/zingerlittlebee/next-socks5:latest container_name: next-socks5 restart: unless-stopped network_mode: host volumes: - ./config.toml:/etc/next-socks5/config.toml:ro tmpfs: - /run/next-socks5 command: ["--config", "/etc/next-socks5/config.toml"] ``` 启动服务: ```bash docker compose up -d ``` 镜像支持多架构(linux/amd64、linux/arm64),同时打有版本号(如 0.1.0)与 latest 标签。容器始终以 headless 模式运行。 ### D. tmpfs 与 admin socket 容器以非特权用户(uid 65534)运行,需要可写的 /run/next-socks5 目录用于 admin socket。若不挂载 tmpfs,attach 命令将无法连接,服务日志会出现 admin endpoint disabled: Permission denied。 ## 3. 预编译二进制 从 Releases 页面下载静态 musl 构建版本: ```bash curl -fL -o next-socks5.tar.gz \ https://github.com/ZingerLittleBee/next-socks5/releases/latest/download/next-socks5-x86_64-unknown-linux-musl.tar.gz tar xzf next-socks5.tar.gz ./next-socks5-x86_64-unknown-linux-musl/next-socks5 serve --no-tui --listen 0.0.0.0:1080 ``` ARM64 架构将 x86_64 替换为 aarch64 即可。 ## 4. 源码编译 需要较新版本的 Rust 稳定工具链: ```bash git clone https://github.com/ZingerLittleBee/next-socks5 cd next-socks5 cargo build --release ./target/release/next-socks5 serve # 启用 TUI ./target/release/next-socks5 serve --no-tui # headless 模式 # 仅编译 headless 版本(移除 TUI 依赖) cargo build --release --no-default-features ``` 也可直接从 git 安装: ```bash cargo install --git https://github.com/ZingerLittleBee/next-socks5 ``` # 四、配置说明 ## 1. 配置文件结构 配置采用 TOML 格式(参考仓库中的 config.example.toml),CLI 参数会覆盖配置文件中的同名项。 ```toml listen = "0.0.0.0:1080" [auth] method = "password" # "none" 或 "password" [[auth.users]] username = "alice" password = "secret" [[auth.users]] username = "bob" password = "hunter2" [timeouts] handshake_ms = 10000 connect_ms = 10000 tcp_idle_ms = 300000 udp_idle_ms = 60000 [limits] max_connections = 2048 max_per_ip = 64 [admin] enabled = true # socket = "/run/next-socks5/admin.sock" ``` ## 2. 认证配置 ### A. 多用户支持 method = "password" 时,每个凭证配置一个 [[auth.users]] 段,客户端匹配任意一组凭证即通过认证(RFC 1929)。这是在同一端口服务多个用户的标准做法,无需为每个用户开放独立端口。 ### B. 开放代理 method = "none" 时为开放代理,users 列表将被忽略。仅在受信任网络中部署时使用此模式,仪表盘仍会记录每次认证尝试。 ## 3. 超时与连接限制 ### A. 超时配置 | 配置项 | 说明 | 默认值 | |--------|------|--------| | handshake_ms | 握手阶段总时限(防 slowloris) | 10000 | | connect_ms | 连接目标服务器超时 | 10000 | | tcp_idle_ms | TCP 连接空闲回收时间 | 300000 | | udp_idle_ms | UDP 关联空闲回收时间 | 60000 | ### B. 连接数限制 两个限制项均为可选,默认不设上限: - max_connections:全局并发上限,作为文件描述符/任务耗尽的兜底 - max_per_ip:单 IP 并发上限,防止单一客户端独占或暴力破解 每条 CONNECT 中继占用约 2 个文件描述符,配置时需参考操作系统的 RLIMIT_NOFILE 上限。公网部署场景建议同时配置两项。 ### C. 公网部署建议 next-socks5 内置无认证速率限制,公网暴露时建议: - 同时设置 max_connections 与 max_per_ip - 在监听端口前部署主机防火墙或 fail2ban - 保持默认的出口过滤开启 ## 4. UDP 中继配置 ### A. UDP 在 NAT 与 Docker 中的挑战 CONNECT 仅使用单个 TCP 监听端口即可工作,但 UDP ASSOCIATE 需要独立的 UDP 中继 socket。默认情况下每个关联绑定一个操作系统分配的临时端口,服务器通告客户端必须发送数据报到的 BND.ADDR:BND.PORT(RFC 1928)。 通过 [udp] 段两个选项可让 UDP 在防火墙与 NAT 后正确工作: ```toml [udp] port_range = "40000-40100" advertise = "203.0.113.42" ``` ### B. port_range(端口范围) 将每个关联的 UDP socket 绑定到指定范围内,而非随机临时端口,这样防火墙/NAT 只需开放该范围。 - 每个关联独占一个 socket,范围大小应大于等于预期并发 UDP 客户端数 - "40000-40000" 表示单端口,UDP 将串行处理 - 范围耗尽时,新的 UDP ASSOCIATE 返回 general failure ### C. advertise(通告地址) 填入 UDP ASSOCIATE 回复中的 IP 地址。默认情况下服务器通告客户端 TCP 连接到达的服务器侧 IP(控制 socket 的本地地址)。 - 当该 IP 客户端不可达时(NAT 后或 Docker bridge 网络),需要覆盖 - 通告端口始终是真实绑定的端口,因此 NAT/转发必须是端口保留(1:1) - 通告地址不可达是 TCP 通但 UDP 不通的首要原因 - 接受裸 IP 或 ip:port 格式(端口被忽略),格式错误会在启动时拒绝 ## 5. Docker 网络配置 ### A. host 网络(推荐) 提供的 compose 使用 network_mode: host(Linux),无需端口映射: ```yaml network_mode: host ``` ### B. bridge 网络 发布 TCP 控制端口与 UDP 范围时必须使用短语法(compose 长语法不支持范围),并设置 advertise 为宿主机公网 IP: ```yaml ports: - "1080:1080/tcp" - "40000-40100:40000-40100/udp" ``` ### C. 防火墙规则 需要开放控制端口 1080/tcp 与 UDP 范围 40000-40100/udp: ```bash # ufw ufw allow 1080/tcp && ufw allow 40000:40100/udp # nftables nft add rule inet filter input udp dport 40000-40100 accept # iptables iptables -A INPUT -p udp --dport 40000:40100 -j ACCEPT ``` ### D. 端口重映射 NAT 的限制 端口重映射(PAT/对称)NAT 无法与多端口范围协同工作(转换后通告的内部端口不正确)。可选方案: - 使用单固定端口("40000-40000")配合 1:1 转发 - 或直接部署在可达公网 IP 上 # 五、使用方法 ## 1. 命令行接口 next-socks5 提供三个子命令: ```text next-socks5 打印帮助(裸调用永不启动服务器) next-socks5 serve [OPTIONS] 运行服务器(别名 run) next-socks5 attach [OPTIONS] 附加到运行中的服务器仪表盘 ``` ### A. 服务器选项 | 参数 | 说明 | |------|------| | --config <path> | TOML 配置文件路径 | | --listen <addr> | 覆盖监听地址(如 0.0.0.0:1080) | | --no-tui | headless 模式(事件输出到 stdout) | | --no-admin | 禁用本地 admin/attach 端点 | | --admin-socket <path> | 覆盖 admin socket 路径 | | -h, --help | 打印帮助 | ### B. attach 选项 | 参数 | 说明 | |------|------| | --socket <path> | 连接的 admin socket(默认 /run/next-socks5/admin.sock) | ## 2. 启动服务 ### A. TUI 模式(默认) 不带 --no-tui 直接运行服务器即可启动仪表盘: ```bash next-socks5 serve --listen 127.0.0.1:1080 ``` ### B. headless 模式 适用于 systemd 与容器场景,事件流输出到 stdout: ```bash next-socks5 serve --no-tui --listen 0.0.0.0:1080 ``` ## 3. TUI 仪表盘 仪表盘默认开启,展示以下信息: - 实时吞吐(含 30 秒趋势图) - 成功/错误统计 - 可排序的活跃连接表 - 滚动日志面板 ### A. 键位映射 | 按键 | 功能 | |------|------| | Tab | 在连接表与日志面板间切换焦点(聚焦面板会高亮) | | s | 循环切换排序键:ID、UP↓、DOWN↓、AGE↓(显示在表标题中) | | ↑/↓ 或 k/j | 焦点面板单行滚动 | | PgUp/PgDn | 焦点面板整屏滚动 | | q / Ctrl-C | 退出 | ### B. 模拟数据预览 为便于演示或测试仪表盘功能,可使用 --mock 参数注入合成数据流: ```bash # 本地预览 cargo run --release -- serve --listen 127.0.0.1:1080 --mock # 已安装二进制 next-socks5 serve --listen 127.0.0.1:1080 --mock ``` --mock 仅供演示与测试,生产环境切勿启用。 ## 4. Attach 已运行服务 通过 systemd/OpenRC/Docker 安装的服务以 headless 模式运行,但仍通过本地 Unix socket(默认 /run/next-socks5/admin.sock)提供实时仪表盘。在同一台机器上即可附加观察,无需重启,也无需额外开关。 ### A. 基本用法 ```bash # 1. SSH 到服务所在主机(默认 socket 需要 root) ssh root@your-server # 2. Attach 到默认 socket next-socks5 attach # Docker:在容器内执行 docker exec -it next-socks5 next-socks5 attach ``` ### B. 自定义 socket 路径 ```bash next-socks5 attach --socket /tmp/ns5.sock ``` ### C. 安全特性 - 仅本地访问,无网络暴露 - 无认证机制(依赖本地权限) - 只读:attach 客户端只能观察,不能控制服务器 按 q 可分离;服务器停止时仪表盘会显示 connection lost 后退出。 ### D. 手动安装场景 --no-service 手动安装时,进程以当前用户运行,默认 /run 路径通常不可写。需指定可写的 socket 路径: ```bash next-socks5 serve --no-tui --admin-socket /tmp/ns5.sock next-socks5 attach --socket /tmp/ns5.sock ``` # 六、工作原理 ## 1. SOCKS5 协议基础 SOCKS5 协议定义于 RFC 1928,工作流程分为三个阶段: ```mermaid flowchart TD A[阶段一:协商] --> B[阶段二:认证] B --> C[阶段三:请求处理] C --> D{命令类型} D -->|CONNECT| E[TCP 中继] D -->|UDP ASSOCIATE| F[UDP 中继] D -->|BIND| G[拒绝 0x07] E --> H[双向数据转发] F --> H ```  ## 2. CONNECT 流程详解 ```mermaid sequenceDiagram participant U as 用户 participant C as next-socks5 客户端 participant S as next-socks5 服务器 participant T as 目标服务器 U->>C: curl --socks5 C->>S: TCP 握手 greeting S-->>C: 选择认证方式 C->>S: 凭证 RFC 1929 S-->>C: 认证成功 C->>S: CONNECT 请求 ATYP + DST.ADDR + DST.PORT S->>S: 出口过滤检查 S->>T: 建立连接 T-->>S: 连接建立 S-->>C: 回复 0x00 成功 C->>T: 双向中继数据 ```  ### A. 协商阶段 客户端连接服务器后发送 greeting 消息,包含客户端支持的认证方式列表。服务器从中选择一种,返回所选方式。 ### B. 认证阶段 若服务器选择用户名/密码认证(0x02),客户端发送 RFC 1929 定义的凭证,服务器校验后返回成功或失败。 ### C. 请求阶段 认证通过后,客户端发送请求,包含命令类型、目标地址类型与目标地址。服务器根据命令执行相应操作。 ## 2. UDP ASSOCIATE 实现细节 ### A. UDP 封装格式 UDP ASSOCIATE 使用独立的 UDP socket 转发数据,每个数据报需按 RFC 1928 封装: | 字段 | 含义 | |------|------| | RSV | 保留字段(2 字节,0x0000) | | FRAG | 分片标志(next-socks5 丢弃 FRAG != 0 的分片) | | ATYP | 目标地址类型 | | DST.ADDR | 目标地址 | | DST.PORT | 目标端口 | | DATA | 实际数据报内容 | ### B. 安全约束 next-socks5 在 UDP 中继中实施以下安全策略: - 丢弃 FRAG != 0 的分片,避免重组攻击 - 源 IP 过滤:仅接受来自控制连接客户端 IP 的数据报 - BND.ADDR 永不为 0.0.0.0,确保客户端有可达地址 - 空闲回收:超过 udp_idle_ms 无活动的关联自动清理 ## 3. 出口过滤机制 默认出口过滤作为 SSRF 防护层,覆盖以下范围: ```mermaid flowchart LR A[目标地址] --> B{出口过滤检查} B -->|回环地址| C[拒绝] B -->|链路本地| C B -->|私有地址段| C B -->|公网地址| D[允许转发] D --> E[建立连接] C --> F[返回错误] ```  # 七、最佳实践 ## 1. 公网部署 公网部署场景建议遵循以下原则: - 始终启用用户名密码认证,避免开放代理 - 同时配置 max_connections 与 max_per_ip,防止资源耗尽 - 保持默认出口过滤开启,防止 SSRF 攻击 - 在监听端口前部署防火墙或 fail2ban,弥补认证速率限制的缺失 - 选择复杂凭证,密码至少 20 字符 ## 2. NAT 与 Docker 环境 UDP 在 NAT/容器环境中需特别注意: - 优先使用 host 网络模式,避免端口映射问题 - bridge 模式下使用短语法发布端口范围 - advertise 地址必须为客户端可达的公网 IP - 范围大小应覆盖预期并发 UDP 客户端 - 端口重映射 NAT 场景使用单固定端口配合 1:1 转发 ## 3. 容器化部署 Docker 部署的最佳实践: - 始终挂载 tmpfs /run/next-socks5,确保 admin socket 可用 - 配置文件以只读方式挂载 - 设置 restart: unless-stopped 实现自重启 - 使用版本标签而非 latest,便于版本追踪 ## 4. 监控与观测 利用内置 TUI 仪表盘进行实时观测: - 通过吞吐趋势图发现流量异常 - 通过错误统计发现认证失败激增 - 通过活跃连接表识别可疑连接 - 对生产环境使用 attach 远程观察,不影响服务 *** ## 参考资料 1. [next-socks5 GitHub 仓库](https://github.com/ZingerLittleBee/next-socks5) 2. [RFC 1928: SOCKS Protocol Version 5](https://www.rfc-editor.org/rfc/rfc1928) 3. [RFC 1929: Username/Password Authentication for SOCKS V5](https://www.rfc-editor.org/rfc/rfc1929) 4. [next-socks5 性能测试文档](https://github.com/ZingerLittleBee/next-socks5/blob/main/docs/PERFORMANCE.md) 5. [next-socks5 配置示例](https://github.com/ZingerLittleBee/next-socks5/blob/main/config.example.toml) 最后修改:2026 年 07 月 03 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏