这篇主要分享如何把代理核心 Mihomo(Clash.Meta 的继任者)直接跑在 WSL2 里。

环境:Debian 13 (trixie) on WSL2,Mihomo v1.19.33,面板 MetaCubeXD v1.273.1(版本会滚动,安装时以官方 Releases 最新版为准)。

整体架构

思路很简单:Mihomo 是唯一的进程,对外开三类口,代理端口给流量用,控制端口给面板用,面板的静态文件由 Mihomo 自己托管,不需要再起 Web 服务器。

端口用途
7890HTTP 代理
7891SOCKS5 代理
7892Mixed 混合端口(HTTP + SOCKS5 二合一,日常主用这个)
9090RESTful API + MetaCubeXD 面板(/ui 路径)

安装:两个压缩包

Mihomo:

# 从 GitHub Releases 下载 linux-amd64 版,解压后放进 /usr/local/bin
wget -O /tmp/mihomo.gz \
  "https://github.com/MetaCubeX/mihomo/releases/download/v1.19.33/mihomo-linux-amd64-v1.19.33.gz"
gunzip /tmp/mihomo.gz
sudo mv /tmp/mihomo /usr/local/bin/mihomo && sudo chmod +x /usr/local/bin/mihomo
mihomo -v

目录按用途拆开,后面维护会省事很多:

sudo mkdir -p /etc/mihomo/ui /var/log/mihomo   # 配置与面板 / 日志
sudo chown -R $USER:$USER /etc/mihomo /var/log/mihomo

MetaCubeXD 不用单独部署:下载它的静态包(compressed-dist.tgz)解压进 /etc/mihomo/ui,在配置里用 external-ui 指过去,Mihomo 启动时会把面板挂在 9090 端口的 /ui 下。

配置的四个关键决策

完整的 config.yaml 有几百行(代理组和规则占大头),这里只讲真正影响使用体验的四个决策,其余照官方文档默认值即可。

1. 控制器 & 密钥

mixed-port: 7892
allow-lan: false
bind-address: "127.0.0.1"
external-controller: "127.0.0.1:9090"
external-ui: "/etc/mihomo/ui"
secret: "改成你自己的强密码"

2. DNS 用 fake-ip,并按国内外分开解析

我使用 fake-ip 模式(域名先映射到一段保留 IP,流量真正出站时再解析,规则匹配更快),同时用 nameserver-policy 分流解析:

dns:
  enable: true
  listen: "127.0.0.1:5353"
  enhanced-mode: fake-ip
  fake-ip-range: "28.0.0.1/8"
  fake-ip-filter: ["*.lan", "*.local", "*.cn"]   # 这些不走 fake-ip(节选)
  nameserver: ["223.5.5.5", "119.29.29.29"]       # 国内:阿里 / 腾讯
  fallback: ["https://1.1.1.1/dns-query", "https://8.8.8.8/dns-query"]
  nameserver-policy:
    "geosite:cn": ["223.5.5.5", "119.29.29.29"]
    "geosite:geolocation-!cn": ["https://1.1.1.1/dns-query", "https://8.8.8.8/dns-query"]

另外 WSL2 里建议 ipv6: false。

3. 链式代理:订阅做跳板,自有节点做落地

如果手里有两类资源时——订阅节点(线路好、但 IP 是共享的)和自有 VPS / ISP 落地(IP 干净、但直连线路一般)——用 Mihomo 的 dialer-proxy 可以把它们串起来:

proxies:
  - name: "🏠 VPS落地"
    type: ss
    server: YOUR_VPS_IP
    port: 8388
    cipher: aes-128-gcm
    password: "YOUR_PASSWORD"
    dialer-proxy: "🔀 跳板选择"    # 先经订阅节点中转,再到落地机

流量路径变成:本机 → 订阅节点(跳板组,可自动测速/故障转移)→ 自有落地 → 目标站点。入口吃订阅的线路质量,出口用自己干净的 IP。

4. 按服务分组,规则顺序就是优先级

按服务拆组:AI 服务、GitHub、谷歌、微软、苹果各一组,再加广告拦截、全球直连和兜底的"漏网之鱼"。每组内部的候选顺序写明自己的偏好(比如微软、苹果服务默认直连优先,国内本来就通)。

配套的经验是规则顺序即优先级:AI 服务的精确域名规则必须排在谷歌、微软这些大类 GeoSite 规则之前。自动选择(url-test)、故障转移(fallback)以及负载均衡(load-balance)这三种组各留一个,被主选组和跳板组复用。

WSL2 适配

第一,启用 systemd 要改 wsl.conf。 在 /etc/wsl.conf 里写 [boot] systemd=true,然后在 PowerShell 执行 wsl --shutdown 重启子系统,systemd 才生效。之后就能像在真 Linux 上一样写 mihomo.service(Restart=on-failure、日志追加到 /var/log/mihomo/mihomo.log)、systemctl enable 开机自启。

第二,终端代理靠 shell 函数手动开关。 我给自己写了 proxy-on / proxy-off / proxy-status 三个函数,本质是批量 export / unset 那几个 http_proxy、all_proxy、no_proxy 变量(HTTP 走混合口 7892、SOCKS 走 7891)。apt 要走代理是另一处独立配置(/etc/apt/apt.conf.d/proxy.conf),按需添加。

日常运维

面板之外,Mihomo 的 RESTful API 适合写进脚本和快捷命令(记得带 Authorization: Bearer <secret> 请求头):

# 热重载配置(不断开现有连接)
curl -X PUT "http://127.0.0.1:9090/configs?force=false" -H "Authorization: Bearer $SECRET" \
  -H "Content-Type: application/json" -d '{"path": "/etc/mihomo/config.yaml"}'

# 手动触发订阅更新 / 节点健康检查
curl -X PUT http://127.0.0.1:9090/providers/proxies/my-subscription -H "Authorization: Bearer $SECRET"
curl "http://127.0.0.1:9090/providers/proxies/my-subscription/healthcheck" -H "Authorization: Bearer $SECRET"

# 清除 fake-ip 缓存(解析行为异常时)
curl -X POST http://127.0.0.1:9090/cache/fakeip/flush -H "Authorization: Bearer $SECRET"

改完配置走一遍三口验证:

curl -x http://127.0.0.1:7890 https://api.ipify.org   # HTTP 口 + 出口 IP
curl --socks5 127.0.0.1:7891 https://api.ipify.org    # SOCKS 口
curl -x http://127.0.0.1:7892 https://api.ipify.org   # 混合口

小结

这套方案跑下来,可以把"代理"从一个个客户端里的零散设置,收成了一份放在 /etc/mihomo/config.yaml 。换机器时要搬的也只有这一份 YAML。

附录:全量配置

正文里只贴了片段,这里把全套配置完整放出,方便照抄。所有敏感值(secret、服务器地址、密码、订阅链接)都是占位符,替换成你自己的再用;代理组和规则部分可以直接整段采用,按需增删分组即可。

A. 主配置 /etc/mihomo/config.yaml

# ============================================================
#  Mihomo 主配置 - Debian 13 WSL2 环境
#  作者:K.Zhaang
#  更新:2026 | Mihomo v1.19+ | MetaCubeXD latest
# ============================================================

# ---------- 基础设置 ----------
mixed-port: 7892          # HTTP + SOCKS5 混合端口(推荐使用此端口)
port: 7890                # 单独 HTTP 代理端口
socks-port: 7891          # 单独 SOCKS5 代理端口
redir-port: 7893          # 透明代理端口(TProxy,WSL2 内可选)
allow-lan: false          # 仅本机访问;若需局域网访问改为 true
bind-address: "127.0.0.1"

mode: rule                # rule | global | direct
log-level: info           # silent | error | warning | info | debug
ipv6: false               # WSL2 环境建议关闭 IPv6

# ---------- 外部控制器(MetaCubeXD 连接入口)----------
external-controller: "127.0.0.1:9090"
external-ui: "/etc/mihomo/ui"           # MetaCubeXD 静态文件路径
external-ui-url: ""                     # 留空使用本地文件
secret: "your_secret_token_here"        # ← 修改为强密码!

# ---------- 内存与性能 ----------
profile:
  store-selected: true    # 持久化节点选择
  store-fake-ip: true

# ---------- DNS 配置 ----------
dns:
  enable: true
  ipv6: false
  listen: "127.0.0.1:5353"
  enhanced-mode: fake-ip            # fake-ip 模式,规则匹配效率高
  fake-ip-range: "28.0.0.1/8"
  fake-ip-filter:                   # 以下域名不使用 fake-ip
    - "*.lan"
    - "*.local"
    - "localhost.ptlogin2.qq.com"
    - "+.stun.*.*"
    - "+.stun.*.*.*"
    - "+.stun.*.*.*.*"
    - "lens.l.google.com"
    - "stun.l.google.com"
    - "*.cn"
  nameserver:
    - "223.5.5.5"         # 阿里 DoH(国内)
    - "119.29.29.29"      # 腾讯 DoH(国内)
  fallback:
    - "https://1.1.1.1/dns-query"       # Cloudflare
    - "https://8.8.8.8/dns-query"       # Google
  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - "240.0.0.0/4"
  nameserver-policy:
    "geosite:cn": ["223.5.5.5", "119.29.29.29"]
    "geosite:geolocation-!cn": ["https://1.1.1.1/dns-query", "https://8.8.8.8/dns-query"]

# ---------- GEO 数据库 ----------
geodata-mode: false         # 使用 geoip.dat(false)或 mmdb(true)
geo-auto-update: true
geo-update-interval: 24     # 小时
geox-url:
  geoip: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat"
  geosite: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat"
  mmdb: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country.mmdb"

# ---------- 出站代理(你的 VPS/ISP 节点)----------
proxies:
  
  - name: "🏠 VPS落地"
    type: ss                   # 推荐 ss aead 或 vmess,避免 hy2/tuic/reality
    server: YOUR_VPS_IP        # ← 替换为 VPS IP
    port: 8388                 # ← 替换为端口
    cipher: aes-128-gcm        # ← 替换为加密方式
    password: "YOUR_PASSWORD"  # ← 替换为密码
    dialer-proxy: "🔀 跳板选择"  # ← 关键:通过订阅节点中转

  - name: "🏠 ISP落地"
    type: ss                   # 推荐 ss aead 或 vmess,避免 hy2/tuic/reality
    server: YOUR_VPS_IP        # ← 替换为 ISP IP
    port: 8388                 # ← 替换为端口
    cipher: aes-128-gcm        # ← 替换为加密方式
    password: "YOUR_PASSWORD"  # ← 替换为密码
    dialer-proxy: "🔀 跳板选择"  # ← 关键:通过订阅节点中转

# ---------- 订阅代理提供商 ----------
proxy-providers:
  my-subscription:
    type: http
    url: "https://YOUR_SUBSCRIPTION_URL_HERE"   # ← 替换为你的订阅地址
    interval: 86400          # 自动更新间隔(秒),24 小时
    path: "./providers/my-sub.yaml"
    health-check:
      enable: true
      url: "https://www.gstatic.com/generate_204"
      interval: 300          # 健康检查间隔(秒)
      timeout: 5000          # 超时(毫秒)
      lazy: true             # 懒检查,减少无谓流量
    override:
      skip-cert-verify: false
      udp: true

# ---------- 代理组 ----------
proxy-groups:

  # ───────── 顶层主选 ─────────

  # 🚀 主选组 - 手动或自动切换
  - name: "🚀 节点选择"
    type: select
    use:
      - my-subscription
    proxies:
      - "♻️ 自动选择"
      - "🔯 故障转移"
      - "🔁 负载均衡"
      - "🏠 VPS落地"
      - "🏠 ISP落地"
      - DIRECT

  # ♻️ 自动选择(最低延迟)
  - name: "♻️ 自动选择"
    type: url-test
    use:
      - my-subscription
    url: "https://www.gstatic.com/generate_204"
    interval: 300
    tolerance: 50            # 延迟容忍误差(ms),低于此值不切换

  # 🔯 故障转移
  - name: "🔯 故障转移"
    type: fallback
    use:
      - my-subscription
    url: "https://www.gstatic.com/generate_204"
    interval: 300

  # 🔁 负载均衡(轮询,分散流量)
  - name: "🔁 负载均衡"
    type: load-balance
    strategy: round-robin
    use:
      - my-subscription
    url: "https://www.gstatic.com/generate_204"
    interval: 300

  # ───────── 链式代理 ─────────

  # 🔀 跳板选择(从订阅中选一个节点作为 VPS/IPS 的入口跳板)
  - name: "🔀 跳板选择"
    type: select
    use:
      - my-subscription
    proxies:
      - "♻️ 自动选择"
      - "🔯 故障转移"
      - "🔁 负载均衡"

  # ───────── AI 服务 ─────────

  # 🤖 AI 服务(Claude / ChatGPT / Gemini / Copilot)
  - name: "🤖 AI 服务"                
    type: select
    proxies:
      - "🏠 VPS落地"                  # 首选 VPS/IPS 落地,IP 纯净
      - "🏠 ISP落地"
      - "🚀 节点选择"
      - "♻️ 自动选择"
      - DIRECT

  # ───────── 科技平台 ─────────
  # 🐙 GitHub
  - name: "🐙 GitHub"
    type: select
    proxies:
      - "🚀 节点选择"
      - "🏠 VPS落地"
      - "♻️ 自动选择"
      - DIRECT

  # 🔍 谷歌服务
  - name: "🔍 谷歌服务"
    type: select
    proxies:
      - "🚀 节点选择"
      - "🏠 VPS落地"
      - "🏠 ISP落地"
      - "♻️ 自动选择"
      - DIRECT

  # 🪟 微软服务
  - name: "🪟 微软服务"
    type: select
    proxies:
      - DIRECT                         # 微软国内可直连,默认直连
      - "🚀 节点选择"
      - "🏠 VPS落地"
      - "🏠 ISP落地"
      - "♻️ 自动选择"

  # 🍎 苹果服务
  - name: "🍎 苹果服务"
    type: select
    proxies:
      - DIRECT                         # App Store 国区直连
      - "🚀 节点选择"
      - "🏠 VPS落地"
      - "🏠 ISP落地"
      - "♻️ 自动选择"

  # ───────── 媒体与其他 ─────────

  # 🌍 国外媒体(流媒体专线)
  - name: "🌍 国外媒体"
    type: select
    proxies:
      - "🚀 节点选择"
      - "♻️ 自动选择"
      - "🏠 VPS落地"
      - "🏠 ISP落地"
      - DIRECT

  # 🎯 全球直连
  - name: "🎯 全球直连"
    type: select
    proxies:
      - DIRECT
      - "🚀 节点选择"

  # 🛑 广告拦截
  - name: "🛑 广告拦截"
    type: select
    proxies:
      - REJECT
      - DIRECT

  # 🐟 漏网之鱼(未匹配规则的流量)
  - name: "🐟 漏网之鱼"
    type: select
    proxies:
      - "🚀 节点选择"
      - "♻️ 自动选择"
      - DIRECT

# ---------- 分流规则 ----------
rules:

  # ── 本地及局域网直连 ──
  - DOMAIN-SUFFIX,local,DIRECT
  - IP-CIDR,127.0.0.0/8,DIRECT
  - IP-CIDR,172.16.0.0/12,DIRECT
  - IP-CIDR,192.168.0.0/16,DIRECT
  - IP-CIDR,10.0.0.0/8,DIRECT
  - IP-CIDR,100.64.0.0/10,DIRECT
  - IP-CIDR,::1/128,DIRECT
  - IP-CIDR,fc00::/7,DIRECT

  # ── 广告拦截(使用 GeoSite 数据库) ──
  - GEOSITE,category-ads-all,🛑 广告拦截

  # ── AI 服务(精确域名,必须在谷歌/微软大类之前)──
  - DOMAIN-SUFFIX,anthropic.com,🤖 AI 服务
  - DOMAIN-SUFFIX,claude.ai,🤖 AI 服务
  - GEOSITE,openai,🤖 AI 服务
  - DOMAIN-SUFFIX,gemini.google.com,🤖 AI 服务
  - DOMAIN-SUFFIX,generativelanguage.googleapis.com,🤖 AI 服务
  - DOMAIN-SUFFIX,aistudio.google.com,🤖 AI 服务
  - DOMAIN-SUFFIX,copilot.microsoft.com,🤖 AI 服务
  - DOMAIN-SUFFIX,copilot.cloud.microsoft,🤖 AI 服务

  # ── GitHub ──
  - GEOSITE,github,🐙 GitHub

  # ── 谷歌服务 ──
  - GEOSITE,google,🔍 谷歌服务

  # ── 微软服务 ──
  - GEOSITE,microsoft,🪟 微软服务
  - GEOSITE,bing,🪟 微软服务

  # ── 苹果服务 ──
  - GEOSITE,apple,🍎 苹果服务

  # ── 流媒体 ──
  - GEOSITE,netflix,🌍 国外媒体
  - GEOSITE,youtube,🌍 国外媒体
  - GEOSITE,disney,🌍 国外媒体
  - GEOSITE,hbo,🌍 国外媒体
  - GEOSITE,spotify,🌍 国外媒体

  # ── 国内直连 ──
  - GEOSITE,private,🎯 全球直连
  - GEOSITE,cn,🎯 全球直连
  - GEOIP,private,🎯 全球直连,no-resolve
  - GEOIP,CN,🎯 全球直连

  # ── 其余境外流量 ──
  - GEOSITE,geolocation-!cn,🚀 节点选择

  # ── 兜底(漏网之鱼) ──
  - MATCH,🐟 漏网之鱼

B. systemd 服务

先在 /etc/wsl.conf 里启用 systemd:

[boot]
systemd=true

改完在 PowerShell 执行 wsl --shutdown 重启子系统,再创建 /etc/systemd/system/mihomo.service:

[Unit]
Description=Mihomo Proxy Service
Documentation=https://github.com/MetaCubeX/mihomo
After=network.target nss-lookup.target

[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
LimitNOFILE=1048576
StandardOutput=append:/var/log/mihomo/mihomo.log
StandardError=append:/var/log/mihomo/mihomo.log

[Install]
WantedBy=multi-user.target

然后 sudo systemctl daemon-reload && sudo systemctl enable --now mihomo 即可。

C. Shell 代理开关函数(追加到 ~/.bashrc 或 ~/.zshrc)

# ── Mihomo 代理快捷函数 ──────────────────────────────────────
MIHOMO_HTTP_PORT=7892
MIHOMO_SOCKS_PORT=7891

proxy-on() {
    export http_proxy="http://127.0.0.1:$MIHOMO_HTTP_PORT"
    export https_proxy="http://127.0.0.1:$MIHOMO_HTTP_PORT"
    export all_proxy="socks5://127.0.0.1:$MIHOMO_SOCKS_PORT"
    export no_proxy="localhost,127.0.0.1,::1,10.0.0.0/8,192.168.0.0/16"
    echo "✔ 代理已开启 → HTTP :$MIHOMO_HTTP_PORT  SOCKS :$MIHOMO_SOCKS_PORT"
}

proxy-off() {
    unset http_proxy https_proxy all_proxy no_proxy
    echo "✘ 代理已关闭"
}

proxy-status() {
    echo "http_proxy  : ${http_proxy:-(未设置)}"
    echo "all_proxy   : ${all_proxy:-(未设置)}"
}

proxy-toggle() {
    if [ -n "$http_proxy" ]; then
        proxy-off
    else
        proxy-on
    fi
}

# Chrome 始终通过代理启动
chrome() {
    google-chrome \
        --proxy-server="http://127.0.0.1:$MIHOMO_HTTP_PORT" \
        --proxy-bypass-list="localhost;127.*;10.*;192.168.*" \
        "$@" &
}
# ────────────────────────────────────────────────────────────

# 使配置立即生效
# source ~/.bashrc

D. apt 走代理(可选,写入 /etc/apt/apt.conf.d/proxy.conf)

sudo tee /etc/apt/apt.conf.d/proxy.conf > /dev/null << 'EOF'
Acquire::http::Proxy "http://127.0.0.1:7890";
Acquire::https::Proxy "http://127.0.0.1:7890";
EOF