家用 SubConverter-Extended:redir-host、IPv6 与多客户端订阅整理
本文由一次真实的家庭网络部署记录整理而来。文中的公网域名、订阅 token、NAS 绝对路径、公司域名和后端随机路径均已脱敏,请按自己的环境替换。
背景
家里有多台设备需要使用 Clash / Mihomo:路由器上跑 OpenWrt + ShellCrash,电脑上可能还会单独跑 Clash 客户端。过去每台客户端各自维护订阅和规则,时间久了以后很容易出现几类问题:
- 不同客户端规则不一致,排障时很难确认到底命中了哪套策略。
- 开发场景不喜欢
fake-ip,因为 DNS 查询结果会变成虚拟地址,容易误判服务真实连通性。 - IPv6 开启以后,国内 IPv6、海外 IPv6、内网 IPv6 的处理逻辑容易混在一起。
- 企业 VPN / aTrust 这类工具和本机 Clash 共存时,可能会遇到 TUN、fake-ip 网段或进程分流冲突。
这次的目标是把 NAS 上的 SubConverter-Extended 做成统一配置中心:客户端只订阅一个转换后的地址,真正的基础配置、规则碎片、节点聚合都在服务端维护。
最终架构
整体拆成三层:
原始机场订阅 / 多个订阅源
-> Sub-Store:聚合、过滤、输出固定 share 地址
-> SubConverter-Extended:生成 Clash / Mihomo 配置
-> OpenWrt / ShellCrash / 桌面 Clash 客户端
服务上保留两个 SubConverter-Extended 实例:
home 实例
用于 OpenWrt / ShellCrash
redir-host
IPv6 开启
内网和国内 IPv6 优先直连
laptop / work 实例
用于本机 Clash + 企业 VPN 共存
fake-ip
避开企业 VPN 常用网段
额外加入企业 VPN 可视化策略组
示例网络拓扑如下:
主网关
10.0.0.1/24
旁路由
10.0.0.3/24
OpenWrt + ShellCrash + SmartDNS + Mihomo
NAS
10.0.2.1/24
Sub-Store + SubConverter-Extended
客户端
DNS -> 10.0.0.3
DNS 链路可以理解为:
客户端
-> SmartDNS
-> Mihomo DNS
-> ShellCrash 覆写后的加密 DNS 上游
为什么家用场景选择 redir-host
家用路由器上的 Mihomo 使用 redir-host:
ipv6: true
dns:
enable: true
ipv6: true
enhanced-mode: redir-host
主要原因是开发和内网服务调试更直观。fake-ip 的优点是适合代理分流和减少 DNS 污染影响,但它会让客户端看到类似 198.18.x.x 的虚拟地址。对日常使用这通常没问题,但如果经常调试内网服务、容器服务、域名解析、IPv6 连通性,虚拟地址会干扰判断。
在路由器统一接管的场景下,redir-host 加上清晰的规则顺序更容易维护。
IPv6 的处理逻辑
这套配置没有简单地把所有 IPv6 都直连,也没有粗暴地全部代理,而是拆成三类。
第一类是本地 IPv6,固定直连:
ruleset=DIRECT,[]IP-CIDR6,::1/128,no-resolve
ruleset=DIRECT,[]IP-CIDR6,fc00::/7,no-resolve
ruleset=DIRECT,[]IP-CIDR6,fe80::/10,no-resolve
ruleset=DIRECT,[]IP-CIDR6,ff00::/8,no-resolve
第二类是国内 IPv6,使用规则集直连:
ruleset=🎯 全球直连,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/ChinaIpV6.list
第三类是剩余公网 IPv6,交给一个可以手动切换的策略组:
ruleset=🌐 IPv6策略,[]IP-CIDR6,2000::/3,no-resolve
2000::/3 是全球单播 IPv6 范围。关键点在于规则顺序:国内 IPv6 列表必须放在 2000::/3 之前,这样国内 IPv6 会先命中直连,剩下未命中的公网 IPv6 才进入 🌐 IPv6策略。
策略组可以这样设计:
🌐 IPv6策略
-> 🌐 IPv6自动
-> DIRECT
-> 🚀 节点选择
🌐 IPv6自动
使用 IPv6-only 探针 URL 测试节点可用性
探针建议使用只配置 AAAA、不配置 A 记录的域名,例如:
http://ipv6-probe.example.com/generate_204
部署后可以用下面的方式验证:
dig A ipv6-probe.example.com
dig AAAA ipv6-probe.example.com
curl -6 http://ipv6-probe.example.com/generate_204
curl -4 http://ipv6-probe.example.com/generate_204
期望结果是:AAAA 有结果,A 无结果,curl -6 返回 204,curl -4 失败或无法解析。
内网直连不要只写主机地址
如果 NAS、旁路由、主网关分布在多个内网网段,建议按网段写直连,而不是只写某几个 /32 主机地址。
示例:
ruleset=DIRECT,[]IP-CIDR,10.0.0.0/24,no-resolve
ruleset=DIRECT,[]IP-CIDR,10.0.2.0/24,no-resolve
这样访问 NAS 服务、Docker 暴露端口、旁路由管理页、内网 DNS 和其他局域网服务时,不会因为漏掉某个 IP 而被错误送进代理链路。
基于 ACL4SSR Full MultiMode 做母版
自维护大段分组很费时间,所以这次直接使用 ACL4SSR 官方的 Full_MultiMode 作为母版:
https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_MultiMode.ini
它已经包含常用策略组,例如:
💬 Ai平台
🇭🇰 香港节点
🇨🇳 台湾节点
🇸🇬 狮城节点
🇯🇵 日本节点
🇺🇲 美国节点
🇰🇷 韩国节点
🔯 故障转移
🔮 负载均衡
📹 油管视频
🎥 奈飞视频
Ⓜ️ 微软Bing
Ⓜ️ 微软云盘
🎮 游戏平台
AI 服务需要指定可用地区时,直接在客户端把 💬 Ai平台 切到对应地区节点组即可,不需要另写一整套 AI 分流规则。
Docker Compose 的组织方式
SubConverter-Extended 不建议直接把整个 /base 目录挂载进去。更稳妥的方式是只挂载自己改过的几个文件,避免覆盖镜像自带模板、规则和资源。
示例:
services:
subconverter-home:
image: aethersailor/subconverter-extended:latest
container_name: subconverter-home
ports:
- "25500:25500/tcp"
restart: unless-stopped
environment:
TZ: Asia/Shanghai
volumes:
- "/srv/docker/subconverter/base/pref.toml:/base/pref.toml:ro"
- "/srv/docker/subconverter/base/config/home-redir-ipv6.ini:/base/config/home-redir-ipv6.ini:ro"
- "/srv/docker/subconverter/base/base/home-redir-ipv6.yaml:/base/base/home-redir-ipv6.yaml:ro"
subconverter-work:
image: aethersailor/subconverter-extended:latest
container_name: subconverter-work
ports:
- "25501:25500/tcp"
restart: unless-stopped
environment:
TZ: Asia/Shanghai
volumes:
- "/srv/docker/subconverter/work/pref.toml:/base/pref.toml:ro"
- "/srv/docker/subconverter/base/config/work-vpn.ini:/base/config/work-vpn.ini:ro"
- "/srv/docker/subconverter/base/base/work-vpn.yaml:/base/base/work-vpn.yaml:ro"
两个实例通过不同的 pref.toml 指向不同默认配置:
default_external_config = "config/home-redir-ipv6.ini"
profile = "public"
工作场景实例:
default_external_config = "config/work-vpn.ini"
managed_config_prefix = "http://127.0.0.1:25501"
profile = "public"
这里继续保持 profile = "public",不通过请求参数暴露任意 config= 文件读取能力。不同场景靠不同实例的默认配置区分。
用 Sub-Store 管理原始订阅
Sub-Store 用来管理多个原始订阅、聚合、过滤,并输出一个固定 share 地址。它不替代 SubConverter,而是负责把节点源整理好,再交给 SubConverter 生成最终配置。
示例:
services:
sub-store:
image: xream/sub-store:latest
container_name: sub-store
ports:
- "3001:3001/tcp"
restart: unless-stopped
environment:
TZ: Asia/Shanghai
NODE_OPTIONS: "--dns-result-order=ipv4first"
SUB_STORE_FRONTEND_BACKEND_PATH: "/<RANDOM_BACKEND_PATH>"
SUB_STORE_DATA_BASE_PATH: "/opt/app/data"
dns:
- 223.5.5.5
- 119.29.29.29
- 1.1.1.1
volumes:
- "/srv/docker/sub-store/data:/opt/app/data"
这里给 Sub-Store 单独指定 DNS,是为了避免旁路由或 ShellCrash 关闭时,NAS 的系统 DNS 指向不可用内网地址,导致 Sub-Store 无法解析订阅域名。
Sub-Store 会保存原始订阅数据。如果要公网反代,至少要做到:
- 后台和 API 不直接暴露公网。
- share 链路只开放只读路径,例如
/share/。 - token 不写进公开文章、截图或仓库。
- 反代入口加 Basic Auth、访问控制或只允许 VPN 访问。
provider URL 必须让最终客户端能访问
这是最容易踩坑的一点。
SubConverter 生成的最终 Clash / Mihomo 配置里会包含 proxy-providers.url。这个 URL 不是 SubConverter 自己拉取,而是最终客户端拉取。
所以,如果 OpenWrt / Mihomo 客户端不在 Docker 网络里,就不能写:
http://sub-store:3001/share/col/<COLLECTION>?token=<TOKEN>
应该写成客户端能访问的地址,例如内网:
http://10.0.2.1:3001/share/col/<COLLECTION>?token=<SUB_STORE_SHARE_TOKEN>
如果是公网笔记本,则要写公网只读 share 入口:
https://substore-share.example.com/share/col/<COLLECTION>?token=<SUB_STORE_SHARE_TOKEN>
这一点和 Docker Compose 内部服务名无关。服务名只对容器互访有效,对最终的 OpenWrt、ShellCrash、Clash 客户端没有意义。
给客户端准备短订阅地址
长订阅地址通常包含 target、filename、url、exclude 等参数,不适合手动维护。可以在 SubConverter 里配置短路径别名,把这些参数固化进去。
最终客户端只需要使用:
http://10.0.2.1:25500/HomeClash
https://sub.example.com/HomeClash
https://sub-work.example.com/HomeClash
短路径内部再指向真实转换参数:
/sub?target=clash&filename=HomeClash&url=<ENCODED_PROVIDER_URL>&exclude=<ENCODED_EXCLUDE_REGEX>
这样后续更换原始订阅、过滤伪节点、调整输出文件名,都可以在服务端完成,客户端无需改配置。
企业 VPN / aTrust 共存场景
路由器场景通常不需要专门处理 aTrust 进程,因为路由器看不到电脑上的进程名。家用侧更重要的是 redir-host、IPv6、内网直连和 DNS 链路。
但如果办公笔记本本机同时运行 aTrust 和 Clash / Mihomo,就建议单独准备一套配置。示例:
dns:
enhanced-mode: fake-ip
fake-ip-range: 198.19.0.1/16
tun:
route-exclude-address:
- 198.18.0.0/16
这里避开 198.18.0.0/16,避免和企业 VPN / TUN 常见保留网段冲突。
规则上可以加一个可视化策略组:
- PROCESS-NAME,aTrust,🏢 企业VPN
- PROCESS-NAME,aTrustAgent,🏢 企业VPN
- PROCESS-NAME,aTrustXtunnel,🏢 企业VPN
- DOMAIN-SUFFIX,corp.example.com,🏢 企业VPN
- IP-CIDR,198.18.0.0/16,🏢 企业VPN,no-resolve
🏢 企业VPN 默认保持 DIRECT,同时保留 节点选择 或 手动切换 作为排障入口。正常情况下,企业业务链路不应该被代理节点接管。
验证清单
部署后建议先用临时测试节点访问 SubConverter,确认生成的 YAML 是否符合预期:
http://127.0.0.1:25500/sub?target=clash&url=<ENCODED_TEST_NODE>
家用配置重点检查:
ipv6: true
dns:
ipv6: true
enhanced-mode: redir-host
tun:
route-exclude-address:
- 10.0.0.0/24
- 10.0.2.0/24
规则重点检查:
- IP-CIDR,10.0.0.0/24,DIRECT,no-resolve
- IP-CIDR,10.0.2.0/24,DIRECT,no-resolve
- RULE-SET,ChinaIpV6 (IP-CIDR),🎯 全球直连,no-resolve
- IP-CIDR6,2000::/3,🌐 IPv6策略,no-resolve
工作配置重点检查:
dns:
enhanced-mode: fake-ip
fake-ip-range: 198.19.0.1/16
tun:
route-exclude-address:
- 198.18.0.0/16
proxy-groups:
- name: 🏢 企业VPN
- name: 💬 Ai平台
Sub-Store 检查:
http://127.0.0.1:3001/ -> 200 OK
http://127.0.0.1:3001/<RANDOM_BACKEND_PATH>/api/utils/env -> 200 OK
http://10.0.2.1:3001/share/col/<COLLECTION>?token=<TOKEN> -> 可返回节点内容
短路径检查:
http://127.0.0.1:25500/HomeClash -> 302 -> 200 OK
http://127.0.0.1:25501/HomeClash -> 302 -> 200 OK
https://sub.example.com/HomeClash -> 302 -> 200 OK
https://sub-work.example.com/HomeClash -> 302 -> 200 OK
日常维护
规则调整优先改规则碎片:
home-redir-ipv6.ini
work-vpn.ini
DNS、TUN、Mihomo 基础字段优先改 base YAML:
home-redir-ipv6.yaml
work-vpn.yaml
修改挂载文件后重启对应容器:
docker restart subconverter-home
docker restart subconverter-work
docker restart sub-store
升级或大改前建议备份:
docker-compose.yml.bak-YYYYMMDD-HHMMSS
pref.toml.bak-YYYYMMDD-HHMMSS
回滚时恢复备份文件后重新启动服务即可。
这次部署留下的几个经验
第一,redir-host 仍然很适合家用路由器场景,尤其是你需要频繁调试内网和真实 DNS 结果时。
第二,IPv6 不建议只用“全局直连”或“全局代理”二选一。把本地 IPv6、国内 IPv6、剩余公网 IPv6 分开处理,可维护性更好。
第三,Sub-Store 和 SubConverter 的职责要分清。Sub-Store 管订阅源和节点聚合,SubConverter 管规则和最终配置生成。
第四,proxy-providers.url 必须站在最终客户端视角填写。Docker 内部服务名能在容器里访问,不代表 OpenWrt 或公网笔记本能访问。
第五,公网反代 Sub-Store 要非常谨慎。原始订阅、share token、后端 API 路径都不应该直接暴露。
第六,企业 VPN 共存场景最好单独开一套 SubConverter 实例。不要为了兼容一台办公笔记本,把家用路由器配置复杂化。
最终,这套方案把“每台客户端各写一份规则”收敛成了“服务端统一生成配置”。家用设备使用稳定的 redir-host + IPv6 方案,办公笔记本使用独立的 VPN 兼容方案,后续维护时只需要改 NAS 上的几份挂载文件和 Sub-Store 聚合配置。