跳转至

示例配置

仓库中的 examples/ 是可版本控制的起点。复制最接近部署场景的文件,再替换其中的 占位符;不要在原文件中写入真实订阅、密码或私钥。

场景选择

场景 文件 重点
官方多平台完整配置 multi-platform.yaml 远程订阅、23 个中文策略组、24 个规则集、国内外 DNS 分流和跨平台 TUN
桌面普通代理 desktop.yaml Mixed 监听、手动节点和基本路由
路由器/网关 router.yaml TUN、自动路由和严格路由
Android VpnService android.yaml 非 root TUN、应用过滤和移动网络
Android root TUN android-root-tun.yaml root /dev/net/tun、策略路由和包名过滤
Android root TPROXY android-root-tproxy.yaml TCP、UDP、iptables 和策略路由
Android root REDIRECT android-root-redirect.yaml TCP、nftables 和 UID 过滤
高级 DNS dns-advanced.yaml 命名上游、策略和独立出口
自由订阅 subscription-native.yaml 原生节点文档与协议探测
Feed with_feed.yaml 订阅过滤、重命名和策略组
纯手动节点 manual_only.yaml 不依赖订阅服务
日常策略 daily.yaml 自定义策略组和规则

官方多平台完整配置

examples/official/multi-platform.yaml
version: 1
profile: desktop
name: official-multi-platform

# 这份配置可直接用于 Windows、macOS、Linux 和 Android。
# 演示订阅只提供 Direct 节点,先保证配置能够完整启动。
# 需要代理时,只替换 feeds.primary.url,其他部分不必删除。

log:
  on: true
  level: info
  stdout: true
  format: text
  connection-summary-interval: 1m
  file:
    on: false
    path: data/logs/wuther-core.log

database:
  enabled: true
  path: data/state/wuthercore.db
  relative-to: cwd
  busy-timeout: 5s
  max-write-attempts: 12
  multiprocess-wal: auto
  experimental-vacuum: true

inbounds:
  - type: mixed
    tag: 本地代理
    listen: 127.0.0.1
    listen_port: 7890
    udp: true

  - type: tun
    tag: 系统接管
    enabled: true
    address:
      - 198.18.0.1/15
      - fdfe:dcba:9876::1/126
    traffic: system
    dns_mode: hijack
    stack: mixed
    mtu: 1500
    offload: true
    inet6: true
    auto_route: true
    auto_redirect: false
    strict_route: false
    exclude:
      cidr:
        - 127.0.0.0/8
        - 169.254.0.0/16
        - 224.0.0.0/4
        - 255.255.255.255/32
        - ::1/128
        - fe80::/10
        - ff00::/8
      process:
        - wuther-core
        - wuther-core.exe
    route_exclude_address:
      - 10.0.0.0/8
      - 100.64.0.0/10
      - 127.0.0.0/8
      - 169.254.0.0/16
      - 172.16.0.0/12
      - 192.168.0.0/16
      - fc00::/7
      - fe80::/10
    endpoint-independent-nat: true
    udp-timeout: 5m
    exclude_mptcp: false

listen:
  panel: 127.0.0.1:9090
  share: false

feeds:
  primary:
    # 替换成自己的 Clash、Mihomo、URI、base64 或 WutherCore 订阅。
    # 保留本地址时,内核会从 GitHub 拉取一个 Direct 演示节点。
    url: "https://raw.githubusercontent.com/MiChongs/WutherCore/main/examples/official/provider-demo.yaml"
    every: 6h
    via: direct
    size-limit: 16777216
    header:
      User-Agent: WutherCore
      Accept:
        - application/yaml
        - application/json
        - text/plain
    drop:
      name_has: [过期, 到期, 剩余流量, Expire, Traffic]
    rename:
      add_prefix: "[订阅] "
      remove: [倍率, 剩余流量]

# 订阅首次拉取前以及订阅不可用时仍有明确的 Direct 候选。
# Direct 节点的 address 只用于满足统一节点结构,不会真的拨号到该地址。
nodes:
  - name: DIRECT-FALLBACK
    protocol: direct
    address: 127.0.0.1:1
    network:
      udp: true

# 两层结构:上层分流策略组只引用节点组,下层节点组才引用订阅或静态节点。
# 地区节点组使用严格 filter。图标来自 luestr/IconResource 的 120px 资源。
groups:
  节点选择:
    choose: manual
    proxies:
      - 智能节点
      - 最低延迟节点
      - 故障转移节点
      - 负载均衡节点
      - 香港节点
      - 台湾节点
      - 日本节点
      - 新加坡节点
      - 韩国节点
      - 美国节点
      - 加拿大节点
      - 英国节点
      - 德国节点
      - 法国节点
      - 澳大利亚节点
      - 印度节点
      - 其他地区
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Other_icon/120px/Switch.png"

  人工智能:
    choose: manual
    proxies:
      - 美国节点
      - 新加坡节点
      - 日本节点
      - 台湾节点
      - 英国节点
      - 德国节点
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/App_icon/120px/ChatGPT.png"

  流媒体:
    choose: manual
    proxies:
      - 香港节点
      - 台湾节点
      - 日本节点
      - 新加坡节点
      - 美国节点
      - 英国节点
      - 澳大利亚节点
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/App_icon/120px/Netflix.png"

  游戏加速:
    choose: manual
    proxies:
      - 香港节点
      - 日本节点
      - 新加坡节点
      - 韩国节点
      - 台湾节点
      - 美国节点
    disable-udp: false
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/App_icon/120px/ValorantBible.png"

  开发服务:
    choose: manual
    proxies:
      - 香港节点
      - 日本节点
      - 新加坡节点
      - 美国节点
      - 德国节点
      - 英国节点
      - 加拿大节点
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/App_icon/120px/GitHub.png"

  即时通信:
    choose: manual
    proxies:
      - 新加坡节点
      - 香港节点
      - 日本节点
      - 美国节点
      - 台湾节点
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/App_icon/120px/Telegram.png"

  智能节点:
    choose: smart
    include-all: true
    prefer: [香港, HK, 日本, JP, 新加坡, SG]
    avoid: [DIRECT-FALLBACK, 过期, 到期, 剩余]
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 1m
    idle-timeout: 10m
    tolerance: 50
    unified-delay: true
    max-failed-times: 3
    test-timeout: 5s
    sticky: site
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Other_icon/120px/Node_detection_tool.png"

  最低延迟节点:
    choose: fast
    include-all: true
    avoid: [DIRECT-FALLBACK, 过期, 到期, 剩余]
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 30s
    idle-timeout: 5m
    tolerance: 35
    unified-delay: true
    max-failed-times: 3
    test-timeout: 5s
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/App_icon/120px/OoklaSpeedtest.png"

  故障转移节点:
    choose: stable
    include-all: true
    prefer: [香港, HK, 新加坡, SG, 日本, JP, 美国, US]
    avoid: [DIRECT-FALLBACK, 过期, 到期, 剩余]
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 1m
    idle-timeout: 10m
    unified-delay: true
    max-failed-times: 3
    test-timeout: 5s
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Other_icon/120px/HTTPDNS.png"

  负载均衡节点:
    choose: spread
    include-all: true
    avoid: [DIRECT-FALLBACK, 过期, 到期, 剩余]
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 1m
    idle-timeout: 10m
    strategy: sticky-sessions
    max-failed-times: 3
    test-timeout: 5s
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/App_icon/120px/1.1.1.1.png"

  香港节点:
    choose: smart
    include-all: true
    filter: '(?i)(香港|港区|港服|\bHK\b|Hong[ _-]?Kong|🇭🇰)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 50
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/HK.png"

  台湾节点:
    choose: smart
    include-all: true
    filter: '(?i)(台湾|台灣|台北|新北|高雄|台中|\bTW\b|Taiwan|🇹🇼)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 50
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/TW.png"

  日本节点:
    choose: smart
    include-all: true
    filter: '(?i)(日本|东京|東京|大阪|埼玉|\bJP\b|Japan|🇯🇵)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 50
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/JP.png"

  新加坡节点:
    choose: smart
    include-all: true
    filter: '(?i)(新加坡|狮城|獅城|\bSG\b|Singapore|🇸🇬)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 50
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/SG.png"

  韩国节点:
    choose: smart
    include-all: true
    filter: '(?i)(韩国|韓國|首尔|首爾|\bKR\b|Korea|🇰🇷)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 60
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/KR.png"

  美国节点:
    choose: smart
    include-all: true
    filter: '(?i)(美国|美國|洛杉矶|洛杉磯|硅谷|矽谷|西雅图|西雅圖|芝加哥|达拉斯|達拉斯|纽约|紐約|\bUS\b|\bUSA\b|United[ _-]?States|🇺🇸)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 80
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/US.png"

  加拿大节点:
    choose: smart
    include-all: true
    filter: '(?i)(加拿大|多伦多|多倫多|温哥华|溫哥華|\bCA\b|Canada|🇨🇦)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 80
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/CA.png"

  英国节点:
    choose: smart
    include-all: true
    filter: '(?i)(英国|英國|伦敦|倫敦|\bUK\b|\bGB\b|Britain|United[ _-]?Kingdom|🇬🇧)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 80
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/GB.png"

  德国节点:
    choose: smart
    include-all: true
    filter: '(?i)(德国|德國|法兰克福|法蘭克福|\bDE\b|Germany|🇩🇪)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 80
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/DE.png"

  法国节点:
    choose: smart
    include-all: true
    filter: '(?i)(法国|法國|巴黎|\bFR\b|France|🇫🇷)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 80
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/FR.png"

  澳大利亚节点:
    choose: smart
    include-all: true
    filter: '(?i)(澳大利亚|澳大利亞|澳洲|悉尼|墨尔本|墨爾本|\bAU\b|Australia|🇦🇺)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 90
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/AU.png"

  印度节点:
    choose: smart
    include-all: true
    filter: '(?i)(印度|孟买|孟買|\bIN\b|India|🇮🇳)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 90
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/IN.png"

  其他地区:
    choose: smart
    include-all: true
    exclude-filter: '(?i)(香港|港区|港服|\bHK\b|Hong[ _-]?Kong|台湾|台灣|台北|\bTW\b|Taiwan|日本|东京|東京|大阪|\bJP\b|Japan|新加坡|狮城|獅城|\bSG\b|Singapore|韩国|韓國|首尔|首爾|\bKR\b|Korea|美国|美國|\bUS\b|\bUSA\b|United[ _-]?States|加拿大|\bCA\b|Canada|英国|英國|\bUK\b|\bGB\b|Britain|德国|德國|\bDE\b|Germany|法国|法國|\bFR\b|France|澳大利亚|澳大利亞|澳洲|\bAU\b|Australia|印度|\bIN\b|India|🇭🇰|🇹🇼|🇯🇵|🇸🇬|🇰🇷|🇺🇸|🇨🇦|🇬🇧|🇩🇪|🇫🇷|🇦🇺|🇮🇳|DIRECT-FALLBACK)'
    empty-fallback: DIRECT-FALLBACK
    check: https://www.gstatic.com/generate_204
    expected-status: 200-299
    interval: 2m
    idle-timeout: 15m
    tolerance: 80
    unified-delay: true
    hidden: false
    icon: "https://raw.githubusercontent.com/luestr/IconResource/main/Flag_icon/120px/WW.png"

route:
  preset: custom

  # MRS 规则来自 MetaCubeX/meta-rules-dat 的 meta 分支。
  # path 是跨平台相对缓存路径,首次成功后可离线使用上次有效版本。
  sets:
    ads:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/category-ads-all.mrs"
      path: data/rulesets/ads.mrs
      every: 24h
      via: direct

    private-domain:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/private.mrs"
      path: data/rulesets/private-domain.mrs
      every: 24h
      via: direct

    geoip-private:
      type: ipcidr
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geoip/private.mrs"
      path: data/rulesets/private-ip.mrs
      every: 24h
      via: direct

    cn-domain:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/cn.mrs"
      path: data/rulesets/cn-domain.mrs
      every: 24h
      via: direct

    geoip-cn:
      type: ipcidr
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geoip/cn.mrs"
      path: data/rulesets/cn-ip.mrs
      every: 24h
      via: direct

    apple-cn:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/apple-cn.mrs"
      path: data/rulesets/apple-cn.mrs
      every: 24h
      via: direct

    microsoft-cn:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/microsoft@cn.mrs"
      path: data/rulesets/microsoft-cn.mrs
      every: 24h
      via: direct

    games-cn:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/category-games@cn.mrs"
      path: data/rulesets/games-cn.mrs
      every: 24h
      via: direct

    games-global:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/category-games-!cn.mrs"
      path: data/rulesets/games-global.mrs
      every: 24h
      via: direct

    ai-global:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/category-ai-!cn.mrs"
      path: data/rulesets/ai-global.mrs
      every: 12h
      via: direct

    youtube:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/youtube.mrs"
      path: data/rulesets/youtube.mrs
      every: 24h
      via: direct

    netflix-domain:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/netflix.mrs"
      path: data/rulesets/netflix-domain.mrs
      every: 24h
      via: direct

    netflix-ip:
      type: ipcidr
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geoip/netflix.mrs"
      path: data/rulesets/netflix-ip.mrs
      every: 24h
      via: direct

    disney:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/disney.mrs"
      path: data/rulesets/disney.mrs
      every: 24h
      via: direct

    spotify:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/spotify.mrs"
      path: data/rulesets/spotify.mrs
      every: 24h
      via: direct

    telegram-domain:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/telegram.mrs"
      path: data/rulesets/telegram-domain.mrs
      every: 24h
      via: direct

    telegram-ip:
      type: ipcidr
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geoip/telegram.mrs"
      path: data/rulesets/telegram-ip.mrs
      every: 24h
      via: direct

    github:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/github.mrs"
      path: data/rulesets/github.mrs
      every: 24h
      via: direct

    development:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/category-dev.mrs"
      path: data/rulesets/development.mrs
      every: 24h
      via: direct

    google:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/google.mrs"
      path: data/rulesets/google.mrs
      every: 24h
      via: direct

    tiktok:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/tiktok.mrs"
      path: data/rulesets/tiktok.mrs
      every: 24h
      via: direct

    encrypted-dns:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/category-doh.mrs"
      path: data/rulesets/encrypted-dns.mrs
      every: 24h
      via: direct

    global:
      type: domain
      format: mrs
      url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/geolocation-!cn.mrs"
      path: data/rulesets/global.mrs
      every: 24h
      via: direct

    user-direct:
      type: domain
      payload:
        - localhost
        - +.local
        - +.lan
        - +.home.arpa

  # 第一条命中即停止。精确例外应放在大规则集之前。
  steps:
    - {set: user-direct, outbound: direct}
    - {set: private-domain, outbound: direct}
    - {set: geoip-private, outbound: direct}
    - {set: ads, outbound: block}
    - {process: [wuther-core, wuther-core.exe], outbound: direct}
    - {process: [git, git.exe, ssh, ssh.exe], outbound: 开发服务}
    - {port: [22, 9418], network: tcp, outbound: 开发服务}
    - {set: apple-cn, outbound: direct}
    - {set: microsoft-cn, outbound: direct}
    - {set: games-cn, outbound: direct}
    - {set: ai-global, outbound: 人工智能}
    - {set: youtube, outbound: 流媒体}
    - {set: netflix-domain, outbound: 流媒体}
    - {set: netflix-ip, outbound: 流媒体}
    - {set: disney, outbound: 流媒体}
    - {set: spotify, outbound: 流媒体}
    - {set: telegram-domain, outbound: 即时通信}
    - {set: telegram-ip, outbound: 即时通信}
    - {set: github, outbound: 开发服务}
    - {set: development, outbound: 开发服务}
    - {set: games-global, outbound: 游戏加速}
    - {set: tiktok, outbound: 流媒体}
    - {set: google, outbound: 节点选择}
    - {set: encrypted-dns, outbound: 节点选择}
    - {set: cn-domain, outbound: direct}
    - {set: geoip-cn, outbound: direct}
    - {set: global, outbound: 节点选择}
    - {network: udp, port: [443], proto: quic, outbound: 节点选择}
    - "any -> 节点选择"
  final: 节点选择

resolver:
  mode: normal
  fake: auto
  cache: 10m
  ipv6: true
  ipv6-timeout: 300ms
  use-hosts: true
  use-system-hosts: true
  prefer-h3: false
  listen: 127.0.0.1:1053

  fake-ip-filter:
    - "*.lan"
    - "*.local"
    - "*.home.arpa"
    - "time.*"
    - "ntp.*"
  fake-ip-filter-mode: blacklist

  servers:
    alidns:
      endpoint: https://223.5.5.5/dns-query
      exits: [DIRECT]
      strategy: sequential
      timeout: 3s
      max-parallel: 1

    dnspod:
      endpoint: https://1.12.12.12/dns-query
      exits: [DIRECT]
      strategy: sequential
      timeout: 3s
      max-parallel: 1

    cloudflare:
      endpoint: https://1.1.1.1/dns-query
      exits: [节点选择, 故障转移节点, DIRECT]
      strategy: adaptive
      timeout: 4s
      max-parallel: 2

    google:
      endpoint: tls://8.8.8.8
      exits: [节点选择, 故障转移节点, DIRECT]
      strategy: round-robin
      timeout: 4s
      max-parallel: 2

    quad9:
      endpoint: tls://9.9.9.9:853
      exits: [故障转移节点, 节点选择, DIRECT]
      strategy: sequential
      timeout: 4s
      max-parallel: 1

  groups:
    国内DNS:
      members: [alidns, dnspod]
      strategy: parallel
      timeout: 3s
      max-parallel: 2

    国外DNS:
      members: [cloudflare, google, quad9]
      strategy: adaptive
      timeout: 5s
      max-parallel: 3

    # 节点域名不能依赖尚未建立的代理。这里只使用 IP 字面地址的国内 DoH。
    节点域名DNS:
      members: [alidns, dnspod]
      strategy: sequential
      timeout: 4s
      max-parallel: 1

  # 默认先使用国内 DNS。已知国外域名由下方有序规则直接送往国外 DNS。
  # 未分类域名若返回非中国大陆地址,再由 fallback-filter 切换到国外 DNS。
  nameserver: [国内DNS]
  fallback: [国外DNS]
  default-nameserver:
    - udp://223.5.5.5
    - udp://1.12.12.12
  proxy-server-nameserver: [节点域名DNS]
  direct-nameserver: [国内DNS]
  direct-nameserver-follow-policy: true

  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - 0.0.0.0/8
      - 127.0.0.0/8
      - 198.18.0.0/15
      - 240.0.0.0/4
    domain:
      - +.google.com
      - +.googleapis.com
      - +.gstatic.com
      - +.youtube.com
      - +.facebook.com
      - +.twitter.com
      - +.x.com
      - +.github.com
      - +.openai.com
      - +.chatgpt.com
      - +.anthropic.com
      - +.claude.ai
      - +.telegram.org

  # DNS 规则与流量路由使用相同的 MRS 集合。广告必须排在所有 DNS 路由之前。
  rules:
    - "set:ads -> nxdomain"
    - "set:user-direct -> route:国内DNS?nocache"
    - "set:private-domain -> route:国内DNS?nocache"
    - "set:cn-domain -> route:国内DNS?strategy=parallel"
    - "set:apple-cn -> route:国内DNS?strategy=parallel"
    - "set:microsoft-cn -> route:国内DNS?strategy=parallel"
    - "set:games-cn -> route:国内DNS?strategy=parallel"
    - "set:ai-global -> route:国外DNS?strategy=adaptive"
    - "set:youtube -> route:国外DNS?strategy=adaptive"
    - "set:netflix-domain -> route:国外DNS?strategy=adaptive"
    - "set:disney -> route:国外DNS?strategy=adaptive"
    - "set:spotify -> route:国外DNS?strategy=adaptive"
    - "set:telegram-domain -> route:国外DNS?strategy=adaptive"
    - "set:github -> route:国外DNS?strategy=adaptive"
    - "set:development -> route:国外DNS?strategy=adaptive"
    - "set:games-global -> route:国外DNS?strategy=adaptive"
    - "set:tiktok -> route:国外DNS?strategy=adaptive"
    - "set:google -> route:国外DNS?strategy=adaptive"
    - "set:encrypted-dns -> route:国外DNS?strategy=adaptive"
    - "set:global -> route:国外DNS?strategy=adaptive"
    - "any -> route:default?strategy=parallel"

smart:
  on: true
  goal: balanced
  learn: 10m
  sticky: site
  explain: true

find-process-mode: strict

ui:
  on: true
  dashboard: metacubexd
  api:
    native: true
    clash_compat: true
  cors: []

# 默认不接管 Tailscale。需要组网时再启用,避免要求宿主预装 daemon。
mesh:
  tailscale:
    on: false
    mode: off
    keep_tailnet_direct: true
    expose_as_node: false

这份配置可以直接启动,默认远程订阅只提供 Direct 演示节点。把一个订阅 URL 换成 自己的地址后,全部策略组会自动使用订阅节点。使用方法、规则顺序、平台权限和兜底 行为见官方多平台完整配置

Desktop

examples/desktop.yaml
version: 1
profile: desktop
name: "minimal-desktop"

# 模板 A:最小配置,只需替换订阅链接即可使用。
feeds:
  my_airport: "https://example.com/your-subscription"

# 内核会自动补全:
#   listen.local = 7890, listen.panel = 9090, share = false
#   groups.main.choose = smart (use 所有 feeds + nodes)
#   route.preset = cn_smart
#   resolver.mode = smart
#   smart.on = true, ui.on = true

Router

examples/router.yaml
version: 1
profile: router
name: "transparent-gateway"

listen:
  local: 7890
  panel: 9090
  # share: home 会把 Mixed/API 绑到 0.0.0.0;非本机 API 必须配置 ui.secret。
  share: home

ui:
  on: true
  # 部署前请换成足够长的随机串;空 secret + 非本机 panel 会在 check/run 阶段被拒绝。
  secret: "change-me-router-panel-secret"

feeds:
  my_airport: "https://example.com/sub"

groups:
  main:
    choose: smart
    use: [my_airport]
    prefer: [HK, JP, SG, TW]

capture:
  on: true
  method: auto
  traffic: lan
  resolver: hijack
  exclude:
    cidr:
      - "10.0.0.0/8"
      - "172.16.0.0/12"
      - "192.168.0.0/16"
      - "100.64.0.0/10"
      - "fd7a:115c:a1e0::/48"

route:
  preset: cn_smart
  final: main

resolver:
  mode: smart
  fake: auto

mesh:
  tailscale:
    on: true
    keep_tailnet_direct: true

Android VpnService

examples/android.yaml
# =============================================================================
# WutherCore —— Android 完整可用配置(开箱即用)
#
# 设计原则:
#   * **DNS 零依赖启动**:upstream 全部 IP 字面 DoH/DoT,避免 "解析 DNS server
#     hostname → 又需要 DNS" 的鸡生蛋问题;TUN 启动后即生效。
#   * **节点 / 订阅缺失时仍能上网**:route preset 走 cn_smart,国内流量直连,
#     国外流量退到 main → smart 自动择优;内置 direct-fallback 防止 main 空组死锁。
#   * **TUN 自动排除 DNS 服务器 IP / 自身 IP / 私网**:DNS 不会回环 TUN。
#
# 只需改 3 处即可投产:
#   1. feeds.primary.url      — 你的订阅链接(必改)
#   2. ui.secret              — Dashboard 鉴权 token(必改)
#   3. nodes[]                — 可选:手工补几个固定节点;订阅稳定后可删掉直连兜底
#
# 启动:wuthercore run examples/android.yaml
# 在宿主 App:
#   1. System.loadLibrary("wuthercore")
#   2. cfg = VpnBridge.vpnServiceConfigJson(configPath)
#   3. 把 cfg.addresses / cfg.routes / cfg.dns_servers / cfg.*_applications
#      逐项写入 VpnService.Builder,再 establish() + detachFd()
#   4. setVpnService(this) + setVpnFd(fd) + nativeStart()
# 注意:Android VpnService 是三层 TUN,不是 bridge;Builder 没有 addRoute/addDnsServer
# 就不会有真实应用流量进入 native。setVpnService(this) 用于 native 出站 socket
# 调用 VpnService.protect(fd),否则代理节点连接会被自己的 VPN 再次捕获。
# =============================================================================

version: 1
profile: mobile          # mobile = Android / iOS(与 desktop / router / server 区分)
name: "android-daily"

# ---------------------------------------------------------------------------
# 0. log —— 日志控制
#
#    level 控制全局日志等级;filter 可精确覆盖模块等级。下面默认保留 TUN/路由
#    调试日志,便于排查“无流量进入 TUN / DNS 劫持 / root 路由”。
#    文件日志会自动创建父目录。
# ---------------------------------------------------------------------------
log:
  on: true
  level: info
  filter: "info,capture::tun=debug,capture::traffic=debug,capture::dispatch=debug,capture::accept=debug,capture::udp=debug,capture::dns=debug,capture::stack=debug,capture::linux::tun=debug,capture::linux::cmd=debug,capture::tproxy=debug"
  stdout: true
  format: text
  file:
    on: true
    path: "data/logs/wuthercore.log"

# ---------------------------------------------------------------------------
# 1. listen —— 本地监听
# ---------------------------------------------------------------------------
listen:
  local:
    host: 127.0.0.1
    port: 7890           # Mixed (HTTP + SOCKS5 + UDP)
    udp: true
  panel: 9090            # /v1 + Clash 兼容 API(dashboard 连这个端口)
  share: false           # 禁止局域网分享(手机基本不需要)
  auth: []               # 仅本地,不开认证

# ---------------------------------------------------------------------------
# 2. feeds —— 订阅源(机场)
#    URL **必须**替换为你自己的订阅;example.com 拉不到任何节点。
#    via: "direct" 让订阅请求绕过自己的 TUN,避免循环。
# ---------------------------------------------------------------------------
feeds:
  primary:
    url: "https://REPLACE-WITH-YOUR-AIRPORT.example.com/api/v1/clients/sub?token=YOUR_TOKEN&format=clash"
    every: 6h
    via: "direct"
    keep:
      name_has: ["香港", "台湾", "日本", "新加坡", "美国"]
    drop:
      name_has: ["官网", "剩余", "过期", "回国", "网址"]
    rename:
      add_prefix: "[A] "
      remove: ["[Ⓜ]", "↓", "↑", "倍率"]

# ---------------------------------------------------------------------------
# 3. nodes —— 手动节点(与订阅并存)
#    direct-fallback 是订阅失败时的直连兜底,保证 main 组不会空。
#    生产使用请补真实代理节点;如不想兜底直连,可删除 direct-fallback。
# ---------------------------------------------------------------------------
nodes:
  - "direct://0.0.0.0:0#direct-fallback"
# 示例(取消注释 + 替换):
# - "ss://YWVzLTI1Ni1nY206cGFzc3dvcmQ@1.2.3.4:8388#自建-备用"
# - "trojan://password@example.com:443?sni=example.com#Trojan-1"
# - "vmess://eyJ2IjoiMiIsInBzIjoiVk1lc3MtMSIsImFkZCI6ImV4YW1wbGUuY29tIiwicG9ydCI6IjQ0MyIsImlkIjoiYWFhYS1iYmJiLWNjY2MtZGRkZC1lZWVlZmZmZmdnZ2giLCJzY3kiOiJhdXRvIiwibmV0Ijoid3MiLCJob3N0IjoiZXhhbXBsZS5jb20iLCJwYXRoIjoiL3dzIiwidGxzIjoidGxzIn0="

# ---------------------------------------------------------------------------
# 4. groups —— 分组
#    main 选 smart:订阅一拉到节点立即自动选最优,无需手动 PUT /proxies/main。
# ---------------------------------------------------------------------------
groups:
  # 主出口 —— smart 自动择优(按 URLTest 延迟 + 历史成功率)
  main:
    choose: smart
    use: ["primary", "nodes"]
    avoid: ["direct-fallback"]      # 订阅有可用节点时优先不用直连兜底
    sticky: "site"             # 同 eTLD+1 粘节点
    check: "https://www.gstatic.com/generate_204"

  # 强制低延迟(流媒体 / 实时通信)
  streaming-fast:
    choose: fast
    use: ["primary", "nodes"]
    prefer: ["[A] 香港", "[A] 日本", "[A] 新加坡"]
    check: "https://www.gstatic.com/generate_204"

  # 故障转移(AI / 长连接,稳定性优先)
  ai-stable:
    choose: stable
    use: ["primary", "nodes"]
    prefer: ["[A] 美国", "[A] 日本"]
    avoid: ["GFW", "封锁", "免费", "试用"]
    check: "https://chatgpt.com/"

  # 负载均衡(大流量下载)
  bulk-spread:
    choose: spread
    use: ["primary", "nodes"]
    prefer: ["[A] 香港", "[A] 日本"]

# ---------------------------------------------------------------------------
# 5. resolver —— DNS(防泄漏 + Fake-IP)
#
#    ⚠️ 关键设计:所有 upstream 都用 IP 字面,避免"解析 DNS server hostname →
#    又需要 DNS"的鸡生蛋。TUN 一启动就能查询,不卡 bootstrap。
#
#    mode 含义:
#      system  : 走 Android 系统 DNS(最稳;适合首次试运行)
#      secure  : 全部 DoH/DoT,强制加密
#      smart   : mihomo 风格 nameserver + fallback + nameserver-policy
#      fake    : Fake-IP 模式(capture 启用 hijack 时由 fake-DNS 接管)
# ---------------------------------------------------------------------------
resolver:
  mode: smart                  # mihomo smart DNS:主 DNS + fallback + policy
  fake: auto                   # capture 启用时用 Fake-IP;否则真 IP
  cache: 1h
  servers:
    # 国内(IP 直连 DoH —— 不需要再解析 dns.alidns.com)
    ali:        "https://223.5.5.5/dns-query"
    alidns2:    "https://223.6.6.6/dns-query"
    tencent:    "https://119.29.29.29/dns-query"
    dnspod:     "https://1.12.12.12/dns-query"
    # 国外(IP 直连)
    cloudflare:  "https://1.1.1.1/dns-query"
    cloudflare2: "https://1.0.0.1/dns-query"
    google:      "https://8.8.8.8/dns-query"
    google2:     "https://8.8.4.4/dns-query"
    quad9:      "tls://9.9.9.9:853"

  # mihomo 对齐:主 nameserver 先查;命中 fallback-filter 时再使用 fallback。
  nameserver: [ali, alidns2, tencent, dnspod]
  fallback: [cloudflare, cloudflare2, google, google2, quad9]
  default-nameserver: ["223.5.5.5", "1.1.1.1"]
  proxy-server-nameserver: [cloudflare, google, ali]

  nameserver-policy:
    # 使用 route.sets 中真实加载的 MRS 规则集;没有规则集时不会伪造命中。
    "rule-set:cn-domain": [ali, alidns2, tencent, dnspod]
    "rule-set:openai,claude,youtube,netflix": [cloudflare, google, quad9]

  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - "240.0.0.0/4"
    domain:
      - "+.google.com"
      - "+.gstatic.com"
      - "+.googleapis.com"
      - "+.facebook.com"
      - "+.youtube.com"
      - "+.twitter.com"
      - "+.x.com"
      - "+.github.com"
      - "+.openai.com"
      - "+.chatgpt.com"
    geosite:
      - gfw

# ---------------------------------------------------------------------------
# 6. capture —— TUN / VpnService 透明接管
#
#    A. 未 root + 宿主 App(VpnService)是本文件的默认配置
#    B. root TUN 完整配置见 examples/advanced/android-root-tun.yaml
#    C. root TPROXY 完整配置见 examples/advanced/android-root-tproxy.yaml
#    D. root REDIRECT 完整配置见 examples/advanced/android-root-redirect.yaml
#    VpnService 不是桥接网卡;必须使用 VpnBridge.vpnServiceConfigJson(configPath)
#    返回的 routes/dns 配置 Builder,native 侧只负责读写 establish() 后的 TUN fd。
# ---------------------------------------------------------------------------
capture:
  on: true
  method: virtual_nic          # virtual_nic = TUN
  traffic: system              # 接管全机
  resolver: hijack             # 把 53 端口 DNS 劫持到本机 fake-dns(防泄漏)
  stack: mixed                 # mixed = TCP gvisor (兼容性最好) + UDP system
  mtu: 1500
  offload: true
  exclude:
    cidr:
      - "100.64.0.0/10"        # CGNAT / Tailscale
      - "fd7a:115c:a1e0::/48"  # Tailscale ULA
    process: ["tailscaled"]    # 进程级排除(root 模式生效)

  tun:
    # ---- 接口与寻址 ----
    interface_name: "rpktun0"
    address:
      - "172.19.0.1/30"
      - "fdfe:dcba:9876::1/126"

    # ---- 路由接管 ----
    auto_route: true
    iproute2_table_index: 2024
    iproute2_rule_index:  9100
    auto_redirect: false        # Android 当前明确不支持;仅 Linux root-managed TUN 可按专门文档启用
    strict_route: false         # 严格防泄漏会切断 LAN,移动端关
    route_address: []           # 空 = 全部走 TUN

    # ⚠️ 关键:把 DNS 服务器 IP 排除出 TUN,否则 DNS 自循环
    route_exclude_address:
      # 本机 / 私网
      - "127.0.0.0/8"
      - "::1/128"
      - "192.168.0.0/16"
      - "10.0.0.0/8"
      - "172.16.0.0/12"
      - "169.254.0.0/16"        # link-local
      - "fc00::/7"
      - "fe80::/10"
      # DNS upstream IP(与 resolver.servers 完全一致 —— 这些 IP 不能走 TUN)
      - "223.5.5.5/32"
      - "223.6.6.6/32"
      - "119.29.29.29/32"
      - "1.12.12.12/32"
      - "1.1.1.1/32"
      - "1.0.0.1/32"
      - "8.8.8.8/32"
      - "8.8.4.4/32"
      - "9.9.9.9/32"
      # Android Captive Portal(避免连不上 WiFi 时被 TUN 截)
      - "203.0.113.0/24"

    route_address_set: []                     # 引用 route.sets 的动态 IP 集
    route_exclude_address_set:
      - "geoip-cn"                            # ruleset 拉完后国内 IP 不再走 TUN

    # ---- NAT / 性能 ----
    endpoint_independent_nat: true            # QUIC / WebRTC / 游戏强烈建议开
    udp_timeout: 5m
    exclude_mptcp: false
    loopback_address:
      - "127.0.0.1"
      - "::1"

    # ---- 接口过滤 ----
    include_interface: []
    exclude_interface: []

    # ---- UID 过滤(Linux/Android)----
    # 仅接管"主用户"普通 app(10000–19999),并排除 system / Tailscale:
    # include_uid_range: ["10000:99999"]
    # exclude_uid: [1000]                      # 1000=system;root 模式可加 0
    include_uid: []
    include_uid_range: []
    exclude_uid: []
    exclude_uid_range: []

    # ---- GID 过滤(Linux/Android)----
    # Android 常见 GID:3003=INET / 3004=NET_RAW / 3005=NET_ADMIN
    include_gid: []
    include_gid_range: []
    exclude_gid: []
    exclude_gid_range: []

    # ---- Android 专属 ----
    include_android_user: [0]                 # 仅主用户(10/11=工作资料/分身)
    include_package: []                       # 白名单包名(空 = 全部)
    exclude_package:
      - "com.android.captiveportallogin"      # WiFi 强制登录页
      - "com.google.android.gms"              # Google Play 服务(DRM/支付)
      - "com.google.android.gsf"              # Google 服务框架
      - "com.android.vending"                 # Google Play 商店
      # 需要更多排除?常见:网银、运营商充值、打车、外卖

    # ---- LAN MAC 过滤(路由器场景,手机一般空)----
    include_mac_address: []
    exclude_mac_address: []

    # ---- 平台桥:把系统 HTTP proxy 也指到 7890 ----
    # 少数 app 不读 TUN 路由表但读系统 proxy 设置,覆盖到这种 corner case。
    platform:
      http_proxy:
        enabled: true
        server: "127.0.0.1"
        server_port: 7890
        bypass_domain:
          - "localhost"
          - "*.lan"
          - "*.local"

# -----------------------------------------------------------------------------
# 6.B Android root 模式
# -----------------------------------------------------------------------------
# Android root 支持三条独立数据面:
#   1. method=virtual_nic,native 直接打开 /dev/net/tun,支持 TCP 与 UDP
#   2. method=tproxy,使用 iptables/ip6tables 和策略路由,支持 TCP 与 UDP
#   3. method=redirect,使用 nftables NAT,只支持 TCP
#
# tun.auto_redirect 仍然只属于 Linux root-managed TUN,不是 Android root 开关。
# Android root daemon 必须由 root shell、KernelSU 或 Magisk service 启动整个进程。
# native 内部的 su -c id 只做权限探测,不会把普通 App 进程变成 root。
#
# 完整手册:docs/manual/android.md

# ---------------------------------------------------------------------------
# 7. route —— 分流规则
#    步骤自上而下匹配;命中后按 -> 后的目标决策(分组名 / direct / block)。
#    sets: 引用外部规则集(mihomo / sing-box / 自定义 payload)。
#    ⚠️ 首启动 ruleset 还在下载(10s 内),未生效的 set 规则全部 fall through 到下一条。
# ---------------------------------------------------------------------------
route:
  preset: "cn_smart"          # 内置预设:自动添加常见直连
  final: "main"               # 兜底出口

  steps:
    # --- 1. 必须直连 ---
    - "process: wuther-core,wuthercore,proxy-core -> direct"   # 当前与旧版进程名
    - "ip: 100.64.0.0/10 -> direct"              # Tailscale CGNAT
    - "ip: 192.168.0.0/16 -> direct"             # 家庭 LAN
    - "ip: 10.0.0.0/8 -> direct"
    - "ip: 172.16.0.0/12 -> direct"
    - "ip: 169.254.0.0/16 -> direct"             # link-local
    - "ip: fc00::/7 -> direct"
    - "ip: fe80::/10 -> direct"
    - "domain-suffix: lan,local,arpa -> direct"

    # --- 2. 国内(IP + 域名双重命中,先到先得)---
    - "set:geoip-cn -> direct"
    - "set:cn-domain -> direct"
    - "set:geoip-private -> direct"

    # --- 3. 广告 / 隐私拦截 ---
    - "set:adblock -> block"
    - "set:privacy-tracker -> block"

    # --- 4. 流媒体 / AI ---
    - "set:netflix -> streaming-fast"
    - "set:youtube -> streaming-fast"
    - "set:openai  -> ai-stable"
    - "set:claude  -> ai-stable"

    # --- 5. 默认:海外走 main(smart 自动择优)---
    - "default -> main"

  sets:
    # —— 必备:geoip-cn 决定国内/海外的最大分流权重
    geoip-cn:
      type: ipcidr
      format: mrs
      url: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-cn.mrs"
      every: 24h
      via: "direct"

    geoip-private:
      type: ipcidr
      format: mrs
      url: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-private.mrs"
      every: 7d
      via: "direct"

    cn-domain:
      type: domain
      format: mrs
      url: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite-cn.mrs"
      every: 24h
      via: "direct"

    # —— 可选:流媒体(首启动慢一些没节点也无害)
    netflix:
      type: domain
      format: mrs
      url: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite-netflix.mrs"
      every: 24h
      via: "direct"

    youtube:
      type: domain
      format: mrs
      url: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite-youtube.mrs"
      every: 24h
      via: "direct"

    openai:
      type: domain
      format: mrs
      url: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite-openai.mrs"
      every: 24h
      via: "direct"

    claude:
      type: domain
      format: mrs
      url: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite-anthropic.mrs"
      every: 24h
      via: "direct"

    adblock:
      type: domain
      format: mrs
      url: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite-category-ads-all.mrs"
      every: 24h
      via: "direct"

    privacy-tracker:
      type: domain
      format: mrs
      url: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite-tracker.mrs"
      every: 24h
      via: "direct"

# ---------------------------------------------------------------------------
# 8. smart —— 智能择优学习
# ---------------------------------------------------------------------------
smart:
  on: true
  goal: balanced            # balanced / speed / stability / low_cost / privacy
  learn: 14d                # 学习窗口;移动端建议 7-14d
  sticky: site              # off / site / session
  explain: true             # /v1/smart/why 返回选择原因

# ---------------------------------------------------------------------------
# 9. ui —— Dashboard / API
#    ⚠️ secret 必填,否则任何能访问 9090 的进程都能改配置。
# ---------------------------------------------------------------------------
ui:
  on: true
  secret: "REPLACE_ME_DASHBOARD_TOKEN"
  dashboard: "auto"
  api:
    native: true            # /v1/* 原生 API(含 /v1/capture/state)
    clash_compat: true      # Yacd / metacubexd / Razord 直接连
  cors: []                  # CORS 在 server.rs 里已开 AllowAny + PNA,不需重复

# ---------------------------------------------------------------------------
# 10. mesh —— Tailscale 协同(Android 非必需,可整段删掉)
# ---------------------------------------------------------------------------
mesh:
  tailscale:
    on: true
    mode: auto              # auto / localapi / userspace / tsnet / off
    keep_tailnet_direct: true
    expose_as_node: false

Android root TUN

examples/advanced/android-root-tun.yaml
version: 1
profile: mobile
name: android-root-tun

listen:
  local:
    host: 127.0.0.1
    port: 7890
    udp: true
  share: false

nodes:
  - name: upstream
    protocol: socks5
    address: 127.0.0.1:1080
    network:
      udp: true

groups:
  main:
    choose: manual
    use: [nodes]

route:
  preset: custom
  steps:
    - "ip:127.0.0.0/8 -> direct"
    - "ip:10.0.0.0/8 -> direct"
    - "ip:172.16.0.0/12 -> direct"
    - "ip:192.168.0.0/16 -> direct"
  final: main

resolver:
  mode: secure
  fake: off
  servers:
    bootstrap: https://223.5.5.5/dns-query
  nameserver: [bootstrap]
  proxy-server-nameserver: [bootstrap]
  direct-nameserver: [bootstrap]

capture:
  on: true
  method: virtual_nic
  traffic: system
  resolver: hijack
  stack: mixed
  mtu: 1400
  offload: true
  exclude:
    cidr:
      - 127.0.0.0/8
      - ::1/128
  tun:
    interface_name: rpktun0
    address:
      - 172.19.0.1/30
      - fdfe:dcba:9876::1/126
    inet6: true
    auto_route: true
    auto_redirect: false
    strict_route: false
    iproute2_table_index: 2024
    iproute2_rule_index: 9100
    route_exclude_address:
      - 127.0.0.0/8
      - ::1/128
      - 10.0.0.0/8
      - 172.16.0.0/12
      - 192.168.0.0/16
      - 223.5.5.5/32
    endpoint_independent_nat: true
    udp_timeout: 5m
    include_android_user: [0]
    exclude_package:
      - com.android.captiveportallogin

ui:
  on: false

Android root TPROXY

examples/advanced/android-root-tproxy.yaml
version: 1
profile: mobile
name: android-root-tproxy

listen:
  local:
    host: 127.0.0.1
    port: 7890
    udp: true
  share: false

nodes:
  - name: upstream
    protocol: socks5
    address: 127.0.0.1:1080
    network:
      udp: true

groups:
  main:
    choose: manual
    use: [nodes]

route:
  preset: custom
  steps:
    - "ip:127.0.0.0/8 -> direct"
    - "ip:10.0.0.0/8 -> direct"
    - "ip:172.16.0.0/12 -> direct"
    - "ip:192.168.0.0/16 -> direct"
  final: main

resolver:
  mode: secure
  fake: off
  servers:
    bootstrap: https://223.5.5.5/dns-query
  nameserver: [bootstrap]
  proxy-server-nameserver: [bootstrap]
  direct-nameserver: [bootstrap]

capture:
  on: true
  method: tproxy
  traffic: system
  resolver: hijack
  stack: mixed
  exclude:
    cidr:
      - 127.0.0.0/8
      - ::1/128
      - 10.0.0.0/8
      - 172.16.0.0/12
      - 192.168.0.0/16
      - 223.5.5.5/32
  tun:
    inet6: true
    auto_redirect: false
    route_exclude_address:
      - 127.0.0.0/8
      - ::1/128
      - 223.5.5.5/32
    auto_redirect_output_mark: "0x2024"

ui:
  on: false

Android root REDIRECT

examples/advanced/android-root-redirect.yaml
version: 1
profile: mobile
name: android-root-redirect

listen:
  local:
    host: 127.0.0.1
    port: 7890
    udp: true
  share: false

nodes:
  - name: upstream
    protocol: socks5
    address: 127.0.0.1:1080

groups:
  main:
    choose: manual
    use: [nodes]

route:
  preset: custom
  steps:
    - "ip:127.0.0.0/8 -> direct"
    - "ip:10.0.0.0/8 -> direct"
    - "ip:172.16.0.0/12 -> direct"
    - "ip:192.168.0.0/16 -> direct"
  final: main

resolver:
  mode: secure
  fake: off
  servers:
    bootstrap: https://223.5.5.5/dns-query
  nameserver: [bootstrap]
  proxy-server-nameserver: [bootstrap]
  direct-nameserver: [bootstrap]

capture:
  on: true
  method: redirect
  traffic: system
  resolver: off
  stack: system
  exclude:
    cidr:
      - 127.0.0.0/8
      - ::1/128
      - 10.0.0.0/8
      - 172.16.0.0/12
      - 192.168.0.0/16
      - 223.5.5.5/32
  tun:
    inet6: true
    auto_redirect: false
    route_exclude_address:
      - 127.0.0.0/8
      - ::1/128
      - 223.5.5.5/32
    include_android_user: [0]
    exclude_uid:
      - 1000

ui:
  on: false

四种 Android 数据面的权限要求和运行边界见 Android 完整部署

使用流程

  1. 复制示例到仓库外或改名为 config.yaml
  2. 替换订阅地址、节点凭据、密钥与域名。
  3. 运行 wuther-core check config.yaml
  4. 使用 wuther-core explain config.yaml 审计最终计划。
  5. 先验证普通代理,再启用 TUN/TPROXY/REDIRECT。

字段语义、默认值和迁移规则见配置指南