前言

代理应用的版图已变得拥挤且碎片化,因此——出于个人兴趣——我决定将我使用的那些整合成一个单一的百科全书式的应用。

  • Chimera_Client 借鉴了开源 clash-rs 项目,长期目标是对齐 Mihomo 的功能集。
  • Chimera 参考了 clash-nyanpasu 项目,但关键区别在于我的首要目标是对 chimera_client 引擎本身提供一流支持,它在很大程度上可视为 clash-rs 的核心。
  • Chimera_Server 项目可视为 xray-core 的 Rust 实现,并以保持与原版 xray-core 兼容为最终目标。此外,其实现基于开源项目 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:广泛生态兼容性和高级运维特性的事实生产参考。

在本章中,每个模块页面都会明确标注:

  1. chimera_client 当前已可用的内容,
  2. 什么是与 Clash/Mihomo 兼容的目标行为,
  3. 以及当前应采取哪些迁移注意事项。

架构概览

在内部,客户端被组织为四层:

  1. 配置层
    • 将 Clash 风格 YAML 解析为类型化的 Rust 结构。
    • 处理默认值、校验与热重载边界。
  2. 入站 / 控制层
    • 负责本地监听器(SOCKS/HTTP/mixed/TUN,随对齐进展逐步完善)。
    • 暴露用于状态查询、切换与诊断的管理 API。
  3. 策略与 DNS 层
    • 以首条命中语义执行规则链。
    • 提供 DNS 策略原语(当前为系统解析器,目标是 Clash 风格 DNS)。
  4. 出站传输层
    • 执行协议握手与流转发。
    • 封装协议特定参数,同时复用通用 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/监听器)时,应优先保证确定性行为和可调试性,而不是依赖隐式的“魔法”默认值。

参考仓库

各种端口

概览

端口定义了本地应用、控制面板和 DNS 解析器如何接入 chimera_client。本页会交叉对照 Clash-rs 与 Mihomo 的语义,并明确说明 chimera_client 的当前状态。

键名映射

Clash / Mihomo 键名chimera_client 键名用途
port / http-portportHTTP CONNECT / 明文代理监听器
socks-portsocks_portSOCKS5 监听器
mixed-portmixed_port共享的 HTTP + SOCKS 监听器
redir-portredir_portLinux TCP 透明 REDIRECT
tproxy-porttproxy_portLinux TPROXY(TCP/UDP)
external-controllerexternal_controllerREST 控制器端点
dns.listendns.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 导入配置时:

  1. 保留原始键名以便阅读,
  2. 在必要时映射到 chimera_client 可接受的键名,
  3. 禁用尚未激活的入站项,
  4. 在启用局域网暴露前先通过真实连接测试验证。

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 目标的应用层代理

解析器选择流程(参考)

  1. 检查 hosts 覆盖和缓存。
  2. 按策略(基于域名 / 集合)或默认列表选择解析器。
  3. 查询主解析器。
  4. 当校验 / 延迟条件失败时,执行回退路径。
  5. 缓存并返回结果。

兼容性状态

能力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

关键字段与语义

键名类型默认值注意事项
enableboolfalse启用 TUN 运行时。
device-idstringutun1989支持 dev://<name>fd://<n> 或纯名称(按设备名处理)。
gatewayCIDR string198.18.0.1/24分配给 TUN 接口的 IPv4 地址/前缀。
gateway-v6CIDR string未设置双栈 TUN 的可选 IPv6 地址/前缀。
route-allboolfalse将主机全部流量通过 TUN 路由。
routeslist<CIDR>route-all: false 时使用,仅路由选定前缀。
mtuu16平台默认值若未设置,运行时默认使用 1500(Windows 为 65535)。
so-marku32未设置Linux fwmark,用于防环路和策略路由集成。
route-tableu322468TUN 全局路由路径使用的 Linux 策略路由表。
dns-hijackboollistfalse在 TUN 路径中启用 DNS 劫持行为。

按选项说明的行为(以 Clash-rs 为准)

本节会展开说明 clash-rsTunConfig 的每个 tun 字段,并解释其实际影响。

enable

  • 控制整个 TUN 流水线的启用 / 关闭。
  • false 表示运行时会忽略其他所有 tun 字段。

device-id

  • 接口标识符与创建模式。
  • clash-rs 解析器接受的形式:
    • dev://<name>:创建或使用具名 TUN 设备。
    • <name>:按 dev://<name> 处理。
    • fd://<n>:接管一个已经打开的文件描述符(高级嵌入 / systemd 风格)。
  • 解析器接受的别名键:device-urldevice

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 键(同名或同形):

  1. fd://<n> 文件描述符形式的 device-id
    • Mihomo 文档暴露了 device,但没有记录基于 fd 的接管语法。
  2. gateway / gateway-v6 这类显式接口地址分配字段。
    • Mihomo 的 tun 文档更关注 route / rule 控制,没有暴露 clash-rs 风格的 gateway CIDR 键。
  3. route-all + routes 这对精确键。
    • Mihomo 使用 auto-routeroute-addressroute-exclude-address 这类控制项,而不是 clash-rs 的键形态。
  4. route-table 的准确命名。
    • Mihomo 暴露的是 iproute2-table-index / iproute2-rule-index;功能上接近,但键契约并不相同。

注意:clash-rs 中的 so-mark 与 mihomo 中的 routing-mark 在概念上相近(都是 Linux packet mark),因此这是命名 / 兼容性差异,而不是能力缺失。

Device-ID 格式

  • dev://utun1989utun1989:创建/使用具名 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 注意事项(策略路由)

  • 确保已安装 iproute2ip 命令可用)。
  • 以足够权限运行(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 addrifconfig 或平台等效命令)。
  • 启动后验证路由/规则是否正确安装。
  • 若 DNS 异常,请确认 DNS 监听器可达,且系统解析路径确实经过 TUN。
  • 若流量出现环路或卡顿,请检查 so-mark/策略规则的一致性以及主机现有防火墙规则。

参考与对齐说明

  • Clash-rs 配置结构:clash-lib/src/config/def.rsTunConfig、默认值、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 集合。

常见动作:将流量路由到策略组,例如 DIRECTREJECTProxyAuto

常见域名规则

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

推荐排序

  1. 安全拦截和明确绕过(REJECT、私有 / 本地 DIRECT)。
  2. 精确业务规则(DOMAINPROCESS-PATHIP-CIDR)。
  3. Provider / 类别规则(RULE-SETGEOSITE)。
  4. 宽泛启发式规则(DOMAIN-KEYWORDGEOIP)。
  5. 最终的 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 Windows
  • 🐧 Ubuntu
  • 🍎 macOS

第二梯队

  • ❄️ NixOS

当前支持的协议

请参阅 Chimera_Clientclash-rs


Chimera 运行时配置生成机制说明

1. 关键结论

核心(例如 chimera_client / mihomo)在启动和热重载时使用的配置不是直接从 profiles.yaml 读取的。核心真正使用的是一个运行时文件:

  • clash-config.yaml(运行时配置,位于 app_config_dir 下)

这个文件首先由后端在内存中组装,然后写入磁盘,最后通过启动参数Clash API 热重载传递给核心。

2. 配置输入(原材料)

运行时配置由四类输入构建而成:

  1. 应用设置:chimera-config.yaml

    • 结构体:IVerge
    • 加载入口:backend/tauri/src/config/chimera/mod.rsIVerge::new()
    • 用途:控制字段过滤、端口策略、TUN / 系统代理行为等。
  2. Clash Guard 覆盖模板:clash-guard-overrides.yaml

    • 结构体:IClashTemp
    • 加载入口:backend/tauri/src/config/clash/mod.rsIClashTemp::new()
    • 用途:强制覆盖关键字段(例如 modemixed-portexternal-controllersecret 等)。
  3. 配置元数据:profiles.yaml

    • 结构体:Profiles
    • 加载入口:backend/tauri/src/config/profile/profiles.rsProfiles::new()
    • 用途:记录当前激活的配置(current)和配置列表(items
  4. 具体配置内容文件:app_config_dir/profiles/*.yaml

    • 加载入口:Profiles::current_mappings()
    • 用途:提供代理、规则、DNS、TUN 等实际配置内容。

3. 启动初始化阶段

3.1 创建基础文件(如果缺失)

backend/tauri/src/utils/init/mod.rsinit_config() 会确保以下文件存在:

  • clash-guard-overrides.yaml(默认通过 IClashTemp::template() 生成)
  • chimera-config.yaml(默认通过 IVerge::template() 生成)
  • profiles.yaml(一个空 / 默认配置)

3.2 加载全局配置对象

backend/tauri/src/config/core.rsConfig::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

核心步骤:

  1. 加载 Clash Guard 配置

    • let clash_config = Config::clash().latest().0.clone()
  2. 读取当前功能开关 / 设置

    • 例如从 IVerge 读取 enable_clash_fields
  3. 加载当前激活配置的内容

    • 通过 Profiles::current_mappings()
    • 该方法会遍历 current,逐个读取 profiles/<file>.yaml,并将其转换为 Mapping
  4. (预留)执行配置链脚本

    • 调用 process_chain(...)
    • 当前实现只是占位(no-op),会直接返回原始配置
  5. 合并多个配置文件

    • 调用 merge_profiles(...)

    • 当前策略:

      • 第一份配置:完整 extend
      • 后续配置:仅将 proxies 追加到现有的 proxies
  6. 白名单字段过滤(可选,由开关控制)

    • use_whitelist_fields_filter(...)
    • enable_clash_fields = true 时,仅保留 valid + default fields 中的键
  7. 强制覆盖 Guard 字段

    • IClashTempHANDLE_FIELDS 列出的字段写回最终配置
    • 确保关键控制字段由客户端集中管理

4.2 HANDLE_FIELDS 覆盖范围

定义于 backend/tauri/src/enhance/field.rs

  • mode
  • port
  • socks-port
  • mixed-port
  • allow-lan
  • log-level
  • ipv6
  • secret
  • external-controller

这意味着,即使这些字段存在于配置文件中,其最终值也会被 clash-guard-overrides.yaml 中对应的值覆盖。

5. 写入磁盘与文件位置

入口:Config::generate_file(ConfigType::Run)backend/tauri/src/config/core.rs

  • Run 模式输出:app_config_dir()/clash-config.yaml
  • Check 模式输出: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):

  1. 调用 Config::generate_file(ConfigType::Run) 获取路径
  2. 通过 CoreInstanceBuilder.config_path(config_path) 将该路径传给核心进程

换句话说:核心在启动时会直接读取 clash-config.yaml

6.2 运行时热重载

CoreManager::update_config() 的流程:

  1. Config::generate().await? 重新组装内存中的配置
  2. check_config().await? 使用检查文件校验语法 / 可用性
  3. generate_file(Run) 重写 clash-config.yaml
  4. 调用 PUT /configs,并附带 { "path": "<absolute path>" } 请求体,以指示核心重载

相关代码:

  • backend/tauri/src/core/clash/core.rsupdate_config()
  • backend/tauri/src/core/clash/api.rsput_configs(...)

7. 会触发重建的用户操作

7.1 切换 / 修改配置选择

前端 commands.patchProfilesConfig → 后端 patch_profiles_config(...)

  1. 应用草稿:Config::profiles().draft().apply(...)
  2. 触发 CoreManager::update_config()
  3. 成功时:Config::profiles().apply() + save_file()
  4. 失败时: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. 关键细节与常见误解

  1. profiles.yaml 不是核心最终使用的配置

    • 它只存储配置元数据和 current 指针
  2. 配置内容文件不会原样传给核心

    • 它们只有在经过合并、过滤和 guard 覆盖之后,才会变成运行时配置
  3. external-controller 的端口可能会在启动前被修改

    • prepare_external_controller_port() 会按策略检查端口可用性,并在必要时切换端口
  4. verge_mixed_port 主要用于系统代理逻辑

    • 不会被直接写入运行时 YAML 的 mixed-port
    • 系统代理会优先使用 verge_mixed_port,否则回退到 Config::clash().get_mixed_port()
  5. get_runtime_yaml() 返回的是内存中的 IRuntime.config

    • 它通常与最近写入的 clash-config.yaml 保持一致
    • 但从根本上说,它来自内存,而不是每次都重新读取磁盘

9. 当前实现限制(以当前代码库为准)

  1. 链式脚本执行目前仍是占位实现

    • process_chain(...) 目前尚未真正改写配置
  2. 全局链处理代码仍处于注释状态

    • 目前仅存在带作用域的链式框架
  3. patch_clash_config IPC 仍然是 todo!()

    • 如果前端使用该 IPC 路径,将会失败
  4. 直接编辑配置文件不会自动触发热重载

    • save_profile_file(...) 只会写入文件;它不会调用 update_config()

10. 故障排查清单(实用顺序)

如果你怀疑“核心使用了错误的配置”,请按以下顺序检查:

  1. 确认当前激活的配置是否正确

    • 检查 profiles.yamlcurrent
  2. 确认配置源内容符合预期

    • 检查 app_config_dir/profiles/*.yaml
  3. 检查 guard 覆盖项

    • 确认 clash-guard-overrides.yaml 中的 HANDLE_FIELDS 是否覆盖了你预期的值
  4. 检查最终运行时配置

    • 检查 clash-config.yaml
    • 或调用 get_runtime_yaml() 查看内存中的版本
  5. 确认热重载是否真的发生

    • 确认 patch_profiles_config / patch_verge_config / restart_sidecar 是否已执行
    • 检查日志,确认 PUT /configs 是否成功
  6. 如果你遇到端口相关问题

    • 检查 external-controller 是否被端口策略改写

服务模式配置

范围与意图

在 Chimera GUI 中,服务模式会将代理核心作为后台系统服务运行,而 GUI 作为控制界面。当你需要稳定的长期运行能力、更高的网络权限,或登录前启动的工作流时,这种分离非常重要。

前台模式 vs 服务模式

模式运行形态典型用途主要限制
前台模式由 GUI 进程直接持有核心开发与快速配置检查当 GUI 退出或用户注销时,核心会停止
服务模式系统服务持有核心;GUI 通过本地 IPC 对其进行控制日常使用、TUN/透明路由、常驻在线场景需要安装服务并管理权限

为什么启用服务模式

  • 即使 GUI 关闭,也能保持流量转发继续运行。
  • 在开机/登录时自动启动代理服务,并保持可预期的生命周期。
  • 更可靠地支持特权路径(例如 TUN、策略路由、透明捕获)。
  • 减少共享机器上不同用户会话之间的行为漂移。

Chimera GUI 中的配置流程

  1. 先在普通模式下准备并验证当前启用的配置。
  2. 打开 Chimera GUI 设置并启用服务模式。
  3. 在 GUI 提示时安装/注册服务。
  4. 选择启动策略:
    • 手动:仅在需要时启动。
    • 自动:系统启动时即启动(推荐用于常驻在线场景)。
  5. 应用设置并在 GUI 中触发服务重启。
  6. 确认重启后 GUI 能重新连接本地控制端点。

关键选项与推荐默认值

选项名称会因平台/构建略有差异,但含义通常一致:

GUI 选项(常见命名)含义建议默认值
Enable Service Mode将核心运行时归属切换为系统服务长期日常使用建议开启
Install/Repair Service注册或修复服务元数据首次启用后以及升级后执行
Start Service at Boot系统启动期间自动启动服务TUN 或网关式部署建议开启
Keep Running After GUI ExitGUI 关闭后保持服务运行开启
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 与服务二进制来自同一构建渠道/版本。

上线策略

  1. 先从仅 SOCKS/监听器配置开始,并确认基线连通性。
  2. 启用服务模式,并验证 GUI 重启后的重连行为。
  3. 逐步启用高级选项(TUN、DNS 劫持、透明捕获)。
  4. 重启一次,并验证自启动、规则命中行为以及 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-rsChimera 能平滑跟进升级。

测试与质量

chimera_server 维护覆盖解析器、密码原语和传输行为的详尽单元测试。集成测试会启动内存中的客户端/服务端对以验证互操作性。基准测试在代表性硬件上测量握手延迟、吞吐量和内存占用,为回归检测提供基线。

协议

概览

协议默认传输认证优势典型限制
SOCKS5TCP 控制 + 可选 UDP可选用户名/密码几乎兼容任何 TCP 应用,支持 UDP ASSOCIATE 模式默认明文,需要在其他层使用 TLS/混淆
HTTP(S) CONNECT通过 HTTP/1.1 或 HTTP/2 承载 TCPBasic 认证、Bearer 令牌、双向 TLS与 Web 流量融合,易于在网关部署仅代理 TCP,依赖中间层保持长时隧道
Trojan基于 TCP 的 TLSTLS 内校验预共享密码难以被指纹识别,受益于 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:

亮点

  • 四层代理,可转发任意 TCP 流,并通过 ASSOCIATE 命令支持 UDP。
  • 方法协商允许服务器声明 NO AUTHUSERPASS 或自定义认证。
  • 被浏览器、curl、SSH 和 VPN 客户端广泛支持。

流程

  1. 客户端向代理打开一个 TCP 套接字。
  2. 客户端发送支持的认证方法列表;服务器返回选定的方法。
  3. 可选的用户名/密码交换。
  4. 客户端携带目标信息发送 CONNECTBINDUDP ASSOCIATE
  5. 服务器返回成功/失败码并开始转发流量。

配置片段

优势

  • 无需额外插件即可配合传统工具使用。
  • 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 多路复用。

流程

  1. 客户端与代理端点建立 TCP(或 TLS)连接。
  2. 客户端可选进行 HTTP 认证(Basic、Digest、Bearer 或双向 TLS)。
  3. 客户端发送 CONNECT target.example.com:443 HTTP/1.1(或 HTTP/2 的 :method CONNECT)。
  4. 代理校验策略后返回 200 Connection Established
  5. 后续字节透明转发,直到任一侧关闭隧道。

配置片段

优势

  • 与标准 HTTPS 流量混在一起,难以与普通网页浏览区分。
  • 适合在只允许 80/443 端口的企业防火墙后使用。
  • HTTP/2 变体可在单个 TCP 会话上复用多条隧道,降低握手成本。

限制

  • 仅支持 TCP;不经额外封装无法转发 UDP 流。
  • 代理需为每条隧道维护状态,在大量短连接下会影响扩展性。
  • 若未清理,额外的 HTTP 头可能泄露元数据。

Trojan

亮点

  • 以真实的 TLS 握手开始;后续所有字节都是 TLS 应用数据。
  • 认证方式是对预共享密码进行 SHA-224 哈希并做十六进制编码。
  • 请求帧复用 SOCKS5 风格的地址字段,用于 CONNECT 和 UDP ASSOCIATE。
  • 无效或未知流量可以转发到回落端点,使其看起来像正常的 HTTPS。

流程

  1. 客户端与服务器完成标准 TLS 握手(SNI/ALPN 按配置)。
  2. 客户端发送 hex(SHA224(password)) + CRLF + Trojan Request + CRLF(+ 可选负载)。
  3. 服务器校验密码与请求,然后连接到目标。
  4. 对 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。
  • 配合现代拥塞控制,面向低延迟场景进行激进调优。

流程

  1. 客户端向服务器建立 QUIC 连接并完成 TLS 1.3 握手。
  2. 客户端使用服务器配置的 UUID/令牌完成认证。
  3. 客户端为 TCP 请求打开双向 QUIC 流,并使用数据报进行 UDP 中继。
  4. 服务器完成认证校验后,将流量转发到上游目的地。

配置片段

优势

  • 通过 0-RTT 与流复用降低握手开销。
  • 原生处理 UDP,无需额外封装层。
  • 在高丢包或高时延移动网络下通常表现更好。

限制

  • 需要 UDP 可达且网络路径对 QUIC 友好。
  • QUIC 指纹会因实现而异,可能被限速或封锁。
  • 为获得最佳效果,通常需要调优 MTU 与发包节奏。

VLESS

亮点

  • 来自 Project V 的轻量无状态协议,使用 UUID 作为客户端标识。
  • 通常与 TLS、XTLS 或 Reality 传输层搭配,用于加密与伪装。
  • 在 Xray-core 生态内支持多路复用、回退路由和高级路由规则。

流程

  1. 客户端连接到服务器传输层(TLS、XTLS、Reality、gRPC 或 MKCP)。
  2. 客户端发送包含 UUID、命令(TCP/UDP)和目标地址的 VLESS 头。
  3. 服务器校验 UUID 后,建立到目的地的流或数据报隧道。
  4. 可选功能如 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: xhttpclient/server启用 xHTTP 传输。
pathclient/server传输使用的 HTTP 请求路径,客户端与服务端必须一致。
hostclient可选的 Host 请求头覆盖(用于前置/反向代理场景)。
modeclient/server传输模式,通常为 auto(默认)或平台特定变体。
extra.headersclient额外 HTTP 请求头,用于模拟应用/API 流量。
xmuxclient/server多路复用调优项,如并发限制与连接复用。
tls / realityclient/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 搭配,在传输层之上提供认证与路由能力。

流程

  1. 客户端选择伪装域名,并配置服务端公钥 + short ID。
  2. 客户端发起类 TLS 1.3 握手(uTLS 指纹),并将 SNI 设为伪装域名。
  3. 服务器校验 short ID 与密钥交换后接受该会话。
  4. 成功后,连接升级为选定的代理协议(例如 VLESS)。

配置片段

优势

  • 在保持类 TLS 握手行为的同时,避免证书签发与轮换。
  • 当 TLS 客户端指纹贴近常见浏览器时,更难被被动探测识别。
  • 可与 XTLS 流控集成以降低开销。

限制

  • 需要兼容的客户端指纹;不匹配会导致连接失败。
  • 主要局限在 Xray 工具生态内。
  • 效果取决于伪装域名选择与配置正确性。