节点转换映射关系
作者:
长风
发布于:4 months ago / 阅读:3799
#节点转换原理
为了让大家更方便转换,我把节点转换规则抽取出来。第一步,分析节点参数,并组装成对象,如 trojan
节点结构如下:trojan://password@server:port?encryption=none&security=tls&type=h2&host=bing.com&path=%2F4eb3cc3a-baba-4847-8479-e82dab89173e#trojan_node
1. 解析成对象
{
password: password,
server: server,
port: port,
encryption: none,
security: tls,
type: h2,
host: bing.com,
path: /4eb3cc3a-baba-4847-8479-e82dab89173e
name: trojan_node
}
1. 根据映射关系,把对象解析成 clash/singbox 节点
const mapping = {
trojan: {
clash: {
server: 'server', port: 'port', password: 'password', network: 'type=tcp', sni: 'sni|host', alpn:'[alpn]', 'skip-cert-verify': "insecure=='1'", fingerprint: 'fp',
tls: "security==[tls,reality]",
"h2-opts?type=h2": { path: "path", host: '[host]' },
"ws-opts?type=ws": { path: 'path', headers: { Host: 'host' } },
"grpc-opts?type=grpc": { "grpc-service-name": 'serviceName' },
"ss-opts": { enabled: '{NOT_EMPTY}', method: 'encryption?.method', password: 'encryption?.password' },
},
singbox: {
server: 'server', server_port: 'port', passowrd: 'password', network: 'type=tcp', plugin: 'plugin',
transport: { type: 'type=tcp', service_name: 'serviceName', path: 'path', headers: { Host: 'host' } },
tls: { enabled: '{NOT_EMPTY}', server_name: 'sni|peer', alpn:'[alpn]' },
plugin_opts: { mode: 'plugin-opts?.obfs', host: 'plugin-opts?.obfs-host' }
}
},
}
如果转换类型是 clash,那么代码会自动定位到 trojan -> clash 里面的映射参数
转换成 clash 得到的结果就是
proxies:
- type: trojan
name: trojan_node
server: server
port: port
password: password
network: h2
sni: bing.com
tls: true
h2-opts:
path: /4eb3cc3a-baba-4847-8479-e82dab89173e
host:
- bing.com
#解释映射对象
映射对象里面除了可以直接映射对象属性外,还可以添加各种定制服务,如 {NOT_EMPTY}, type==tcp 下面我来解释一下含义
最简单的映射对象属性直接对应 clash/singbox 属性
server: "server"
fingerprint: "fp"
给默认值
network: 'type=tcp'
如果 type 有值,则用 type 值要不然用 tcp给 clash 或者singbox 赋予对象的多个值的任何一个
server_name: 'sni|peer'
对象里面如果有 sni 就给sni 否则再看 peer有没有,有的话给 peertrue
映射
skip-cert-verify
: insecure == '1'
当对象属性 insecure = 1 的时候 skip-cert-verify = truetls: "security==[tls,reality]"
当 security = tls 或者 = reality 的时候 tls = trueenabled: 'tls==[1,tls]|net==[quic]'
当 tls 有 1, tls 任何一个值或者 net = quid 的时候 enabled = true判断某个属性是否应该存在
"h2-opts?type=h2": { path: "path", host: '[host]' },
只有当对象属性 type = h2 的时候才会显示 h2-opts: { path: 'path', host: '[host]' }
属性"grpc-opts?type=grpc": { "grpc-service-name": 'serviceName' },
只有当对象属性 type = grpc 的时候才会显示 grpc-opts: {....}
"http-opts?type=http|type=xhttp": { path: 'path', headers: { Host: 'host' } },
当type = http 或者 type = http 的时候显示 http-opts 属性"headers?net=[ws,http,h2,httpupgrade]": { host: "host" }
当 net 有其ws,http,h2,httpupgrade
任何一个值的时候显示 headers 属性多值显示,有的属性映射到 clash 或者 singbox 的时候可能要显示成数组
host: '[host]'
当对象有 host 属性的时候会显示 host: [bing.com,baidu.com]
有多少显示多少server_ports: '[ports|mport]'
多值数组显示,如果 ports 有值则使用 ports或者使用 mport当某个括号里属性不为空的时候
"ss-opts": { enabled: '{NOT_EMPTY}', method: 'encryption?.method', password: 'encryption?.password' }
, 当 method, 和 password 有值的时候 enabled: true某个对象属性可能不存在,但要获取到的子属性的时候
method: 'encryption?.method'
当对象可能不存在这个属性encryption 的时候用 ?.
防止报错三目判断
type: "net==h2?'http':net"
如果 net等于 h2 则 type = http 否则取 对象的 net 值