18 KiB
Leaf
Leaf 是一个轻量且快速的代理工具。
目录
Downloads
https://github.com/eycorsican/leaf/releases
iOS TestFlight
iOS TF 测试公开链接:https://testflight.apple.com/join/std0FFCS
conf
[General]
loglevel = info
dns-server = 114.114.114.114, 223.5.5.5
always-real-ip = tracker, apple.com
# Local HTTP CONNECT proxy
interface = 127.0.0.1
port = 1087
# Local SOCKS5 proxy with UDP Associate support
socks-interface = 127.0.0.1
socks-port = 1086
[Proxy]
Direct = direct
Reject = reject
# Shadowsocks
SS = ss, 1.2.3.4, 8485, encrypt-method=chacha20-ietf-poly1305, password=123456
# VMess
VMess = vmess, my.domain.com, 8001, username=0eb5486e-e1b5-49c5-aa75-d15e54dfac9d
# VMess over WebSocket over TLS (TLS + WebSocket + VMess)
VMessWSS = vmess, my.domain.com, 443, username=0eb5486e-e1b5-49c5-aa75-d15e54dfac9d, ws=true, tls=true, ws-path=/v2
# Trojan (with TLS)
Trojan = trojan, 4.3.2.1, 443, password=123456, sni=www.domain.com
# Trojan over WebSocket over TLS (TLS + WebSocket + Trojan)
TrojanWS = trojan, 4.3.2.1, 443, password=123456, sni=www.domain.com, ws=true, ws-path=/abc
[Proxy Group]
# fallback 等效于 failover
Fallback = fallback, Trojan, VMessWSS, SS, interval=600, timeout=5
# url-test 等效于 failover=false 的 failover
UrlTest = url-test, Trojan, VMessWSS, SS, interval=600, timeout=5
Failover = failover, Trojan, VMessWSS, SS, health-check=true, check-interval=600, fail-timeout=5, failover=true
Tryall = tryall, Trojan, VMessWSS, delay-base=0
Random = random, Trojan, VMessWSS
[Rule]
# 执行文件目录当中必需有 `site.dat` 文件
EXTERNAL, site:category-ads-all, Reject
# 也可以指定 `dat` 文件所在绝对路径,不支持相对路径
EXTERNAL, site:/tmp/geosite.dat:category-ads-all, Reject
IP-CIDR, 8.8.8.8/32, Fallback
DOMAIN, www.google.com, Fallback
DOMAIN-SUFFIX, google.com, Fallback
DOMAIN-KEYWORD, google, Fallback
# 等效于 EXTERNAL, mmdb:us, Fallback
GEOIP, us, Fallback
EXTERNAL, site:geolocation-!cn, Fallback
# 执行文件目录当中必需有 `geo.mmdb` 文件
EXTERNAL, mmdb:us, Fallback
FINAL, Direct
json
JSON 配置文件目前不考虑兼容性,每个版本都可能会变。
{
"log": {
"level": "info"
},
"dns": {
"servers": [
"1.1.1.1",
"8.8.8.8"
]
},
"inbounds": [
{
"address": "127.0.0.1",
"port": 1087,
"protocol": "http"
},
{
"address": "127.0.0.1",
"port": 1086,
"protocol": "socks"
}
],
"outbounds": [
{
"protocol": "failover",
"settings": {
"actors": [
"vmess_out",
"trojan_out"
]
},
"tag": "failover_out"
},
{
"protocol": "chain",
"settings": {
"actors": [
"vmess_tls",
"vmess_ws",
"vmess"
]
},
"tag": "vmess_out"
},
{
"protocol": "tls",
"tag": "vmess_tls"
},
{
"protocol": "ws",
"settings": {
"path": "/v2"
},
"tag": "vmess_ws"
},
{
"protocol": "vmess",
"settings": {
"address": "server.com",
"port": 443,
"uuid": "89ee4e17-aaad-49f6-91c4-6ea5990206bd"
},
"tag": "vmess"
},
{
"protocol": "chain",
"settings": {
"actors": [
"trojan_tls",
"trojan"
]
},
"tag": "trojan_out"
},
{
"protocol": "tls",
"tag": "trojan_tls"
},
{
"protocol": "trojan",
"settings": {
"address": "server.com",
"password": "112358",
"port": 443
},
"tag": "trojan"
},
{
"protocol": "shadowsocks",
"settings": {
"address": "x.x.x.x",
"method": "chacha20-ietf-poly1305",
"password": "123456",
"port": 8389
},
"tag": "shadowsocks_out"
},
{
"protocol": "socks",
"settings": {
"address": "x.x.x.x",
"port": 1080
},
"tag": "socks_out"
},
{
"protocol": "direct",
"tag": "direct_out"
},
{
"protocol": "drop",
"tag": "drop_out"
}
],
"rules": [
{
"ip": [
"8.8.8.8",
"8.8.4.4"
],
"target": "failover_out"
},
{
"domain": [
"www.google.com"
],
"target": "failover_out"
},
{
"domainSuffix": [
"google.com"
],
"target": "failover_out"
},
{
"domainKeyword": [
"google"
],
"target": "failover_out"
},
{
"external": [
"site:cn"
],
"target": "direct_out"
},
{
"external": [
"mmdb:cn"
],
"target": "direct_out"
}
]
}
Log
"log": {
"level": "info"
}
level 可以是 trace, debug, info, warn, error
DNS
"dns": {
"servers": [
"114.114.114.114",
"1.1.1.1"
]
}
DNS 用于 direct Outbound 请求的域名解析,以及其它 Outbound 中代理服务器地址的解析(如果代理服务器地址是 IP,则不需要解析)。
Inbounds
"inbounds": [
{
...
},
{
...
}
]
inbounds 是一个数组,每一项可以是以下:
http
{
"protocol": "http",
"address": "127.0.0.1",
"port": 1087
}
支持 HTTP Connect。
socks
{
"protocol": "socks",
"address": "127.0.0.1",
"port": 1086
}
默认支持 UDP。
trojan
{
"protocol": "trojan",
"address": "127.0.0.1",
"port": 10086,
"settings": {
"password": "123456"
}
}
ws
WebSocket 传输,一般在 chain 叠加到其它代理协议上。
{
"protocol": "ws",
"settings": {
"path": "/abc"
}
}
chain
chain 可以对多个协议进行叠加。
{
"protocol": "chain",
"address": "127.0.0.1",
"port": 10086,
"settings": {
"actors": [
"ws_out",
"trojan_out"
]
}
}
例如这是一个 WebSocket + Trojan 配置:
"inbounds": [
{
"protocol": "chain",
"tag": "ws_trojan_in",
"address": "127.0.0.1",
"port": 4003,
"settings": {
"actors": [
"ws_in",
"trojan_in"
]
}
},
{
"protocol": "ws",
"tag": "ws_in",
"settings": {
"path": "/abc"
}
},
{
"protocol": "trojan",
"tag": "trojan_in",
"settings": {
"password": "12345"
}
}
]
注意上面配置示例没有 TLS,一般可以交给 nginx 来处理。
Outbounds
支持常见的代理协议比如 Shadowsocks、VMess、Trojan,以及 TLS 和 WebSocket 传输,另外有四个组合类型的 Outbound,其中 chain 可以对各种代理和传输协议进行任意组合。
"outbounds": [
{
...
},
{
...
}
]
outbounds 是一个数组,每一项可以是以下:
direct
直连出口,请求将从本机直接发往目标,不经任何代理。
{
"protocol": "direct",
"tag": "direct_out"
}
drop
拦截请求。
{
"protocol": "drop",
"tag": "drop_out"
}
tls
TLS 传输,一般用来叠加到其它代理或传输协议上。
{
"protocol": "tls",
"settings": {
"serverName": "server.com",
"alpn": ["http/1.1"]
},
"tag": "tls_out"
}
如果 serverName 为空,会尝试从下层协议获取。
ws
WebSocket 传输,一般用来叠加到其它代理或传输协议上。
{
"protocol": "ws",
"settings": {
"path": "/v2"
},
"tag": "ws_out"
}
还未支持自定义 Headers,Host 会尝试从下层协议获取。
h2
HTTP2 传输,一般需要配合 tls 一起使用,tls 需要配置 h2 作为 alpn。
"outbounds": [
{
"protocol": "chain",
"settings": {
"actors": [
"vmess_tls",
"vmess_h2",
"vmess"
]
},
"tag": "vmess_out"
},
{
"protocol": "tls",
"settings": {
"serverName": "server.com",
"alpn": ["h2"]
},
"tag": "vmess_tls"
},
{
"protocol": "h2",
"settings": {
"host": "server.com",
"path": "/v2"
},
"tag": "vmess_h2"
},
{
"protocol": "vmess",
"settings": {
"address": "server.com",
"port": 443,
"uuid": "89ee4e17-aaad-49f6-91c4-6ea5990206bd"
},
"tag": "vmess"
}
]
shadowsocks
{
"protocol": "shadowsocks",
"settings": {
"address": "x.x.x.x",
"method": "chacha20-ietf-poly1305",
"password": "123456",
"port": 8389
},
"tag": "shadowsocks_out"
}
method:
- chacha20-ietf-poly1305
- aes-128-gcm
- aes-256-gcm
vmess
{
"protocol": "vmess",
"settings": {
"address": "server.com",
"port": 10086,
"uuid": "89ee4e17-aaad-49f6-91c4-6ea5990206bd",
"security": "chacha20-ietf-poly1305"
},
"tag": "vmess"
}
security:
- chacha20-ietf-poly1305
- aes-128-gcm
trojan
trojan Outbound 只包含未经 TLS 加密的代理协议,通常还需要利用 chain 对其叠加一层 tls 才能和正常的 trojan 服务器通讯。
{
"protocol": "trojan",
"settings": {
"address": "server.com",
"password": "112358",
"port": 443
},
"tag": "trojan_out"
}
socks
{
"protocol": "socks",
"settings": {
"address": "1.2.3.4",
"port": 1080
},
"tag": "socks_out"
}
socks 不支持用户密码认证。
chain
chain Outbound 可以对任意协议进行叠加,主要用途是在某个代理协议上叠加 tls、ws 等传输,以及配置代理链。
这是一个典型的 TLS + WebSocket + VMess 配置:
"outbounds": [
{
"protocol": "chain",
"settings": {
"actors": [
"vmess_tls",
"vmess_ws",
"vmess"
]
},
"tag": "vmess_out"
},
{
"protocol": "tls",
"tag": "vmess_tls"
},
{
"protocol": "ws",
"settings": {
"path": "/v2"
},
"tag": "vmess_ws"
},
{
"protocol": "vmess",
"settings": {
"address": "server.com",
"port": 443,
"uuid": "89ee4e17-aaad-49f6-91c4-6ea5990206bd"
},
"tag": "vmess"
}
]
如果有多个服务器,可以配置一个代理链,请求将沿着代理链传输后到达目标:
客户端 -> ss1 -> ss2 -> 目标
"outbounds": [
{
"protocol": "chain",
"settings": {
"actors": [
"ss1",
"ss2"
]
},
"tag": "ss_chain_out"
},
{
"protocol": "shadowsocks",
"settings": {
"address": "1.1.1.1",
"method": "chacha20-ietf-poly1305",
"password": "123456",
"port": 1111
},
"tag": "ss1"
},
{
"protocol": "shadowsocks",
"settings": {
"address": "2.2.2.2",
"method": "chacha20-ietf-poly1305",
"password": "123456",
"port": 2222
},
"tag": "ss2"
}
]
failover
{
"protocol": "failover",
"settings": {
"actors": [
"vmess_out",
"trojan_out"
],
"failTimeout": 4,
"healthCheck": true,
"checkInterval": 300,
"failover": true
},
"tag": "failover_out"
}
向列表中的 Outbound 逐个发送请求,直到找到一个可用的 Outbound,可选参数有
failTimeout握手超时,包括 TCP 握手及相应代理协议握手的时间healthCheck如果为true,则对列表中的 Outbound 定时做健康检查,并按延迟重新排序checkInterval健康检查间隔failover如果为false,则只取一个 Outbound 发送请求,失败也不会尝试其它 Outbound
tryall
{
"protocol": "tryall",
"settings": {
"actors": [
"trojan_out",
"vmess_out"
],
"delayBase": 0
},
"tag": "tryall_out"
}
向列表中的所有 Outbound 同时发起代理请求,选取握手成功最快的 Outbound,可选参数有
delayBase延时基数,如果大于 0,则代理请求会延迟 delayBase * index 毫秒,index 从 0 起,每个 Outbound 递增 1
random
{
"protocol": "random",
"settings": {
"actors": [
"trojan_out",
"vmess_out"
]
},
"tag": "random"
}
从列表中随机选一个 Outbound 发送请求。
Rules
规则方面跟 V2Ray 差不多,只是把域名规则展开成 domain, domainSuffix, domainKeyword。
"rules": [
{
...
},
{
...
}
]
rules 是一个数组,每一项可以是以下:
domain
匹配整个域名。
{
"domain": [
"www.google.com"
],
"target": "failover_out"
}
domainSuffix
匹配子域名,虽然名字是 Suffix,但只匹配子域名,即 google.com 匹配 www.google.com,但不匹配 wwwgoogle.com。
{
"domainSuffix": [
"google.com"
],
"target": "failover_out"
}
domainKeyword
匹配域名关键字。
{
"domainKeyword": [
"google"
],
"target": "failover_out"
}
ip
匹配 IP 或 IP-CIDR。
{
"ip": [
"8.8.8.8/32",
"8.8.4.4"
],
"target": "failover_out"
}
geoip
可执行文件目录中必需有 geo.mmdb 文件存在。
{
"geoip": [
"us",
"jp"
],
"target": "failover_out"
}
external
external 规则可以从外部文件加载规则,支持两种格式
{
"external": [
"mmdb:us",
],
"target": "failover_out"
}
{
"external": [
"site:cn",
],
"target": "direct_out"
}
mmdb
MaxMind 的 mmdb 格式,可以有如下形式:
mmdb:TAG假设 mmdb 文件存在于可执行文件目录,并且文件名为geo.mmdbmmdb:FILENAME:TAG假设 mmdb 文件存在于可执行文件目录,文件名为FILENAMEmmdb:PATH:TAG指写 mmdb 文件的绝对路径为PATH
site
V2Ray 的 dat 文件格式,可以有如下形式:
site:TAG同 mmdb,文件名为site.datsite:FILENAME:TAG同 mmdbsite:PATH:TAG同 mmdb
Advanced Features
TUN Inbound
在 macOS 和 Linux 上还支持 TUN Inbound
"inbounds": [
{
"protocol": "tun",
"settings": {
"name": "utun8",
"address": "10.10.0.2",
"netmask": "255.255.255.0",
"gateway": "10.10.0.1",
"mtu": 1500,
"fakeDnsInclude": [
"google"
]
},
"tag": "tun_in"
}
]
参数
name在 macOS 上必须是utun开头后加一个数字,在 Linux 上必须是tun开头后加一个数字addressnetmaskgatewaymtuTUN 接口的一些参数fakeDnsInclude使用 TUN Inbound 将默认使用FakeDNS功能,这个列表可以指定哪些域名会返回伪造 IP,以关键字方式匹配,未指定的域名将不受影响。fakeDnsExclude使用 TUN Inbound 将默认使用FakeDNS功能,这个列表可以将某些域名排除在外,以关键字方式匹配,未指定的域名将会返回伪造的 IP。
fakeDnsInclude 和 fakeDnsExclude 只能二选一,这个配置方式将来大概率会改。
在 macOS 上还不能自动配置地址需要手动:sudo ifconfig utun7 10.10.0.2 netmask 255.255.255.0 10.10.0.1
还需要手动配置路由表,具体可以参考 Mellow :macOS Linux
此外所有非组合类型的 Outbound 必须正确配置一个 bind 地址,这是连接原网关的网卡的地址,即未连接 VPN 前网卡的 IP 地址:
"outbounds: [
{
"bind": "192.168.0.99",
"protocol": "shadowsocks",
"settings": {
"address": "x.x.x.x",
"method": "chacha20-ietf-poly1305",
"password": "123456",
"port": 8389
},
"tag": "shadowsocks_out"
},
{
"bind": "192.168.0.99",
"protocol": "direct",
"tag": "direct"
}
]
"dns": {
"bind": "192.168.0.99",
"servers": ["1.1.1.1"]
}