群晖 NAS 部署 Mihomo(Clash.Meta 内核):支持 VLESS 的 Docker 安装与避坑指南
本文最后更新于 42 天前,如有失效请评论区留言。

为什么要从 dreamacro/clash 换成 mihomo?

我之前在群晖 NAS 上跑的是 dreamacro/clash,日常确实省心,但有一个很现实的问题:一些机场/节点开始以 VLESS 等较新的协议形态为主,或者直接给的是 Clash.Meta 风格订阅,这时候原版 Clash 的兼容性就会变得很尴尬——要么订阅吃不进去,要么能导入但实际连不通。

mihomo 可以理解为 Clash.Meta 系列内核的延续/实现(生态里常见的说法就是 “clash-meta aka mihomo”),对“较新协议与混淆/隧道方案”的支持更完整,所以我这次干脆一步到位换成 mihomo。

环境与前提条件

  • 群晖系统:DSM 7.2

  • 套件:Container Manager(或旧版 Docker 套件)

  • 你已经有:可用订阅链接(Clash / Clash.Meta 订阅均可)

  • 你希望达到的效果:

    1. NAS 上能稳定跑代理内核;

    2. 有一个可视化面板(WebUI)管理节点/策略;

    3. 尽量少踩坑,出问题能快速定位。

整体思路

我们会用到两个容器(或一个内核 + 一个 UI):

  1. mihomo(内核)

    • 提供本地代理端口(HTTP/SOCKS/mixed)

    • 提供控制接口 external-controller(默认常用 9090)

  2. MetaCubeXD(WebUI 面板)

    • 浏览器打开它(常用 9097)

    • 它再去连接 mihomo 的 9090 控制接口

停掉旧 Clash(避免端口冲突)

如果你之前跑过 dreamacro/clashh 或者 haishanh/yacd 或类似内核,建议先停止容器,尤其注意是否占用了:

  • 7890/7891/7892(代理端口常见)

  • 9090(控制接口常见)

9090 被占用会导致 UI 连不上内核,表现通常就是 “Failed to fetch” 或“后端地址添加不上”。

创建目录

以群晖常见路径举例(你按自己的 volume 改):

  • /volume1/docker/mihomo/mihomo/:mihomo 配置与数据

  • /volume1/docker/mihomo/mihomo/metacubexd/:MetaCubeXD 静态文件(可选)

你至少需要这些文件/目录:

mihomo/config.yaml、 geoip.dat 、 geosite.dat 、 geoip.metadb (如果你选择本地部署 metacubexd 静态文件)

说明:不少教程会提醒你准备 geoip.dat / geosite.dat 这类文件,用于规则与地理库匹配,缺了不一定立刻报错,但“规则命中异常/体验不对”时它往往是隐患点之一。

Docker Compose 一把梭(推荐)

下面这份 compose 是“够用且好排查”的版本:一个 mihomo + 一个 metacubexd(UI)。端口可以自行更改:docker-compose.yml(路径自定义即可,我是放在第一个mihomo 目录下)的内容为:


# version: '3'
services:
  mihomo:
    container_name: mihomo
    image: metacubex/mihomo
    restart: always
    privileged: true
    pid: host
    ipc: host
    network_mode: host
    cap_add:
      - ALL
    security_opt:
      - apparmor=unconfined
    volumes:
      - /路径:/root/.config/mihomo # 更改为自己的路径
      - /dev/net/tun:/dev/net/tun
  
  metacubexd:
    container_name: metacubexd
    image: ghcr.io/metacubex/metacubexd
    restart: always
    network_mode: bridge
    ports:
      - '9097:80'
    volumes:
      - /路径:/config/caddy  # 更改为自己的路径

整体而言,我的实现实在docker下面创建了一个mihomo文件夹,在mihomo文件夹下面创建了一个mihomo文件夹以及Docker Compose 模版文件,在子级mihomo文件夹下面创建了metacubexd文件夹以及config.yaml文件以及geoip.dat 、 geosite.dat 、 geoip.metadb。其中,geoip.dat 、 geosite.dat 、 geoip.metadb 文件在网址获取最新版本即可。详细的目录结构为:

mihomo/
├── docker-compose.yml
└── mihomo/
         ├── config.yaml
         ├── geoip.dat
         ├── geosite.dat
         ├── geoip.metadb
         └── metacubexd/
                  └── (这里放 Metacubexd 的前端静态文件/资源,例如 dist/ 或 index.html 等)

接下来写配置文件,config.yaml(我的在第二个mihomo目录下面)的内容为(将订阅链接以及相应的名字更改为你自己的,我有两个,故写了两个,只有一个的话另一个删除即可, 同时, 需要设置登录密码的话secret解除注释并设置密码即可):


mixed-port: 7890
allow-lan: true
bind-address: '*'
mode: rule
log-level: info
external-controller: '0.0.0.0:9090'
#secret: ""

tun:
  enable: true
  stack: mixed
  dns-hijack:
    - "any:53"
    - "tcp://any:53"
  auto-route: true
  auto-redirect: true
  auto-detect-interface: true

proxy-providers:
  订阅链接名字(自定义):
    url: "订阅链接"
    type: http
    interval: 86400
    health-check: {enable: true,url: "https://www.gstatic.com/generate_204", interval: 300}
    override:
      additional-prefix: ""
  订阅链接名字(自定义):
    url: "订阅链接"
    type: http
    interval: 86400
    health-check: {enable: true,url: "https://www.gstatic.com/generate_204", interval: 300}
    override:
      additional-prefix: ""

proxies: 
  - name: "直连"
    type: direct
    udp: true

geodata-mode: true
geox-url:
  geoip: "https://mirror.ghproxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat"
  geosite: "https://mirror.ghproxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat"
  mmdb: "https://mirror.ghproxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country-lite.mmdb"
  asn: "https://mirror.ghproxy.com/https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb"

dns:
  enable: true
  ipv6: true
  respect-rules: true
  enhanced-mode: fake-ip
  fake-ip-filter:
    - "*"
    - "+.lan"
    - "+.local"
    - "+.market.xiaomi.com"
  nameserver:
    - https://120.53.53.53/dns-query
    - https://223.5.5.5/dns-query
  proxy-server-nameserver:
    - https://120.53.53.53/dns-query
    - https://223.5.5.5/dns-query
  nameserver-policy:
    "geosite:cn,private":
      - https://120.53.53.53/dns-query
      - https://223.5.5.5/dns-query
    "geosite:geolocation-!cn":
      - "https://dns.cloudflare.com/dns-query"
      - "https://dns.google/dns-query"

proxy-groups:

  - name: 默认
    type: select
    proxies: [自动选择,直连,香港,台湾,日本,新加坡,美国,其它地区,全部节点]

  - name: Google
    type: select
    proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]

  - name: Telegram
    type: select
    proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]

  - name: Twitter
    type: select
    proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]

  - name: 哔哩哔哩
    type: select
    proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]

  - name: 巴哈姆特
    type: select
    proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]

  - name: YouTube
    type: select
    proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]

  - name: NETFLIX
    type: select
    proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]

  - name: Spotify
    type: select
    proxies:  [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]

  - name: Github
    type: select
    proxies:  [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]

  - name: 国内
    type: select
    proxies:  [直连,默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择]

  - name: 其他
    type: select
    proxies:  [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]

  #分隔,下面是地区分组
  - name: 香港
    type: select
    include-all: true
    filter: "(?i)港|hk|hongkong|hong kong"

  - name: 台湾
    type: select
    include-all: true
    filter: "(?i)台|tw|taiwan"

  - name: 日本
    type: select
    include-all: true
    filter: "(?i)日|jp|japan"

  - name: 美国
    type: select
    include-all: true
    filter: "(?i)美|us|unitedstates|united states"

  - name: 新加坡
    type: select
    include-all: true
    filter: "(?i)(新|sg|singapore)"

  - name: 其它地区
    type: select
    include-all: true
    filter: "(?i)^(?!.*(?:|||||港|hk|hongkong|台|tw|taiwan|日|jp|japan|新|sg|singapore|美|us|unitedstates)).*"

  - name: 全部节点
    type: select
    include-all: true

  - name: 自动选择
    type: url-test
    include-all: true
    tolerance: 10

rules:
  - GEOIP,lan,直连,no-resolve
  - GEOSITE,github,Github
  - GEOSITE,twitter,Twitter
  - GEOSITE,youtube,YouTube
  - GEOSITE,google,Google
  - GEOSITE,telegram,Telegram
  - GEOSITE,netflix,NETFLIX
  - GEOSITE,bilibili,哔哩哔哩
  - GEOSITE,bahamut,巴哈姆特
  - GEOSITE,spotify,Spotify
  - GEOSITE,CN,国内
  - GEOSITE,geolocation-!cn,其他

  - GEOIP,google,Google
  - GEOIP,netflix,NETFLIX
  - GEOIP,telegram,Telegram
  - GEOIP,twitter,Twitter
  - GEOIP,CN,国内
  - MATCH,其他

启动与验证

打开 Container Manmager – 项目 – 新增,项目名称:自己定义,路径为 docker-compose.yml的目录,会自动加载 docker-compose.yml,等待建立完成即可。

打开 UI(9097)并连接后端

访问:

  • UI:http://群晖IP:9097

打开后的内容:

  • 后端地址:http://群晖IP:9090

  • 密钥:填你 config.yaml 里的 secret(没有设置就不填即可, 在config.yaml文件里面配置)

注意两个细节(非常高频的坑):

  1. 后端地址不要写 https。不少人图省事写了 https,结果浏览器安全策略/混合内容直接拦掉,UI 就会表现成 “Failed to fetch”。

  2. 如果你开了广告拦截/隐私插件,建议无痕模式或临时关闭插件测试一次。

初上手

在 mihomo / MetaCubeXD 里看到的 Global、自动选择、手动选择、DIRECT 这些卡片,本质上是 代理组(Proxy Group)

理解它最简单的方式是:
节点是“刀”,代理组是“刀架”,规则是在说“什么菜用哪把刀”。

常见组类型(在面板里最常看到的):

  1. GLOBAL(全局)

    • 含义:不管访问什么域名/APP,统一走在 GLOBAL 里选的那一组/那一个节点。

    • 适合:临时测试、“我就想一把梭”。

    • 代价:国内直连也被代理走了,可能更慢。

  2. 自动选择(URLTest)

    • 含义:内核会按延迟/可用性定期测一轮,在一堆节点里自动挑“当前最好用”的。

    • 适合:不想天天手动换节点。

  3. 故障转移(Fallback)

    • 含义:优先用主节点,挂了就切到下一个。

    • 适合:稳定性优先的场景。

  4. 手动选择(Select)

    • 含义:你点哪个就用哪个,不自动切。

    • 适合:你对某条线路很有把握,或者需要固定出口 IP。

  5. DIRECT(直连) / REJECT(拒绝)

    • 含义:直连就是不走代理;拒绝就是直接拦掉。

    • 适合:国内站点、广告域名、追踪域名等。

在面板的设置页面可以选择模式。

注意事项与建议

/dev/net/tun 不存在

docker-compose.yml中关于mihomo容器的配置里面有/dev/net/tun 路径的映射,在群晖里面可能会提示不存在(省心的方式:直接注释掉该行即可)

如果你要折腾 TUN(让 NAS“系统层面”更多流量透明走代理),群晖上经常会遇到:

/dev/net/tun does not exist

解决方法:在群晖控制面板 -> 任务计划  -> 新增 -> 触发的任务 -> 用户账号:root , 事件选择开机,在任务设置中填写的脚本为:


if [ ! -c /dev/net/tun ]; then
    mkdir -p /dev/net
    mknod /dev/net/tun c 10 200
    chmod 600 /dev/net/tun
fi

我个人建议:

  • 如果只是“让 NAS 上的 Docker 拉镜像、让电脑手机能上网”,先别上来就搞 TUN。

  • 先用 mixed-port + 规则模式 + WebUI 跑顺,再决定是否透明代理,成本会低很多。

TUN 的好处在哪里?为什么很多人想用?
主要好处 1:不用每个应用单独设置代理

很多设备/应用要么不支持代理,要么设置入口很深(甚至根本没有代理设置)。
TUN 接管后,这些流量也能被 mihomo 统一处理。

典型场景:

NAS 上某些 Docker 容器/服务访问外网(拉镜像、插件更新)

某些客户端不支持 SOCKS/HTTP 代理,但仍想走代理

想要更接近“像路由器一样”统一代理的体验

主要好处 2:规则更“真实”

如果只是靠浏览器设置代理,很多系统服务、后台进程的流量根本不经过 mihomo;
TUN 接管后,mihomo 能看到更完整的连接请求,你的规则分流才更符合预期。

主要好处 3:对“非 HTTP 流量”更友好

很多协议不是 HTTP(例如某些游戏、系统更新、特定客户端协议)。
只要是 IP 流量,理论上都能被 TUN 接管进来再决定如何处理。

反向代理与安全建议:别把控制口裸到公网

很多人喜欢把 UI 用域名/HTTPS 反代出去,我也理解:在外面用手机看面板很爽。

但我必须认真提醒一句:

  • 9090 是控制接口,它不是给公网随便访问的。

  • 真要暴露,也至少做到:

    1. 强 secret

    2. IP 白名单(只允许你自己的出口 IP)

    3. 或者加一层鉴权(Basic Auth / OAuth / VPN)

如果你用 Nginx 反代,最少也建议做“只允许指定 IP 段访问”,避免把 NAS 变成公共靶子。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
新年
快乐