macOS 上 配置 Launchctl 运行 Clash Meta(Mihomo)内核服务
✨ 文章介绍了如何在 macOS 上使用 launchctl 配置和启动 Clash Meta(Mihomo)内核服务。首先,讲解了 launchd 和 launchctl 的基本概念及常用命令,随后提供了 clash.plist 配置文件的示例,说明了如何设置服务标识、运行参数和日志路径。接着,详细描述了如何移动内核和配置文件到相应路径,并以 root 权限启动服务。最后,介绍了如何通过 Web 面板管理 Clash,包括修改控制 API 端口和设置鉴权的建议。
背景
Clash 是一个简单而强大的网络代理工具,在原有的 Clash Premium 内核停更后就切换到了 Meta (Mihomo)内核,macOS 上就直接使用了 https://github.com/MetaCubeX/ClashX.Meta 客户端,但最近可能是 macOS 15 的问题,开启 tun 接口有点问题。想了想还是干脆和在 Linux 上一样直接裸跑内核服务。下面记录下配置:
Launchd
launchd 是 macOS 的系统和服务管理工具,负责启动、管理和停止后台进程。它通过 plist 配置文件来定义服务的启动行为,包括服务依赖、运行时环境以及日志管理等。launchd 管理的服务可以是系统级别的守护进程,也可以是用户级别的应用程序和工具。
launchctl 是与 launchd 配合使用的命令行工具,允许用户手动加载、启动、停止和卸载服务。通过 launchctl,用户可以查看正在运行的服务、控制服务状态,或在需要时重新加载服务配置。
launchctl 常用命令:
# 加载并启动指定的服务。
launchctl load xxx
# 停止并卸载指定的服务。
launchctl unload xxx
# 列出所有已加载的服务及其状态。
launchctl list
# 启动或停止指定的服务。
launchctl start xxx
launchctl stop xxxplist 配置文件
编写配置文件如下:(此处以用户名 app 为例)
clash.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- 服务标识符(标签)/ 后台进程名称 -->
<key>Label</key>
<string>clash</string>
<!-- 系统启动并加载这个服务时自动运行 -->
<key>RunAtLoad</key>
<true />
<!-- 限定为系统会话类型 -->
<key>LimitLoadToSessionType</key>
<array>
<string>System</string>
</array>
<!-- 程序运行命令参数 -->
<key>ProgramArguments</key>
<array>
<!-- 内核位置 -->
<string>/usr/local/bin/clash</string>
<string>-d</string>
<!-- 配置文件路径,路径下的 config.yaml -->
<string>/Users/app/.config/clash</string>
</array>
<!-- 程序运行工作路径 -->
<key>WorkingDirectory</key>
<string>/Users/app/.config/clash</string>
<!-- 标准输出日志路径 -->
<key>StandardOutPath</key>
<string>/Users/app/.config/clash/clash_stdout.log</string>
<!-- 标准错误日志路径 -->
<key>StandardErrorPath</key>
<string>/Users/app/.config/clash/clash_stderr.log</string>
</dict>
</plist>Clash Meta 内核及配置
对照👆上面配置文件的定义,将 Clash Meta 内核与相应的配置文件移动到对应的路径下,并修改相关权限。
Release: https://github.com/MetaCubeX/mihomo/releases/tag/v1.18.10
Alpha: https://github.com/MetaCubeX/mihomo/releases/tag/Prerelease-Alpha
选择需要的内核下载,我这里是 mihomo-darwin-arm64-go122-v1.18.10.gz ,将其解压并重命名为 clash,再执行命令
sudo mv clash /usr/local/bin/
sudo chown root clash
sudo chmod +x clash同理操作配置文件,配置文件命名为 config.yaml
mkdir -p /Users/app/.config/clash
mv config.yaml /Users/app/.config/clash
chmod 644 /Users/app/.config/clash/config.yamlClash Meta 配置文件此处不做展开,请参考
配置加载服务
完成👆上面的各项配置后,此时我们就可以重新回到 Launchd 的操作了。因为我要使用 tun 接口,也就是要以 root 权限启动,故需要将 clash.plist 配置移动到 /Library/LaunchDaemons 下。
sudo mv clash.plist /Library/LaunchDaemons
sudo chown root clash.plist
sudo chmod 644 clash.plist现在我们就可以通过 launchctl 命令来加载并启动服务了。
sudo launchctl load /Library/LaunchDaemons/clash.plist
# 查看服务
sudo launchctl list | grep clash
# 卸载停止服务
# sudo launchctl unload /Library/LaunchDaemons/clash.plistmacOS DNS 处理
上面我们添加了 launchctl 服务,但 macOS 上使用 Clash 内核, DNS 需要额外处理,如下为在 ~/.zshrc 中增加的配置,方便后续使用。
# Clash service control with DNS management
# Reference: https://github.com/MetaCubeX/mihomo/issues/248
alias startclash='networksetup -setdnsservers Wi-Fi 198.18.0.2 && sudo launchctl start clash'
alias stopclash='sudo launchctl stop clash && networksetup -setdnsservers Wi-Fi Empty'
clash_service() {
case $1 in
(start)
if startclash; then
echo "✓ Clash service started"
else
echo "✗ Failed to start Clash" >&2
return 1
fi
;;
(stop)
if stopclash; then
echo "✓ Clash service stopped"
else
echo "✗ Failed to stop Clash" >&2
return 1
fi
;;
(status)
if service_status=$(sudo launchctl list | grep -w clash); then
echo "✓ Clash running (PID: ${${(s: :)service_status}[1]})"
else
echo "✗ Clash not running"
return 1
fi
;;
(restart)
stopclash && startclash
echo "✓ Clash service restarted"
;;
(*)
echo "Usage: ${${0:-clash_service}:t} start|stop|status|restart" >&2
return 1
;;
esac
}修改完成后执行 source ~/.zshrc 加载。后续执行 clash_service start|stop|status|restart 即可控制 clash 内核的运行。
clash_service
Usage: clash_service start|stop|status|restartMeta 面板管理

此时 clash 已经以后台服务形式运行了,基于 Clash 的外部控制 API,我们可以通过相应的 Web 面板来管理,按照上面仓库配置文件,本地会有管理面板的 UI 文件,访问 http://127.0.0.1:9090/ui 即可进入。
如下为我的修改:
external-controller: 127.0.0.1:39090
secret: "ClashPasswd"
external-ui: ui
external-ui-url: "https://github.com/Zephyruso/zashboard/releases/latest/download/dist-cdn-fonts.zip"
# RESTful API CORS标头配置
external-controller-cors:
allow-origins:
- 'http://127.0.0.1'
allow-private-network: true此时访问 http://127.0.0.1:39090/ui 输入 external-controller 和 secret 对应的值即可进入管理面板了,面板功能还是挺全的,很好使。