Freedom — Xray-core
Freedom 是 Xray 的旁路出站 —— 把流量直接送往真实目标,中间不加任何代理协议层。另外它还携带两个反 DPI 功能:TCP / TLS 分片与任意噪声包注入。
出站
"protocol": "freedom" 出站的 settings:
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
targetStrategy | string | asis | asis | useip | useipv4 | useipv6 | useipv4v6 | useipv6v4 | forceip | forceipv4 | forceipv6 | forceipv4v6 | forceipv6v4 | 已弃用 —— 启动时非 asis 的值会被迁移到 streamSettings.sockopt.domainStrategy(取值相同)并记录警告;请改为直接设置后者。拨号前如何解析目的地址。asis 透传路由引擎给出的值;useip* 仅在必要时解析为 IP;forceip* 总是解析并替换。*v4v6 / *v6v4 后缀控制首选哪个家族。 |
domainStrategy | string | (inherits targetStrategy) | <same values> | targetStrategy 的旧式别名。仅在 targetStrategy 为空时被读取。与 targetStrategy 一同弃用。 |
redirect | string | (unset) | <host:port> | 覆盖每次拨号的目的地,便于无视路由把流量送到本地服务。 |
userLevel | uint32 | 0 | <uint32> | 经过该出站的连接的默认策略等级。 |
fragment | *Fragment | (disabled) | Fragment | 按分段的 TCP 分片,用于规避基于长度的 DPI。 |
noise | *Noise | (unsupported) | (use noises) | 不受支持 —— 请使用 noises 数组;设置 noise 会在配置构建时显式报错。 |
noises | []*Noise | (unset) | [Noise] | 在真实数据包之前(或之间)发送的噪声包列表,用于干扰模式匹配。 |
proxyProtocol | uint32 | 0 | 0 | 1 | 2 | 在出站连接前置 PROXY 协议头。0 关闭;1 / 2 分别使用 v1(文本)或 v2(二进制)。 |
ipsBlocked | *StringList | (ignored) | (use finalRules) | 不受支持 —— 请用 finalRules 表达 IP 拦截;设置它只会记录一条警告,没有实际作用。 |
finalRules | []*FreedomFinalRuleConfig | (unset) | [FreedomFinalRuleConfig] | 在拨号时按连接求值的放行 / 拦截规则 —— 即出站自身上的一个轻量防火墙,按 network / port / IP 匹配。设置了 streamSettings.sockopt.dialerProxy 时会被忽略(并记录警告)。 |
源码: infra/conf/freedom.go:19-30 · 锚定版本 v26.9.9 (52a412d)
fragment
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
packets | string | (all) | tlshello | <from-to> | | 选择要分片的数据包。tlshello 只分片 TLS ClientHello(手段细腻,对 SNI 混淆有用)。"1-3" 这样的范围分片该偏移区间的包。空值分片所有数据包 —— 最激进。 |
length | *Int32Range | (required) | {from, to} | 每个分片的字节数范围。最小值必须 > 0。 |
interval | *Int32Range | (required) | {from, to} | 分片间延迟的毫秒数范围。 |
maxSplit | *Int32Range | (unbounded) | {from, to} | 每个数据包的总分片数范围。可选上限。 |
源码: infra/conf/freedom.go:32-37 · 锚定版本 v26.9.9 (52a412d)
noises[]
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
type | string | (required) | rand | str | hex | base64 | 噪声载荷形式。rand 生成随机字节,长度由 packet(范围字符串)决定。str / hex / base64 把 packet 当作字面量解释。 |
packet | string | (required) | <bytes or range> | 载荷内容。格式取决于 type。 |
delay | *Int32Range | (unset) | {from, to} | 发送该噪声包前等待的毫秒数范围。 |
applyTo | string | ip | ip | all | ipv4 | ipv6 | 限制注入仅作用于哪种 IP 家族。ip 与 all 都同时作用于两者。 |
源码: infra/conf/freedom.go:39-44 · 锚定版本 v26.9.9 (52a412d)
finalRules[]
freedom 出站在拨号时应用的小型放行 / 拦截防火墙。规则按顺序求值,第一条命中即决定结果。IP 拦截应写在这里 —— ipsBlocked 字段会被忽略。
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
action | string | (required) | allow | block | 对匹配连接的处理方式。block 拒绝它;allow 放行 —— 把 allow 规则列在前面,可在更宽的 block 中开出例外。 |
network | *NetworkList | (any) | tcp | udp | tcp,udp | 仅匹配这些网络。 |
port | *PortList | (any) | <port / range list> | 仅匹配这些目的端口。 |
ip | *StringList | (any) | <IP / CIDR / geoip:> | 仅匹配这些目的 IP。接受 geoip: 类目。 |
blockDelay | *Int32Range | (immediate) | {from, to} | 对于 block 动作,在丢弃连接前等待该毫秒范围内的随机延迟 —— 拖住探测者,而不是快速失败。 |
源码: infra/conf/freedom.go:46-52 · 锚定版本 v26.9.9 (52a412d)
示例
朴素 freedom 出站(直通):
json
{
"outbounds": [
{ "tag": "direct", "protocol": "freedom", "settings": {} }
]
}强制 IPv4 优先、IPv6 回落的解析:
json
{
"outbounds": [
{
"tag": "direct-v4",
"protocol": "freedom",
"settings": {},
"streamSettings": { "sockopt": { "domainStrategy": "forceipv4v6" } }
}
]
}TLS-hello 分片(SNI 混淆的良好起点):
json
{
"outbounds": [
{
"tag": "frag",
"protocol": "freedom",
"settings": {
"fragment": {
"packets": "tlshello",
"length": { "from": 10, "to": 20 },
"interval": { "from": 10, "to": 20 }
}
}
}
]
}噪声注入(每条 IPv4 连接前 4 字节随机数据,延迟 0–1 ms):
json
{
"outbounds": [
{
"tag": "noisy",
"protocol": "freedom",
"settings": {
"noises": [
{
"type": "rand",
"packet": "4-4",
"delay": { "from": 0, "to": 1 },
"applyTo": "ipv4"
}
]
}
}
]
}直接拦截 QUIC(UDP/443),并拖住到私有网段的连接以拖慢探测:
json
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {
"finalRules": [
{ "action": "block", "network": "udp", "port": "443" },
{ "action": "block", "ip": ["geoip:private"], "blockDelay": { "from": 1000, "to": 3000 } }
]
}
}
]
}把一切转发到本地服务(测试辅助):
json
{
"outbounds": [
{
"tag": "redir",
"protocol": "freedom",
"settings": { "redirect": "127.0.0.1:8080" }
}
]
}说明
- freedom
settings中的targetStrategy/domainStrategy已弃用。启动时 Xray 会把非asis的值迁移到streamSettings.sockopt.domainStrategy并记录警告;freedom 出站上的出站级targetStrategy也以同样方式迁移(infra/conf/xray.go:341-364)。迁移后的值会覆盖你自行设置的sockopt.domainStrategy,因此只配置其中之一。domainStrategy仍只在targetStrategy为空时作为回退被读取(infra/conf/freedom.go:46-48)。 - 配置了
finalRules且目标为域名时,freedom 会先解析该域名(使用sockopt.domainStrategy;其为AsIs时使用系统解析器)以检查block规则,连接建立后再对实际连接的地址复查一次。 - 设置了
streamSettings.sockopt.dialerProxy时,freedom 不再是最后一跳:finalRules会被忽略(记录警告),域名也不会被预先解析。 - freedom 会在启动时拒绝
streamSettings.sockopt.addressPortStrategy。 - 未知策略字符串会触发启动错误,而不是静默回退(
infra/conf/freedom.go:72-73)。 - 单数形式的
noise不受支持:设置它会在启动时报错,并提示改用noises = [ { ... } ](infra/conf/freedom.go:145-147)。 ipsBlocked不受支持 —— 请在finalRules中以{ "action": "block", "ip": [...] }规则表达;该字段本身只会记录一条警告,其余被忽略。finalRules的动作仅有allow/block(未知动作会在启动时报错)。ip接受geoip:类目;blockDelay仅对block规则生效。fragment.packets: "tlshello"是推荐起点 —— 只分片 TLS ClientHello 能击穿基于 SNI 的 DPI,又不影响连接其余部分(开销是一次性的)。- 启用
fragment时fragment.length.from与fragment.interval必填(infra/conf/freedom.go:102-118)。maxSplit范围可选。 1..2之外的proxyProtocol会被静默忽略 —— 只有这两个值会输出头(infra/conf/freedom.go:162-164)。
跨内核说明
- sing-box 把这种能力命名为 Direct,出站本身几乎没有自身选项 —— 没有目的地覆盖字段;同等效果请使用 route action。参见 Direct — sing-box。
- mihomo 也有同样精简的 Direct 类型;每个配置中都隐含内置的
DIRECT代理。参见 Direct — mihomo。
源码: infra/conf/freedom.go:19-52 · v26.9.9 (52a412d)
