前言
代理应用的版图已变得拥挤且碎片化,因此——出于个人兴趣——我决定将我使用的那些整合成一个单一的百科全书式的应用。
Chimera_Client借鉴了开源 clash-rs 项目,长期目标是对齐 Mihomo 的功能集。Chimera参考了 clash-nyanpasu 项目,但关键区别在于我的首要目标是对chimera_client引擎本身提供一流支持,它在很大程度上可视为clash-rs的核心。Chimera_Server项目可视为 xray-core 的 Rust 实现,并以保持与原版xray-core兼容为最终目标。此外,其实现基于开源项目 shoes。
项目链接
clash-rs: https://github.com/Watfaq/clash-rsMihomo: https://github.com/MetaCubeX/mihomoclash-nyanpasu: https://github.com/libnyanpasu/clash-nyanpasuxray-core: https://github.com/XTLS/Xray-coreshoes: https://github.com/cfal/shoes
简介
This documentation set introduces the proxy ecosystem maintained in this repository, focusing on three core projects: Chimera_Client, Chimera, and Chimera_Server. Each module targets a different layer of the overall stack—client core, client GUI, and server core—but they share a common goal: delivering reliable, high-performance connectivity under diverse network conditions. The following chapters explain how these applications work together, what problems each component solves, and how teams can deploy and extend them.
此外,每个项目的文档通常分为两大部分:一部分是面向普通用户的配置指南,用于快速上手和日常使用;另一部分是面向开发者的高级参考,旨在帮助他们理解实现细节、扩展能力,并支持后续开发。
系统拓扑
参考部署将 clash-rs 客户端与一个或多个 Chimera 前端配对,二者都构建在chimera_core 提供的共享原语之上。客户端通常运行在用户设备或边缘节点上,在那里接管本地应用并将出站流量转换为代理可感知的流。随后这些流经由安全隧道到达Chimera,后者在转发数据包至上游服务或公网之前完成认证、路由与协议终止。
由于整个栈以 chimera_core 为中心,对加密套件、多路复用策略或配置模式的升级会立即在两端生效,最大限度减少版本偏差。可观测性也被统一:各层发出的遥测共享标识符,使请求链路能够端到端追踪。
Chimera_Client
当前支持的协议与传输
- Trojan + WS
- Hysteria2
- Reality + TCP
- SOCKS5
- HTTP
- Xhttp
未来支持
- gRPC
- VMess
- WireGuard
- SSH
角色与目标
chimera_client 是 Chimera 生态中的 Clash 兼容客户端运行时。它的设计目标是在兼容现有 Clash/Mihomo 配置的同时,利用 Rust 的类型安全与异步生态构建一个可维护的代码库。
对运维人员而言,这意味着:
- 保留熟悉的配置与策略心智模型。
- 通过明确的 schema 与模块边界提升实现清晰度。
- 支持渐进式对齐:从稳定的基础能力(如 SOCKS 入站 + rules)开始,再逐步补齐与
clash-rs和 Mihomo 之间的特性差距。
与 Clash-rs 和 Mihomo 的关系
chimera_client 文档将 clash-rs 和 Mihomo 视为两个最重要的参考实现:
- clash-rs:用于解析器 / 运行时行为和配置语义的 Rust 原生参考实现。
- Mihomo:广泛生态兼容性和高级运维特性的事实生产参考。
在本章中,每个模块页面都会明确标注:
chimera_client当前已可用的内容,- 什么是与 Clash/Mihomo 兼容的目标行为,
- 以及当前应采取哪些迁移注意事项。
架构概览
在内部,客户端被组织为四层:
- 配置层
- 将 Clash 风格 YAML 解析为类型化的 Rust 结构。
- 处理默认值、校验与热重载边界。
- 入站 / 控制层
- 负责本地监听器(SOCKS/HTTP/mixed/TUN,随对齐进展逐步完善)。
- 暴露用于状态查询、切换与诊断的管理 API。
- 策略与 DNS 层
- 以首条命中语义执行规则链。
- 提供 DNS 策略原语(当前为系统解析器,目标是 Clash 风格 DNS)。
- 出站传输层
- 执行协议握手与流转发。
- 封装协议特定参数,同时复用通用 TLS / socket 工具。
这种划分与常见的 Clash 家族架构一致,并降低了解析器、运行时与协议引擎之间的耦合。
模块指南
每个功能区域都独立成文:
- 端口与监听器:键名映射与当前入站支持情况。参见端口与监听器。
- DNS 模块:fake-IP 与 real-IP 模型、解析器策略,以及当前实现状态。参见DNS 模块。
- TUN 模块:route-all / split-route 语义与 Linux 策略路由说明。参见Tun 模块。
- 规则模块:规则分类、排序策略与基于 provider 的策略组合。参见规则类型及其作用。
兼容性概览(英文文档,当前)
| 区域 | chimera_client(当前) | clash-rs / Mihomo 参考 |
|---|---|---|
| 入站监听器 | socks_port 可用;其他项部分实现 / 开发中 | 完整的 Clash 家族监听器矩阵 |
| DNS | 主要走系统解析器路径;Clash 风格配置块作为目标形态记录 | 成熟的 fake-IP / real-IP / 分流解析工作流 |
| TUN | 已记录目标模型;主线尚未完全启用 | 成熟的跨平台实现 |
| 规则 | 核心 Clash 规则语言已有文档并完成对齐 | 完整的规则 / provider 生态 |
可将此表作为阅读索引:各模块页面会进一步说明示例与注意事项。
部署模式
当前推荐的类生产使用模式:
- 从基于 SOCKS 的本地代理开始。
- 除非你正在验证开发中的 DNS 分支,否则应对 DNS 配置保持保守。
- 先使用显式规则顺序和较小的 provider 集,再逐步扩展。
- 仅在对齐分支和环境前置条件都验证完成后再启用 TUN。
对于 CI / 测试,建议同时保留一个最小配置和一个 Clash/Mihomo 对齐配置,以尽早发现解析器 / 运行时偏差。
性能与运维重点
长期性能策略与 Clash 家族工作负载保持一致:
- 可预测、低开销的规则匹配,
- 长生命周期会话下受控的内存行为,
- 以及面向策略调试的高可观测性。
在引入对齐特性(DNS/TUN/监听器)时,应优先保证确定性行为和可调试性,而不是依赖隐式的“魔法”默认值。
参考仓库
chimera_client:https://github.com/MFSGA/Chimera_Clientclash-rs: https://github.com/Watfaq/clash-rsmihomo: https://github.com/MetaCubeX/mihomo
各种端口
概览
端口定义了本地应用、控制面板和 DNS 解析器如何接入 chimera_client。本页会交叉对照 Clash-rs 与 Mihomo 的语义,并明确说明 chimera_client 的当前状态。
键名映射
| Clash / Mihomo 键名 | chimera_client 键名 | 用途 |
|---|---|---|
port / http-port | port | HTTP CONNECT / 明文代理监听器 |
socks-port | socks_port | SOCKS5 监听器 |
mixed-port | mixed_port | 共享的 HTTP + SOCKS 监听器 |
redir-port | redir_port | Linux TCP 透明 REDIRECT |
tproxy-port | tproxy_port | Linux TPROXY(TCP/UDP) |
external-controller | external_controller | REST 控制器端点 |
dns.listen | dns.listen | 本地 DNS 套接字 |
按监听器类型划分的行为
HTTP 代理(port / http-port)
- 典型的浏览器 / 系统代理入口。
- 需要 HTTP CONNECT 与 HTTP 代理语义。
SOCKS5(socks-port)
- 兼容性最广的应用层入站。
- 支持直接与应用集成,无需修改内核路由。
混合(mixed-port)
- 单一端口同时承载 HTTP 和 SOCKS 协议。
- 适用于客户端只允许配置一个代理端点的场景。
Redir(redir-port)
- 通过 iptables REDIRECT 实现的 Linux TCP 透明捕获。
- 本身不捕获 UDP。
TProxy(tproxy-port)
- Linux 上的透明 TCP+UDP 捕获路径。
- 需要策略路由(
fwmark+ route table)与防火墙集成。
外部控制器(external-controller)
- 供控制面板与自动化使用的管理 API。
- 除非需要远程访问,否则优先绑定回环地址。
DNS 监听(dns.listen)
- 用于 fake-IP / 分流 DNS 工作流的本地解析器套接字。
- 通常与 TUN 或透明代理模式配套使用。
兼容性状态矩阵
| 特性 | chimera_client 当前状态 | clash-rs / Mihomo |
|---|---|---|
| SOCKS5 入站 | 可用 | 可用 |
| SOCKS UDP Associate | 当前说明中受限 / 禁用 | 可用 |
| HTTP 入站 | 预留 / 计划中 | 可用 |
| 混合入站 | 预留 / 计划中 | 可用 |
| Redir 入站 | 预留 / 计划中 | 可用 |
| TProxy 入站 | 预留 / 计划中 | 可用 |
| 外部控制器 | 积极开发中 | 成熟 |
| 本地 DNS 监听器 | 积极开发中 | 成熟 |
当前推荐用法
- 优先使用
socks_port作为稳定入站。 - 开发期间将管理和 DNS 绑定保持在
127.0.0.1。 - 除非你的分支显式启用了它们,否则应将非 SOCKS 入站视为兼容性键。
配置示例
最小化 chimera_client 配置(当前安全)
bind_address: "127.0.0.1"
allow_lan: false
socks_port: 7891
dns:
enable: false
ipv6: false
Clash / Mihomo 参考布局
port: 7890
socks-port: 7891
mixed-port: 7892
redir-port: 7893
tproxy-port: 7894
external-controller: 127.0.0.1:9090
dns:
listen: 127.0.0.1:1053
迁移说明
从 Mihomo 或 clash-rs 导入配置时:
- 保留原始键名以便阅读,
- 在必要时映射到
chimera_client可接受的键名, - 禁用尚未激活的入站项,
- 在启用局域网暴露前先通过真实连接测试验证。
DNS 模块
范围与目标
DNS 模块决定在策略路由之前如何解析域名。在 Clash 家族客户端中,DNS 行为会显著影响规则命中精度、延迟以及抗污染能力。
本页以 clash-rs 和 Mihomo 的行为作为参考,同时标注当前 chimera_client 的成熟度。
为什么 DNS 设计很重要
- 域名规则要求查询结果与连接流之间保持稳定映射。
- 即使应用后续按 IP 建连,fake-IP 模式仍可保留域名语义。
- 解析器选择会影响抗封锁能力、启动可靠性和隐私泄露风险。
配置要点
- 上游:UDP / DoH / DoT 端点及其顺序。
- 模式:fake-IP 与 real-IP。
- 基于 DNS 的策略路由:nameserver-policy 与 fallback 策略。
- 缓存策略:容量、TTL 边界与预取行为。
- 安全控制:fake-IP 过滤、hosts 覆盖与 ECS 处理。
- 引导:用于解析加密 DNS 端点的明文 DNS。
模式对比
| 模式 | 优势 | 取舍 | 典型用途 |
|---|---|---|---|
fake-ip | 建连后能更好保留域名规则语义 | 需要仔细维护过滤列表 | TUN / 透明代理部署 |
redir-host / real-IP 风格 | 更简单的应用兼容性 | 以 IP 建连后可能丢失域名语义 | 面向保守 DNS 目标的应用层代理 |
解析器选择流程(参考)
- 检查 hosts 覆盖和缓存。
- 按策略(基于域名 / 集合)或默认列表选择解析器。
- 查询主解析器。
- 当校验 / 延迟条件失败时,执行回退路径。
- 缓存并返回结果。
兼容性状态
| 能力 | chimera_client 当前状态 | clash-rs / Mihomo 参考 |
|---|---|---|
| 系统解析器透传 | 主要路径 | 也支持 |
| Clash 风格本地 DNS 服务器 | 开发中 | 成熟 |
| Fake-IP 工作流 | 目标状态 | 成熟 |
| Nameserver 策略 / fallback 过滤 | 目标状态 | 成熟 |
配置参考
chimera_client(当前保守配置)
dns:
enable: false
ipv6: false
与 Clash/Mihomo 对齐的目标结构
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- "*.lan"
- "*.local"
default-nameserver:
- 1.1.1.1
- 8.8.8.8
nameserver:
- https://dns.alidns.com/dns-query
- tls://1.1.1.1:853
fallback:
- 9.9.9.9
fallback-filter:
geoip: true
geoip-code: CN
实践建议
- 从 real-IP / 系统解析器行为起步以确保稳定性。
- 仅在端到端验证完域名规则工作流后再启用 fake-IP。
- 保持 fake-IP 排除项尽量精确且可审计。
- 跟踪 fallback 命中率;突然升高通常意味着上游退化或被阻断。
故障排查清单
- 确认本地 DNS 监听器可达(例如:
dig @127.0.0.1 -p 1053 example.com)。 - 确认系统解析器或 TUN 协议栈确实指向客户端监听器。
- 检查日志中是否存在上游超时、TLS 握手错误或污染响应。
- 可临时强制使用单一 UDP 解析器,以隔离 DoH/DoT 连通性问题。
对齐参考
- clash-rs:
clash-lib/src/config及 DNS 运行时模块中的 DNS 结构与运行时行为。 - Mihomo:enhanced-mode、nameserver-policy 与 fallback-filter 语义的生产参考。
Tun 模块
范围与目标
TUN 模式会捕获主机的三层流量,并将其送入代理管线,无需每个应用具备代理能力。相比 HTTP/SOCKS 监听器,TUN 最接近“系统级代理”行为,通常与策略路由和 DNS 控制联合使用。
本页遵循 clash-rs 的语义与配置键,以便后续 chimera_client 对齐更加直接。
当前项目状态
chimera_client(当前主线)在配置解析器中尚未暴露tun配置块。- 下方 TUN 章节是与 clash-rs 对齐的目标形态和运维指引,不代表
chimera_client中所有字段都已生效。 - 当前建议在
chimera_client中使用基于 SOCKS/监听器的工作流,除非你正在验证开发中的 TUN 分支。
配置结构(与 Clash-rs 对齐)
tun:
enable: true
device-id: "dev://utun1989"
route-all: true
gateway: "198.18.0.1/24"
gateway-v6: "fd00:fac::1/64"
mtu: 1500
so-mark: 3389
route-table: 2468
dns-hijack: true
# dns-hijack:
# - 1.1.1.1:53
# - 8.8.8.8:53
# routes:
# - 1.1.1.1/32
# - 2001:4860:4860::8888/128
关键字段与语义
| 键名 | 类型 | 默认值 | 注意事项 |
|---|---|---|---|
enable | bool | false | 启用 TUN 运行时。 |
device-id | string | utun1989 | 支持 dev://<name>、fd://<n> 或纯名称(按设备名处理)。 |
gateway | CIDR string | 198.18.0.1/24 | 分配给 TUN 接口的 IPv4 地址/前缀。 |
gateway-v6 | CIDR string | 未设置 | 双栈 TUN 的可选 IPv6 地址/前缀。 |
route-all | bool | false | 将主机全部流量通过 TUN 路由。 |
routes | list<CIDR> | 空 | 在 route-all: false 时使用,仅路由选定前缀。 |
mtu | u16 | 平台默认值 | 若未设置,运行时默认使用 1500(Windows 为 65535)。 |
so-mark | u32 | 未设置 | Linux fwmark,用于防环路和策略路由集成。 |
route-table | u32 | 2468 | TUN 全局路由路径使用的 Linux 策略路由表。 |
dns-hijack | bool 或 list | false | 在 TUN 路径中启用 DNS 劫持行为。 |
按选项说明的行为(以 Clash-rs 为准)
本节会展开说明 clash-rs 中 TunConfig 的每个 tun 字段,并解释其实际影响。
enable
- 控制整个 TUN 流水线的启用 / 关闭。
false表示运行时会忽略其他所有tun字段。
device-id
- 接口标识符与创建模式。
- clash-rs 解析器接受的形式:
dev://<name>:创建或使用具名 TUN 设备。- 纯
<name>:按dev://<name>处理。 fd://<n>:接管一个已经打开的文件描述符(高级嵌入 / systemd 风格)。
- 解析器接受的别名键:
device-url、device。
gateway
- 分配给 TUN 网卡的 IPv4 CIDR,例如
198.18.0.1/24。 - 它同时定义本地 TUN IP 和用于路由决策的前缀。
gateway-v6
- 分配给 TUN 网卡的可选 IPv6 CIDR。
- 若省略,则 TUN 路径中的 IPv6 处理实际上会被禁用。
route-all
true:全隧道,安装默认路径风格的路由 / 规则。false:分流,仅将routes中的前缀送入 TUN。- 如果
route-all: true,则routes列表在运行时基本失去意义。
routes
- 用于分流模式(
route-all: false)的 CIDR 列表。 - 典型用法:仅路由特定公共解析器、目标地区或服务网络。
mtu
- TUN 接口 MTU 覆盖值。
- 不设置时使用运行时 / 平台默认值;遇到分片 / PMTU 问题时再显式设置。
so-mark
- 仅 Linux 使用,附加到出站数据包上的 fwmark。
- 与
ip rule/iptables/nftables配合使用,以避免代理环路并集成自定义策略路由。
route-table
- 仅 Linux 使用的策略路由表索引,由 clash-rs 的 TUN 路由安装逻辑使用。
- 默认值为
2468;若你的系统已占用该表号,则应修改。
dns-hijack
false:不在 TUN 路径中重定向 DNS。true:将 UDP/53 查询劫持到 Clash DNS 服务。list:clash-rs 当前会把列表模式视为启用劫持行为(效果与true相同)。
Mihomo 差异说明(基于公开 Tun 文档)
与上面的 clash-rs 结构相比,以下项目在 mihomo 中未被记录为一等的 tun 键(同名或同形):
- 带
fd://<n>文件描述符形式的device-id。- Mihomo 文档暴露了
device,但没有记录基于 fd 的接管语法。
- Mihomo 文档暴露了
gateway/gateway-v6这类显式接口地址分配字段。- Mihomo 的 tun 文档更关注 route / rule 控制,没有暴露 clash-rs 风格的 gateway CIDR 键。
route-all+routes这对精确键。- Mihomo 使用
auto-route、route-address、route-exclude-address这类控制项,而不是 clash-rs 的键形态。
- Mihomo 使用
route-table的准确命名。- Mihomo 暴露的是
iproute2-table-index/iproute2-rule-index;功能上接近,但键契约并不相同。
- Mihomo 暴露的是
注意:clash-rs 中的
so-mark与 mihomo 中的routing-mark在概念上相近(都是 Linux packet mark),因此这是命名 / 兼容性差异,而不是能力缺失。
Device-ID 格式
dev://utun1989或utun1989:创建/使用具名 TUN 设备。dev://tun0:常见 Linux 写法。fd://3:使用现有文件描述符,适用于由其他组件创建 TUN 的场景。
在 macOS 上,设备名必须使用 utun 前缀。
路由行为
route-all: true
- Linux:使用策略路由规则和独立路由表(
route-table)。 - macOS/Windows:通过 TUN 安装较宽泛的默认路由项。
- 在 Linux 上,DNS 劫持集成绑定于该路径(目标端口
53的策略规则)。
route-all: false
- 仅
routes中的 CIDR 会通过 TUN 路由。 - 这更适合分阶段上线,并避免接管主机全部流量。
若两者同时配置,运行时以 route-all 为准。
DNS 交互
dns-hijack控制 TUN 流中的 DNS 劫持,但它不能替代可工作的 DNS 模块配置。- 要获得可预测的基于域名路由效果,应将 TUN 与 DNS 设置(
dns.enable、解析器列表、按需 fake-IP 策略)配套使用。 - 在实践中,Clash 风格部署通常将
dns-hijack: true与 fake-IP 模式搭配使用。
Linux 注意事项(策略路由)
- 确保已安装
iproute2(ip命令可用)。 - 以足够权限运行(CAP_NET_ADMIN 或等效 root 权限)。
- 建议设置
so-mark,并与外部策略规则保持一致,以避免代理环路。
快速检查:
ip rule
ip route show table 2468
ip -6 route show table 2468
示例配置
全隧道配置
tun:
enable: true
device-id: "dev://utun1989"
route-all: true
gateway: "198.18.0.1/24"
dns-hijack: true
分流配置
tun:
enable: true
device-id: "dev://tun0"
route-all: false
gateway: "198.18.0.1/24"
routes:
- 1.1.1.1/32
- 8.8.8.8/32
dns-hijack: false
基于 FD 的配置
tun:
enable: true
device-id: "fd://3"
route-all: true
gateway: "198.18.0.1/24"
故障排查清单
- 先确认进程权限;在许多受限环境中,TUN 创建和路由变更会静默失败。
- 确认接口已存在(
ip addr、ifconfig或平台等效命令)。 - 启动后验证路由/规则是否正确安装。
- 若 DNS 异常,请确认 DNS 监听器可达,且系统解析路径确实经过 TUN。
- 若流量出现环路或卡顿,请检查
so-mark/策略规则的一致性以及主机现有防火墙规则。
参考与对齐说明
- Clash-rs 配置结构:
clash-lib/src/config/def.rs(TunConfig、默认值、dns-hijack形态)。 - Clash-rs 配置转换:
clash-lib/src/config/internal/convert/tun.rs。 - Clash-rs TUN 运行时与设备解析:
clash-lib/src/proxy/tun/inbound.rs。 - Clash-rs 路由行为:
clash-lib/src/proxy/tun/routes/{linux,macos,windows}.rs。 - Clash-rs 示例配置:
clash-bin/tests/data/config/tun.yaml。 - Chimera_Client 当前解析器快照:
clash-lib/src/config/def.rs(主线尚无tun配置块)。 - Mihomo tun 文档(用于键形态对比):
https://wiki.metacubex.one/config/inbound/tun/。
规则类型及其作用
概览
在 chimera_client 中,规则决定由哪个出站组处理某条流量。规则按自上而下、首条命中优先的方式求值,这与 Clash-rs 和 Mihomo 的行为一致。
规则求值模型
常见的输入信号包括:
- 域名指示信息(SNI / Host),
- 解析后的目标 IP,
- 目标端口 / 源端口,
- 进程身份(平台支持时),
- GeoIP / GeoSite 数据集,
- 以及外部 rule-provider 集合。
常见动作:将流量路由到策略组,例如 DIRECT、REJECT、Proxy 或 Auto。
常见域名规则
DOMAIN
精确主机名匹配。
rules:
- DOMAIN,api.github.com,Proxy
DOMAIN-SUFFIX
后缀匹配(包含子域名)。
rules:
- DOMAIN-SUFFIX,google.com,Proxy
DOMAIN-KEYWORD
基于子串的域名匹配。需谨慎使用以避免过度匹配。
rules:
- DOMAIN-KEYWORD,openai,Proxy
IP 与网络规则
IP-CIDR
IPv4 目标前缀匹配。
rules:
- IP-CIDR,1.1.1.0/24,DIRECT
IP-CIDR6
IPv6 目标前缀匹配。
rules:
- IP-CIDR6,2606:4700::/32,DIRECT
SRC-IP-CIDR
源子网匹配(对路由器 / 网关场景很有用)。
rules:
- SRC-IP-CIDR,192.168.50.0/24,GameProxy
GEOIP
国家 / 地区 IP 数据库匹配。
rules:
- GEOIP,CN,DIRECT
GEOSITE
域名类别 / 列表匹配。
rules:
- GEOSITE,geolocation-!cn,Proxy
端口与进程规则
DST-PORT
基于目标端口的路由。
rules:
- DST-PORT,443,Proxy
SRC-PORT
基于源端口的路由。
rules:
- SRC-PORT,60000-60100,DIRECT
PROCESS-NAME
匹配可执行文件名。
rules:
- PROCESS-NAME,Telegram.exe,Proxy
PROCESS-PATH
匹配可执行文件完整路径。
rules:
- PROCESS-PATH,/Applications/Discord.app/Contents/MacOS/Discord,Proxy
Provider 与逻辑规则
RULE-SET
引用由远程或本地 provider 管理的规则集合。
rule-providers:
streaming:
type: http
behavior: domain
url: https://example.com/streaming.yaml
interval: 86400
path: ./ruleset/streaming.yaml
rules:
- RULE-SET,streaming,Proxy
MATCH
最终的全量兜底规则。
rules:
- MATCH,DIRECT
推荐排序
- 安全拦截和明确绕过(
REJECT、私有 / 本地DIRECT)。 - 精确业务规则(
DOMAIN、PROCESS-PATH、IP-CIDR)。 - Provider / 类别规则(
RULE-SET、GEOSITE)。 - 宽泛启发式规则(
DOMAIN-KEYWORD、GEOIP)。 - 最终的
MATCH兜底规则。
兼容性说明(clash-rs + Mihomo)
- 首条命中优先:一旦规则命中,后续规则将被忽略。
- 规则语法大体可移植,但实际行为仍依赖于 DNS 模式和入站类型。
- 进程级规则对平台敏感;应在每个目标操作系统上分别验证。
- GeoIP / GeoSite 的新鲜度会直接影响正确性。
最小混合示例
rules:
- DOMAIN,internal.example.com,DIRECT
- DOMAIN-SUFFIX,corp.example.com,DIRECT
- PROCESS-NAME,Telegram.exe,Proxy
- GEOSITE,category-ads-all,REJECT
- GEOIP,CN,DIRECT
- RULE-SET,streaming,Proxy
- MATCH,Auto
运维建议
- 保持规则意图清晰;避免在列表前部放置相互重叠的宽泛规则。
- 对规则 provider 及其刷新间隔进行版本控制。
- 在调试错配时开启连接决策日志。
- 应联合验证 DNS 策略和规则策略,尤其是在 fake-IP / TUN 场景下。
Chimera 图形化用户界面
设计目标
Chimera 作为高性能入口层,负责终止客户端会话、执行策略,并将流量转发到目标地址。单个入口端口可同时暴露多种代理协议。
Chimera 的核心设计优先级包括:
- 最小化握手延迟,
- 提供细粒度访问控制,
- 确保跨平台兼容性,
- 支持水平扩展,
- 并提供内建可观测性。
当前支持的平台
第一梯队
- 🖥️ Windows
- 🐧 Ubuntu
- 🍎 macOS
第二梯队
- ❄️ NixOS
当前支持的协议
请参阅 Chimera_Client 和 clash-rs。
Chimera 运行时配置生成机制说明
1. 关键结论
核心(例如 chimera_client / mihomo)在启动和热重载时使用的配置不是直接从 profiles.yaml 读取的。核心真正使用的是一个运行时文件:
clash-config.yaml(运行时配置,位于app_config_dir下)
这个文件首先由后端在内存中组装,然后写入磁盘,最后通过启动参数或Clash API 热重载传递给核心。
2. 配置输入(原材料)
运行时配置由四类输入构建而成:
-
应用设置:
chimera-config.yaml- 结构体:
IVerge - 加载入口:
backend/tauri/src/config/chimera/mod.rs→IVerge::new() - 用途:控制字段过滤、端口策略、TUN / 系统代理行为等。
- 结构体:
-
Clash Guard 覆盖模板:
clash-guard-overrides.yaml- 结构体:
IClashTemp - 加载入口:
backend/tauri/src/config/clash/mod.rs→IClashTemp::new() - 用途:强制覆盖关键字段(例如
mode、mixed-port、external-controller、secret等)。
- 结构体:
-
配置元数据:
profiles.yaml- 结构体:
Profiles - 加载入口:
backend/tauri/src/config/profile/profiles.rs→Profiles::new() - 用途:记录当前激活的配置(
current)和配置列表(items)
- 结构体:
-
具体配置内容文件:
app_config_dir/profiles/*.yaml- 加载入口:
Profiles::current_mappings() - 用途:提供代理、规则、DNS、TUN 等实际配置内容。
- 加载入口:
3. 启动初始化阶段
3.1 创建基础文件(如果缺失)
backend/tauri/src/utils/init/mod.rs → init_config() 会确保以下文件存在:
clash-guard-overrides.yaml(默认通过IClashTemp::template()生成)chimera-config.yaml(默认通过IVerge::template()生成)profiles.yaml(一个空 / 默认配置)
3.2 加载全局配置对象
backend/tauri/src/config/core.rs → Config::global() 会初始化:
Profiles::new()IVerge::new()IClashTemp::new()IRuntime::new()
IRuntime 是内存中的运行时配置容器;其 config 字段类型为 Option<Mapping>。
4. 运行时配置主组装流程
主入口:Config::generate()(backend/tauri/src/config/core.rs)
flowchart TD A["Start Config::generate"] --> B["Call enhance::enhance"] B --> C["Read YAML(s) of current profile"] C --> D["merge_profiles: merge configs"] D --> E["(Optional) whitelist-based field filtering"] E --> F["Override key fields (HANDLE_FIELDS)"] F --> G["Write into in-memory runtime config"] G --> H["Write out clash config YAML"] H --> I["Load at startup or hot-reload via PUT /configs"]
4.1 enhance::enhance() 做了什么
位置:backend/tauri/src/enhance/mod.rs
核心步骤:
-
加载 Clash Guard 配置
let clash_config = Config::clash().latest().0.clone()
-
读取当前功能开关 / 设置
- 例如从
IVerge读取enable_clash_fields
- 例如从
-
加载当前激活配置的内容
- 通过
Profiles::current_mappings() - 该方法会遍历
current,逐个读取profiles/<file>.yaml,并将其转换为Mapping
- 通过
-
(预留)执行配置链脚本
- 调用
process_chain(...) - 当前实现只是占位(no-op),会直接返回原始配置
- 调用
-
合并多个配置文件
-
调用
merge_profiles(...) -
当前策略:
- 第一份配置:完整
extend - 后续配置:仅将
proxies追加到现有的proxies
- 第一份配置:完整
-
-
白名单字段过滤(可选,由开关控制)
use_whitelist_fields_filter(...)- 当
enable_clash_fields = true时,仅保留valid + default fields中的键
-
强制覆盖 Guard 字段
- 将
IClashTemp中HANDLE_FIELDS列出的字段写回最终配置 - 确保关键控制字段由客户端集中管理
- 将
4.2 HANDLE_FIELDS 覆盖范围
定义于 backend/tauri/src/enhance/field.rs:
modeportsocks-portmixed-portallow-lanlog-level- ipv6
secretexternal-controller
这意味着,即使这些字段存在于配置文件中,其最终值也会被 clash-guard-overrides.yaml 中对应的值覆盖。
5. 写入磁盘与文件位置
入口:Config::generate_file(ConfigType::Run)(backend/tauri/src/config/core.rs)
Run模式输出:app_config_dir()/clash-config.yamlCheck模式输出:temp_dir()/clash-config-check.yaml
如果生成失败,Config::init_config() 会提供回退方案:直接将 IClashTemp 写为运行时配置。
6. 核心如何获取这份配置
6.1 启动时加载
CoreManager::run_core() → Instance::try_new()(backend/tauri/src/core/clash/core.rs):
- 调用
Config::generate_file(ConfigType::Run)获取路径 - 通过
CoreInstanceBuilder.config_path(config_path)将该路径传给核心进程
换句话说:核心在启动时会直接读取 clash-config.yaml。
6.2 运行时热重载
CoreManager::update_config() 的流程:
Config::generate().await?重新组装内存中的配置check_config().await?使用检查文件校验语法 / 可用性generate_file(Run)重写clash-config.yaml- 调用
PUT /configs,并附带{ "path": "<absolute path>" }请求体,以指示核心重载
相关代码:
backend/tauri/src/core/clash/core.rs→update_config()backend/tauri/src/core/clash/api.rs→put_configs(...)
7. 会触发重建的用户操作
7.1 切换 / 修改配置选择
前端 commands.patchProfilesConfig → 后端 patch_profiles_config(...):
- 应用草稿:
Config::profiles().draft().apply(...) - 触发
CoreManager::update_config() - 成功时:
Config::profiles().apply()+save_file() - 失败时:
discard()(回滚)
7.2 修改设置(某些字段)
前端 commands.patchVergeConfig → 后端 feat::patch_verge(...):
-
先写入一份
IVerge草稿 -
某些字段(例如
enable_tun_mode)可能触发:Config::generate()+run_core()(重启场景)- 或
update_core_config()(热更新场景)
7.3 导入第一份配置
当 import_profile(...) 成功后,如果当前还没有激活配置,它会自动构造 ProfilesBuilder.current = [new_uid],并复用 patch_profiles_config(...) 触发更新。
8. 关键细节与常见误解
-
profiles.yaml不是核心最终使用的配置- 它只存储配置元数据和
current指针
- 它只存储配置元数据和
-
配置内容文件不会原样传给核心
- 它们只有在经过合并、过滤和 guard 覆盖之后,才会变成运行时配置
-
external-controller的端口可能会在启动前被修改prepare_external_controller_port()会按策略检查端口可用性,并在必要时切换端口
-
verge_mixed_port主要用于系统代理逻辑- 它不会被直接写入运行时 YAML 的
mixed-port - 系统代理会优先使用
verge_mixed_port,否则回退到Config::clash().get_mixed_port()
- 它不会被直接写入运行时 YAML 的
-
get_runtime_yaml()返回的是内存中的IRuntime.config- 它通常与最近写入的
clash-config.yaml保持一致 - 但从根本上说,它来自内存,而不是每次都重新读取磁盘
- 它通常与最近写入的
9. 当前实现限制(以当前代码库为准)
-
链式脚本执行目前仍是占位实现
process_chain(...)目前尚未真正改写配置
-
全局链处理代码仍处于注释状态
- 目前仅存在带作用域的链式框架
-
patch_clash_configIPC 仍然是todo!()- 如果前端使用该 IPC 路径,将会失败
-
直接编辑配置文件不会自动触发热重载
save_profile_file(...)只会写入文件;它不会调用update_config()
10. 故障排查清单(实用顺序)
如果你怀疑“核心使用了错误的配置”,请按以下顺序检查:
-
确认当前激活的配置是否正确
- 检查
profiles.yaml→current
- 检查
-
确认配置源内容符合预期
- 检查
app_config_dir/profiles/*.yaml
- 检查
-
检查 guard 覆盖项
- 确认
clash-guard-overrides.yaml中的HANDLE_FIELDS是否覆盖了你预期的值
- 确认
-
检查最终运行时配置
- 检查
clash-config.yaml - 或调用
get_runtime_yaml()查看内存中的版本
- 检查
-
确认热重载是否真的发生
- 确认
patch_profiles_config/patch_verge_config/restart_sidecar是否已执行 - 检查日志,确认
PUT /configs是否成功
- 确认
-
如果你遇到端口相关问题
- 检查
external-controller是否被端口策略改写
- 检查
服务模式配置
范围与意图
在 Chimera GUI 中,服务模式会将代理核心作为后台系统服务运行,而 GUI 作为控制界面。当你需要稳定的长期运行能力、更高的网络权限,或登录前启动的工作流时,这种分离非常重要。
前台模式 vs 服务模式
| 模式 | 运行形态 | 典型用途 | 主要限制 |
|---|---|---|---|
| 前台模式 | 由 GUI 进程直接持有核心 | 开发与快速配置检查 | 当 GUI 退出或用户注销时,核心会停止 |
| 服务模式 | 系统服务持有核心;GUI 通过本地 IPC 对其进行控制 | 日常使用、TUN/透明路由、常驻在线场景 | 需要安装服务并管理权限 |
为什么启用服务模式
- 即使 GUI 关闭,也能保持流量转发继续运行。
- 在开机/登录时自动启动代理服务,并保持可预期的生命周期。
- 更可靠地支持特权路径(例如 TUN、策略路由、透明捕获)。
- 减少共享机器上不同用户会话之间的行为漂移。
Chimera GUI 中的配置流程
- 先在普通模式下准备并验证当前启用的配置。
- 打开 Chimera GUI 设置并启用服务模式。
- 在 GUI 提示时安装/注册服务。
- 选择启动策略:
- 手动:仅在需要时启动。
- 自动:系统启动时即启动(推荐用于常驻在线场景)。
- 应用设置并在 GUI 中触发服务重启。
- 确认重启后 GUI 能重新连接本地控制端点。
关键选项与推荐默认值
选项名称会因平台/构建略有差异,但含义通常一致:
| GUI 选项(常见命名) | 含义 | 建议默认值 |
|---|---|---|
Enable Service Mode | 将核心运行时归属切换为系统服务 | 长期日常使用建议开启 |
Install/Repair Service | 注册或修复服务元数据 | 首次启用后以及升级后执行 |
Start Service at Boot | 系统启动期间自动启动服务 | TUN 或网关式部署建议开启 |
Keep Running After GUI Exit | GUI 关闭后保持服务运行 | 开启 |
Require Elevation on Apply | 在应用特权更改时提示获取管理员/root 权限 | 开启 |
Auto Recover on Crash | 异常退出后重启服务进程 | 开启 |
平台说明
Windows
- 服务模式通常由 Windows 服务控制管理器(SCM)支撑。
- 若 GUI 提示失败,首次安装/修复请使用提权终端执行。
- 使用以下命令验证状态:
Get-Service *chimera*
Linux
- 服务模式通常由
systemd管理(chimera.service或类似单元名)。 - 对于会影响 TUN/路由行为的配置变更,建议显式重启服务。
- 使用以下命令验证状态:
systemctl status chimera.service
journalctl -u chimera.service -n 100 --no-pager
macOS
- 服务模式通常通过
launchd实现(系统守护进程方式)。 - 确保 GUI 与服务二进制来自同一构建渠道/版本。
上线策略
- 先从仅 SOCKS/监听器配置开始,并确认基线连通性。
- 启用服务模式,并验证 GUI 重启后的重连行为。
- 逐步启用高级选项(TUN、DNS 劫持、透明捕获)。
- 重启一次,并验证自启动、规则命中行为以及 DNS 解析稳定性。
故障排查清单
| 现象 | 可能原因 | 修复方法 |
|---|---|---|
| 服务无法启动 | 缺少管理员/root 权限 | 以提权方式重新安装/修复服务 |
| GUI 显示“disconnected from core” | 控制端点不匹配或服务崩溃循环 | 重新应用服务设置并检查服务日志 |
| TUN 功能未生效 | 服务在运行,但特权路由配置失败 | 检查系统日志与权限/能力授权 |
| 配置变更看似未生效 | GUI 已保存配置,但服务未重载 | 在 GUI 中显式触发服务重启 |
| 注销后流量中断 | 前台模式仍在运行 | 重新确认服务模式已启用并完成安装 |
运行边界
服务模式改变的是进程生命周期和权限模型,而不是代理策略语义。你的规则、DNS 策略和出站定义仍由当前生效的 Chimera 配置决定。
chimera_server 库
用途与范围
chimera_server 是共享的 Rust crate,为客户端和服务端项目提供协议原语、配置模式、密码套件以及通用工具。通过集中这些能力,生态系统避免重复逻辑,确保协议合规,并让安全修复在各二进制中保持一致。
关键模块
- 配置模型:用于 Clash 清单、Chimera 清单以及共享策略片段的强类型结构与基于 serde 的序列化。
- 加密与握手工具:AEAD 加密算法、密钥派生、证书固定辅助、TLS 指纹模板以及 QUIC 传输参数。
- 传输抽象:用于流/会话生命周期的 trait 接口、多路复用接口、缓冲区管理以及异步运行时适配器。
- 事件总线:轻量的发布/订阅机制,使上层能够接入连接生命周期事件、指标和告警。
API 接口与可扩展性
该 crate 提供稳定的 Rust API,并可选提供 C FFI 绑定以供其他语言使用。扩展点允许第三方注册自定义密码套件、添加路由注解或挂接遥测输出。版本管理遵循 semver,发生破坏性变更时提供清晰的迁移指南,确保 clash-rs 和 Chimera 能平滑跟进升级。
测试与质量
chimera_server 维护覆盖解析器、密码原语和传输行为的详尽单元测试。集成测试会启动内存中的客户端/服务端对以验证互操作性。基准测试在代表性硬件上测量握手延迟、吞吐量和内存占用,为回归检测提供基线。
协议
概览
| 协议 | 默认传输 | 认证 | 优势 | 典型限制 |
|---|---|---|---|---|
| SOCKS5 | TCP 控制 + 可选 UDP | 可选用户名/密码 | 几乎兼容任何 TCP 应用,支持 UDP ASSOCIATE 模式 | 默认明文,需要在其他层使用 TLS/混淆 |
| HTTP(S) CONNECT | 通过 HTTP/1.1 或 HTTP/2 承载 TCP | Basic 认证、Bearer 令牌、双向 TLS | 与 Web 流量融合,易于在网关部署 | 仅代理 TCP,依赖中间层保持长时隧道 |
| Trojan | 基于 TCP 的 TLS | TLS 内校验预共享密码 | 难以被指纹识别,受益于 CDN/SNI | 每个密码映射到端口/用户,需要有效的 TLS 证书 |
| Hysteria 2 | 带 TLS 1.3 的 QUIC(UDP) | 密码或类似 OIDC 的令牌 | 高吞吐、原生 UDP、支持拥塞调优 | 需要开放 UDP 端口,MTU 调优很重要 |
| TUIC | 带 TLS 1.3 的 QUIC(UDP) | 基于 UUID 或令牌的认证 | 支持 0-RTT、流复用且握手开销低 | 需要 UDP 可达;QUIC 指纹会因实现不同而变化 |
| VLESS | 基于 TCP 或 MKCP 的 TLS/XTLS | 基于 UUID 的身份 | 灵活的多路复用,可选 XTLS 自动拆分 | 缺少 TLS/XTLS 层则无加密,工具生态较为特定 |
| xHTTP 传输 | 基于 TLS/Reality 的类 HTTP 流 | 通常使用上层协议(如 VLESS)的 UUID/Token | 更好的 Web 流量伪装,且对反向代理/CDN 友好 | 请求头/路径不一致会导致握手失败;相较裸 TCP 有额外开销 |
| Reality(TLS 伪装) | 类 TLS 1.3 握手 | 公钥 + short ID(外加上游认证) | 无证书 TLS 拟态,对被动探测更具抵抗力 | 依赖客户端指纹匹配,生态上与 Xray 工具链绑定 |
详细拆解已移至独立文件;每个文件都遵循相同结构(亮点、流程、配置片段、优势与限制),便于对比。
深入解析
- SOCKS5 – 通用的 TCP/UDP 代理,支持灵活的方法协商。
- HTTP CONNECT Proxy – 基于标准 Web 端口的 HTTPS 友好隧道。
- Trojan – 以 TLS 伪装的密码代理,适合 CDN 前置。
- Hysteria 2 – 基于 QUIC 的传输,针对高丢包或高延迟链路优化。
- TUIC —— 基于 QUIC 的代理协议,支持多路复用并针对低延迟进行激进调优。
- VLESS – 基于 UUID 认证的协议,传输层可配置 TLS、XTLS 或 Reality。
- xHTTP 传输——面向 Xray 生态的类 HTTP 传输形态,常与 VLESS 搭配使用。
- Reality —— Xray 传输中使用的 TLS 伪装层,无需证书。
SOCKS5
官方 RFC
SOCKS 第 5 版协议主要由 RFC 1928 规定。
关键 RFC:
- RFC 1928 — SOCKS Protocol Version 5(核心协议、寻址、UDP ASSOCIATE、认证协商)
- RFC 1929 — Username/Password Authentication for SOCKS V5(可选的用户名/密码认证方法)
- RFC 1961 — GSS-API Authentication Method for SOCKS V5(可选认证)
- RFC 3089 — SOCKS-based IPv6/IPv4 Gateway(IPv6 场景下的互操作性)
亮点
- 四层代理,可转发任意 TCP 流,并通过 ASSOCIATE 命令支持 UDP。
- 方法协商允许服务器声明
NO AUTH、USERPASS或自定义认证。 - 被浏览器、curl、SSH 和 VPN 客户端广泛支持。
流程
- 客户端向代理打开一个 TCP 套接字。
- 客户端发送支持的认证方法列表;服务器返回选定的方法。
- 可选的用户名/密码交换。
- 客户端携带目标信息发送
CONNECT、BIND或UDP ASSOCIATE。 - 服务器返回成功/失败码并开始转发流量。
配置片段
优势
- 无需额外插件即可配合传统工具使用。
- UDP ASSOCIATE 使 DNS-over-UDP 成为可能。
- 最小的封装开销保持低延迟。
限制
- 没有内置加密;必须依赖 TLS-over-SOCKS 或上游混淆。
- UDP ASSOCIATE 要求客户端持续监听本地端口,部分防火墙会阻断。
- 认证通常是静态的,除非再加一层管理机制。
参考资料
- https://www.rfc-editor.org/rfc/rfc1928
- https://www.rfc-editor.org/rfc/rfc1929
- https://www.rfc-editor.org/rfc/rfc1961
- https://www.rfc-editor.org/rfc/rfc3089
附录
RFC 1928(全文)
#### RFC 1929 (Full Text)
```text
#### RFC 1961 (Full Text)
```text
#### RFC 3089 (Full Text)
```text
HTTP
亮点
- 表现为普通的 HTTP(S) 服务器,通过
CONNECT方法将单个请求升级为隧道。 - 易于使用 Nginx、Apache 或云负载均衡进行前置。
- 双方支持时可使用 HTTP/2 多路复用。
流程
- 客户端与代理端点建立 TCP(或 TLS)连接。
- 客户端可选进行 HTTP 认证(Basic、Digest、Bearer 或双向 TLS)。
- 客户端发送
CONNECT target.example.com:443 HTTP/1.1(或 HTTP/2 的:method CONNECT)。 - 代理校验策略后返回
200 Connection Established。 - 后续字节透明转发,直到任一侧关闭隧道。
配置片段
优势
- 与标准 HTTPS 流量混在一起,难以与普通网页浏览区分。
- 适合在只允许 80/443 端口的企业防火墙后使用。
- HTTP/2 变体可在单个 TCP 会话上复用多条隧道,降低握手成本。
限制
- 仅支持 TCP;不经额外封装无法转发 UDP 流。
- 代理需为每条隧道维护状态,在大量短连接下会影响扩展性。
- 若未清理,额外的 HTTP 头可能泄露元数据。
Trojan
亮点
- 以真实的 TLS 握手开始;后续所有字节都是 TLS 应用数据。
- 认证方式是对预共享密码进行 SHA-224 哈希并做十六进制编码。
- 请求帧复用 SOCKS5 风格的地址字段,用于 CONNECT 和 UDP ASSOCIATE。
- 无效或未知流量可以转发到回落端点,使其看起来像正常的 HTTPS。
流程
- 客户端与服务器完成标准 TLS 握手(SNI/ALPN 按配置)。
- 客户端发送
hex(SHA224(password))+ CRLF + Trojan Request + CRLF(+ 可选负载)。 - 服务器校验密码与请求,然后连接到目标。
- 对 TCP,数据双向转发;对 UDP,数据包会被封装并通过 TLS 流隧道传输。
报文格式
- 精确的帧格式与字段定义见 报文格式。
- 首个 TLS 记录可在请求之后携带负载,以减少数据包数量。
流量处理
- 回落行为与反探测说明见 流量处理。
优势
- 使用标准 TLS 栈和证书,继承成熟的 TLS 安全性与 ALPN 支持。
- 当由合法的 HTTPS 端点提供服务时,难以进行指纹识别。
- 握手完成后,协议开销很小。
限制
- 共享密码模式意味着撤销粒度较粗,除非使用按用户分配的密码。
- 需要有效的 TLS 证书并进行运维续期。
- 必须配置回落行为,使探测与真实 HTTPS 无法区分。
参考资料
- https://trojan-gfw.github.io/trojan/protocol
Trojan 报文格式
TLS 握手
- 客户端首先执行一次标准的 TLS 握手。
- 如果握手失败,服务器会像普通 HTTPS 服务器一样关闭连接。
- 一些实现还会对纯 HTTP 探测返回类似 nginx 的响应。
初始请求
TLS 建立后,首个应用数据包为:
+-----------------------+---------+----------------+---------+----------+
| hex(SHA224(password)) | CRLF | Trojan Request | CRLF | Payload |
+-----------------------+---------+----------------+---------+----------+
| 56 | 0x0D0A | Variable | 0x0D0A | Variable |
+-----------------------+---------+----------------+---------+----------+
Trojan Request
Trojan Request 使用类 SOCKS5 格式:
+-----+------+----------+----------+
| CMD | ATYP | DST.ADDR | DST.PORT |
+-----+------+----------+----------+
| 1 | 1 | Variable | 2 |
+-----+------+----------+----------+
- CMD 值:0x01 CONNECT,0x03 UDP ASSOCIATE。
- ATYP 值:0x01 IPv4,0x03 DOMAINNAME,0x04 IPv6。
- DST.ADDR 为目标地址,DST.PORT 使用网络字节序。
- SOCKS5 字段细节:https://tools.ietf.org/html/rfc1928
UDP ASSOCIATE 帧格式
当 CMD 为 UDP ASSOCIATE 时,每个 UDP 数据报在 TLS 流中的帧格式为:
+------+----------+----------+--------+---------+----------+
| ATYP | DST.ADDR | DST.PORT | Length | CRLF | Payload |
+------+----------+----------+--------+---------+----------+
| 1 | Variable | 2 | 2 | 0x0D0A | Variable |
+------+----------+----------+--------+---------+----------+
- Length 为负载大小,使用网络字节序。
- Payload 为原始 UDP 数据报。
注意事项
- 首个 TLS 记录可在请求后立即携带负载,从而减少数据包数量与长度模式。
- 客户端通常会提供本地 SOCKS5 代理,并将本地 SOCKS5 请求转换为 Trojan 请求。
Trojan 流量处理
其他协议(回落)
- Trojan 像普通 HTTPS 服务一样监听 TLS 套接字。
- TLS 完成后,服务器检查第一个应用数据包。
- 如果该数据包不是有效的 Trojan 请求(结构或密码错误),服务器会将其视为“其他协议”,并把解密后的 TLS 流转发到预设端点(默认
127.0.0.1:80)。 - 预设端点随后控制响应,使其行为与真实 HTTPS 站点无异。
主动检测
- 结构或密码不正确的探测会被交给回落端点。
- 因此,主动扫描器看到的是普通 HTTPS 或 HTTP 行为,而非定制的代理标识。
被动检测
- 使用有效证书时,流量受 TLS 保护,看起来像普通 HTTPS。
- 对于 HTTP 目的地,TLS 握手后只有一个 RTT;非 HTTP 流量常表现为 HTTPS 保活或WebSocket。
- 这种相似性有助于绕过针对明显代理特征的 ISP QoS。
参考资料
- https://github.com/trojan-gfw/trojan/issues/14
参考资料
- https://v2.hysteria.network/zh/docs/developers/Protocol/
Hysteria 2 协议规范
Hysteria 是基于 QUIC 的 TCP 与 UDP 代理,旨在提供速度、安全性与抗审查能力。本文档描述 Hysteria 自 2.0.0 版本起使用的协议,内部有时称为“v4“协议。下文将其称为“该协议“或“Hysteria 协议“。
规范性语言
本文档中的关键词“MUST“、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY” 和 “OPTIONAL“的含义应按 RFC 2119 解释:https://tools.ietf.org/html/rfc2119
底层协议与报文格式
Hysteria 协议 MUST 构建在标准 QUIC 传输协议(RFC 9000)之上,并使用不可靠数据报扩展(RFC 9221)。
所有多字节数字均使用大端字节序。
所有变长整数(“varints”)按 QUIC(RFC 9000)定义进行编码/解码。
认证与 HTTP/3 伪装
Hysteria 协议的一个关键特性是:对于没有正确认证凭据的第三方(无论是中间人还是主动探测者),Hysteria 代理服务器的行为就像标准的 HTTP/3 Web 服务器。此外,客户端与服务器之间的加密流量看起来与正常 HTTP/3 流量无法区分。
因此,Hysteria 服务器 MUST 实现一个 HTTP/3 服务器(RFC 9114),并像标准 Web 服务器一样处理 HTTP 请求。为防止主动探测者发现 Hysteria 服务器的常见响应模式,实现方 SHOULD 建议用户要么托管真实内容,要么将其设置为其他站点的反向代理。
真正的 Hysteria 客户端在连接后 MUST 向服务器发送以下 HTTP/3 请求:
:method: POST
:path: /auth
:host: hysteria
Hysteria-Auth: [string]
Hysteria-CC-RX: [uint]
Hysteria-Padding: [string]
Hysteria-Auth:认证凭据。
Hysteria-CC-RX:客户端最大接收速率(字节/秒)。值为 0 表示未知。
Hysteria-Padding:可变长度的随机填充字符串。
Hysteria 服务器 MUST 识别该特殊请求,并且不会尝试提供内容或转发到上游站点,而是 MUST 使用所提供的信息对客户端进行认证。若认证成功,服务器 MUST 发送以下响应(HTTP 状态码 233):
:status: 233 HyOK
Hysteria-UDP: [true/false]
Hysteria-CC-RX: [uint/"auto"]
Hysteria-Padding: [string]
Hysteria-UDP:服务器是否支持 UDP 中继。
Hysteria-CC-RX:服务器最大接收速率(字节/秒)。值为 0 表示无限制;“auto” 表示服务器拒绝提供该值,并要求客户端使用拥塞控制自行确定速率。
Hysteria-Padding:可变长度的随机填充字符串。
关于如何使用 Hysteria-CC-RX 的取值,详见“拥塞控制”章节。
Hysteria-Padding 为可选项,仅用于混淆请求/响应模式,双方 SHOULD 忽略它。
如果认证失败,服务器 MUST 要么表现得像不理解该请求的标准 Web 服务器,要么在其作为反向代理时,将请求转发到上游站点并将响应返回给客户端。
客户端 MUST 检查状态码以判断认证是否成功。若状态码不是 233,客户端 MUST 认为认证失败并断开与服务器的连接。
客户端通过认证之后(且仅在之后),服务器 MUST 将该 QUIC 连接视为 Hysteria 代理连接,并 MUST 按下一节所述开始处理来自客户端的代理请求。
代理请求
TCP
对于每个 TCP 连接,客户端 MUST 创建一个新的 QUIC 双向流,并发送以下 TCPRequest 消息:
[varint] 0x401 (TCPRequest ID)
[varint] Address length
[bytes] Address string (host:port)
[varint] Padding length
[bytes] Random padding
服务器 MUST 以 TCPResponse 消息回应:
[uint8] Status (0x00 = OK, 0x01 = Error)
[varint] Message length
[bytes] Message string
[varint] Padding length
[bytes] Random padding
如果状态为 OK,服务器 MUST 随后在客户端与指定的 TCP 地址之间转发数据,直到任一方关闭连接。如果状态为 Error,服务器 MUST 关闭该 QUIC 流。
UDP
UDP 数据包 MUST 按以下 UDPMessage 格式封装,并通过 QUIC 的不可靠数据报发送(客户端到服务器和服务器到客户端均如此):
[uint32] Session ID
[uint16] Packet ID
[uint8] Fragment ID
[uint8] Fragment count
[varint] Address length
[bytes] Address string (host:port)
[bytes] Payload
客户端 MUST 为每个 UDP 会话使用唯一的 Session ID。服务器 SHOULD 为每个 Session ID 分配唯一的 UDP 端口,除非它有其他机制区分来自不同会话的数据包(例如对称 NAT、不同的出站 IP 地址等)。
该协议未提供显式关闭 UDP 会话的方法。客户端可以无限期地保留并复用 Session ID,但服务器 SHOULD 在一段时间不活动或基于其他条件后释放并重新分配与该 Session ID 关联的端口。如果客户端向服务器已不再识别的 Session ID 发送 UDP 数据包,服务器 MUST 将其视为新会话并分配新的端口。
如果服务器不支持 UDP 中继,它 SHOULD 静默丢弃从客户端接收到的所有 UDP 消息。
分片
由于 QUIC 不可靠数据报通道的限制,任何超过 QUIC 最大数据报大小的 UDP 数据包 MUST 要么分片,要么被丢弃。
对于分片的数据包,每个分片 MUST 携带相同的唯一 Packet ID。Fragment ID 从 0 开始,表示在总 Fragment Count 中的索引。服务器与客户端 MUST 等待该分片数据包的所有分片到齐后再处理;如果丢失一个或多个分片,整个数据包 MUST 被丢弃。
对于未分片的数据包,Fragment Count MUST 设为 1。在这种情况下,Packet ID 和 Fragment ID 的值无关紧要。
拥塞控制
Hysteria 的一项独特能力是允许在客户端设置 tx/rx(上传/下载)速率。认证过程中,客户端通过 Hysteria-CC-RX 头向服务器发送其 rx 速率。服务器可据此确定向客户端的发送速率,并通过同一头返回其 rx 速率,反之亦然。
有三种特殊情况:
- 如果客户端发送 0,表示它不知道自身的 rx 速率。服务器 MUST 使用拥塞控制算法(如 BBR、Cubic)来调整其发送速率。
- 如果服务器返回 0,表示没有带宽限制。客户端 MAY 以任意速率发送。
- 如果服务器返回 “auto”,表示它选择不指定速率。客户端 MUST 使用拥塞控制算法来调整其发送速率。
“Salamander” 混淆
Hysteria 协议支持一个可选的混淆层,代号为 “Salamander”。
“Salamander” 将所有 QUIC 数据包封装为以下格式:
[8 bytes] Salt
[bytes] Payload
对于每个 QUIC 数据包,混淆器 MUST 计算将随机生成的 8 字节盐值追加到用户提供的预共享密钥后的 BLAKE2b-256 哈希。
hash = BLAKE2b-256(key + salt)
随后使用该哈希按以下算法对负载进行混淆:
for i in range(0, len(payload)):
payload[i] ^= hash[i % 32]
去混淆器 MUST 使用相同的算法计算带盐哈希并还原负载。任何无效的数据包 MUST 被丢弃。
TUIC
亮点
- 基于 QUIC 的代理协议,使用 TLS 1.3 进行加密与流复用。
- 支持 0-RTT 会话恢复,并通过 QUIC 数据报中继 UDP。
- 配合现代拥塞控制,面向低延迟场景进行激进调优。
流程
- 客户端向服务器建立 QUIC 连接并完成 TLS 1.3 握手。
- 客户端使用服务器配置的 UUID/令牌完成认证。
- 客户端为 TCP 请求打开双向 QUIC 流,并使用数据报进行 UDP 中继。
- 服务器完成认证校验后,将流量转发到上游目的地。
配置片段
优势
- 通过 0-RTT 与流复用降低握手开销。
- 原生处理 UDP,无需额外封装层。
- 在高丢包或高时延移动网络下通常表现更好。
限制
- 需要 UDP 可达且网络路径对 QUIC 友好。
- QUIC 指纹会因实现而异,可能被限速或封锁。
- 为获得最佳效果,通常需要调优 MTU 与发包节奏。
VLESS
亮点
- 来自 Project V 的轻量无状态协议,使用 UUID 作为客户端标识。
- 通常与 TLS、XTLS 或 Reality 传输层搭配,用于加密与伪装。
- 在 Xray-core 生态内支持多路复用、回退路由和高级路由规则。
流程
- 客户端连接到服务器传输层(TLS、XTLS、Reality、gRPC 或 MKCP)。
- 客户端发送包含 UUID、命令(TCP/UDP)和目标地址的 VLESS 头。
- 服务器校验 UUID 后,建立到目的地的流或数据报隧道。
- 可选功能如 Flow Control Transport(FCT)或 XTLS 拆分可加速流量。
配置片段
优势
- 基于 UUID 的认证易于扩展到大量用户,并可与自动化签发系统集成。
- 兼容多种传输层,在 TCP、gRPC、WS 或 QUIC 之间提供灵活选择。
- XTLS/Reality 选项降低 TLS 开销并模拟合法 HTTPS 指纹。
限制
- 依赖 Xray-core 生态;主流操作系统工具并不原生支持。
- 流控参数配置错误会破坏与旧客户端的兼容性。
- 安全性高度依赖所选传输层;不带 TLS 的裸 VLESS 没有加密。
xHTTP 传输
概览
xHTTP 是 Xray 的一种传输方式,它通过常规 HTTP 请求/响应模式承载代理流量,使其更接近普通 Web 应用流量。它常与 VLESS + TLS/Reality 搭配使用,以增强伪装并穿越受限网络环境。
适用场景
- 你需要让流量融入常见 HTTPS API 访问模式。
- 你的网络环境对长连接 WebSocket 或 gRPC 特征较敏感。
- 你希望将 VLESS 的身份认证与 HTTP 风格的上下行行为结合。
核心配置字段
| 字段 | 侧别 | 含义 |
|---|---|---|
network: xhttp | client/server | 启用 xHTTP 传输。 |
path | client/server | 传输使用的 HTTP 请求路径,客户端与服务端必须一致。 |
host | client | 可选的 Host 请求头覆盖(用于前置/反向代理场景)。 |
mode | client/server | 传输模式,通常为 auto(默认)或平台特定变体。 |
extra.headers | client | 额外 HTTP 请求头,用于模拟应用/API 流量。 |
xmux | client/server | 多路复用调优项,如并发限制与连接复用。 |
tls / reality | client/server | 生产环境强烈建议启用加密/伪装层。 |
最小示例(客户端,Clash-Meta 风格)
proxies:
- name: vless-xhttp
type: vless
server: edge.example.com
port: 443
uuid: 11111111-2222-3333-4444-555555555555
tls: true
servername: cdn.example.com
network: xhttp
xhttp-opts:
path: /api/v1/sync
host:
- cdn.example.com
mode: auto
headers:
User-Agent:
- okhttp/4.12.0
最小示例(服务端,Xray 风格)
{
"inbounds": [
{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{ "id": "11111111-2222-3333-4444-555555555555" }
],
"decryption": "none"
},
"streamSettings": {
"network": "xhttp",
"security": "tls",
"tlsSettings": {
"serverName": "cdn.example.com",
"certificates": [
{
"certificateFile": "/etc/ssl/fullchain.pem",
"keyFile": "/etc/ssl/privkey.pem"
}
]
},
"xhttpSettings": {
"path": "/api/v1/sync",
"mode": "auto"
}
}
}
]
}
部署注意事项
- 保持客户端与服务端
path和 mode 完全一致,否则握手会失败。 - 优先使用真实且稳定的请求头;频繁变更指纹会降低稳定性。
- 若部署在 Nginx/Caddy/CDN 后方,请确保请求缓冲与超时限制适配长连接代理流。
- 先使用保守的
xmux参数,待观察延迟与上游限制后再调高并发。
故障排查清单
- 连接后立即出现
EOF:请检查 UUID、TLS server name 以及path是否一致。 - 频繁重连:请检查反向代理空闲超时和 HTTP/2 上游设置。
- 握手正常但吞吐差:请减少请求头冗余、调优
xmux,并确认 CDN 区域亲和性。
Reality
亮点
- 来自 Xray 生态的 TLS 伪装层,可在不签发证书的情况下模拟 TLS 1.3 握手。
- 使用服务端公钥与 short ID,将握手绑定到看似真实的 TLS 指纹。
- 通常与 VLESS 或 Trojan 搭配,在传输层之上提供认证与路由能力。
流程
- 客户端选择伪装域名,并配置服务端公钥 + short ID。
- 客户端发起类 TLS 1.3 握手(uTLS 指纹),并将 SNI 设为伪装域名。
- 服务器校验 short ID 与密钥交换后接受该会话。
- 成功后,连接升级为选定的代理协议(例如 VLESS)。
配置片段
优势
- 在保持类 TLS 握手行为的同时,避免证书签发与轮换。
- 当 TLS 客户端指纹贴近常见浏览器时,更难被被动探测识别。
- 可与 XTLS 流控集成以降低开销。
限制
- 需要兼容的客户端指纹;不匹配会导致连接失败。
- 主要局限在 Xray 工具生态内。
- 效果取决于伪装域名选择与配置正确性。