在家庭或内网环境中,将群晖 NAS 作为局域网代理服务器是一个非常实用的方案。通过 Docker 部署维护活跃的 Mihomo(原 Clash.Meta) 核心,搭配 Metacubexd WebUI,再由 DSM 定时脚本自动同步订阅与热重载,既能完整保留机场丰富的策略分流规则,又无需在各个设备上单独下载代理客户端。
一、前期环境准备
- 群晖系统:DSM 7.2 及以上版本(推荐),套件中心已安装 Container Manager。
- 固定 IP:确保群晖 NAS 在局域网内分配了静态 IP(下文示例假设群晖 IP 为
<your-nas-ip>)。 - 文件目录结构:在群晖的
docker共享文件夹下建立如下目录层级(可通过 File Station 或 SSH 创建):
/volume1/docker/clash/├── config/│ └── Country.mmdb # (可选) 离线 IP 数据库├── docker-compose.yaml # 容器编排文件└── update.sh # 订阅自动更新脚本二、编写 Docker Compose 编排
这里采用 host 网络模式部署 Mihomo,避免多重 NAT 损耗,并能直接监听群晖的所有网卡;Metacubexd 作为静态面板映射到 8080 端口。
- 打开群晖 Container Manager -> 项目 (Project) -> 新增。
- 项目名称:
clash - 路径:选择
/volume1/docker/clash - 来源:选择”创建 docker-compose.yaml”,粘贴以下内容:
version: '3.8'
services: mihomo: image: metacubex/mihomo:latest container_name: mihomo restart: unless-stopped network_mode: host volumes: - /volume1/docker/clash/config:/root/.config/mihomo environment: - TZ=Asia/Shanghai
metacubexd: image: ghcr.io/metacubex/metacubexd:latest container_name: metacubexd restart: unless-stopped ports: - "8080:80"注意:先不要急着启动容器,需先准备好初始配置及 GeoIP 数据库,避免初次拉起时报错。
三、避坑点:预置 Country.mmdb 数据库
Mihomo 首次启动时会解析规则中的 GEOIP,默认从境外 GitHub 源下载 Country.mmdb。国内直连群晖极易出现 can't download MMDB: context deadline exceeded,导致容器反复崩溃退出。
解决方案(手动导入):
- 用电脑浏览器下载最新的数据库文件:
https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country.mmdb - 打开 File Station,将下载的文件重命名为
Country.mmdb(注意首字母大写),上传到/volume1/docker/clash/config/目录下。
四、配置全量订阅自动同步脚本
如果直接用纯手写的简易配置,会丢失机场自带的流媒体、AI 工具、国内直连等细分规则;而如果单纯手动上传订阅,节点过期或变更时又需要反复下载。
通过编写 Shell 脚本结合 Mihomo 的 RESTful API,可以实现”拉取全量规则配置 -> 修正局域网与控制器参数 -> 覆盖并热重载”:
- 在
/volume1/docker/clash/下新建update.sh文件。 - 写入以下内容(请将
SUB_URL替换为你的真实订阅链接,API_SECRET替换为你自定义的密钥):
#!/bin/bash# 机场提供的 Clash 完整订阅链接SUB_URL="https://your-subscription-url-here"
# 配置文件绝对路径及密钥CONFIG_FILE="/volume1/docker/clash/config/config.yaml"API_SECRET="<your-api-secret>"
# 1. 模拟 Clash 客户端 User-Agent 下载订阅配置curl -fsSL -A "clash.meta" "$SUB_URL" -o "${CONFIG_FILE}.tmp"
# 2. 检查下载是否成功且文件非空if [ -s "${CONFIG_FILE}.tmp" ]; then # 清理订阅中可能自带的监听限制 sed -i '/^mixed-port:/d' "${CONFIG_FILE}.tmp" sed -i '/^allow-lan:/d' "${CONFIG_FILE}.tmp" sed -i '/^bind-address:/d' "${CONFIG_FILE}.tmp" sed -i '/^external-controller:/d' "${CONFIG_FILE}.tmp" sed -i '/^secret:/d' "${CONFIG_FILE}.tmp"
# 在文件头部插入局域网代理与远程控制的必要参数 sed -i '1i mixed-port: 7890\nallow-lan: true\nbind-address: "*"\nexternal-controller: 0.0.0.0:9090\nsecret: "'"$API_SECRET"'"' "${CONFIG_FILE}.tmp"
# 替换现有配置文件 mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
# 3. 通过 RESTful API 发送热重载请求(无缝生效,不断流) curl -s -X PUT -H "Authorization: Bearer $API_SECRET" \ -H "Content-Type: application/json" \ -d "{\"path\": \"/root/.config/mihomo/config.yaml\"}" \ http://127.0.0.1:9090/configs?force=true > /dev/null
echo "[$(date)] Config updated and reloaded successfully."else rm -f "${CONFIG_FILE}.tmp" echo "[$(date)] Failed to download subscription, keeping current config."fi- 给脚本赋予执行权限并首次运行生成初始配置,通过 SSH 登录群晖执行:
chmod +x /volume1/docker/clash/update.shbash /volume1/docker/clash/update.sh执行完成后,检查 /volume1/docker/clash/config/ 下是否已成功生成带内容的 config.yaml。
五、启动容器并设置定时任务
1. 启动容器
回到群晖 Container Manager -> 项目,找到 clash 项目并点击”启动”。
查看 mihomo 容器日志,若出现 Mixed(http+socks) proxy listening at: [::]:7890 和 RESTful API listening at: [::]:9090,说明核心运行正常。
2. 设置 DSM 定时自动更新
- 进入 DSM 控制面板 -> 任务计划 -> 新增 -> 计划的任务 -> 用户定义的脚本。
- 常规:任务名称填写
Update-Mihomo,用户账号务必选择root。 - 计划:设置执行频率(如每天凌晨 04:00)。
- 任务设置:输入命令:
bash /volume1/docker/clash/update.sh- 点击”确定”保存。
六、Web 面板管理与局域网设备接入
1. 访问 Metacubexd 面板
浏览器访问 http://<your-nas-ip>:8080(群晖 IP + 8080 端口):
- API 地址 / Hostname:填写
http://<your-nas-ip>:9090(注意:必须是http://,千万不能写https://,也不能写127.0.0.1)。 - 密钥 (Secret):输入脚本里设定的
API_SECRET。 - 进入面板后,将默认直连的策略组切换为你需要的代理节点或自动优选策略。
2. 局域网客户端使用
任何需要上网的手机、电脑或主机设备,无需安装任何客户端软件:
- 代理服务器 / 主机名:
<your-nas-ip>(群晖 IP) - 端口:
7890 - 协议:HTTP / SOCKS5 均可(
mixed-port自动适配)
七、常见问题与排查清单
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 容器 IP 显示为空 | 容器使用了 host 模式 | 属于正常现象,直接使用群晖 NAS 的实际局域网 IP 即可。 |
容器日志报 can't download MMDB 闪退 | 宿主机网络直连 GitHub 失败 | 手动下载 country.mmdb 并重命名为 Country.mmdb 上传至配置目录。 |
| Web 面板提示无法连接后端 9090 | 前端协议误写成了 https:// 或地址填成了 127.0.0.1 | 前端填写 http://群晖IP:9090;检查 config.yaml 中 external-controller 是否为 0.0.0.0:9090。 |
| 执行 update.sh 提示 No such file | 群晖共享文件夹可能位于其他存储空间(如 volume2) | 在 File Station 中右键查看目录属性确认真实挂载路径。 |